Skip to content

Commit 775da60

Browse files
author
Tim Corringham
committed
Update template specialization assert handling
Amend the fix for DXASSERTS in template specialization by incorporating changes from review comments.
1 parent 76a8f5f commit 775da60

2 files changed

Lines changed: 49 additions & 53 deletions

File tree

tools/clang/lib/Sema/SemaHLSL.cpp

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -830,12 +830,10 @@ GetOrCreateTemplateSpecialization(ASTContext &context, Sema &sema,
830830
if (specializationDecl->getInstantiatedFrom().isNull()) {
831831
// InstantiateClassTemplateSpecialization returns true if it finds an
832832
// error.
833-
bool errorFound = sema.InstantiateClassTemplateSpecialization(
834-
NoLoc, specializationDecl,
835-
TemplateSpecializationKind::TSK_ImplicitInstantiation, true);
836-
// Template specialization is suppressed if a fatal error has already been
837-
// registered so don't assert in such cases.
838-
DXVERIFY_NOMSG(sema.Diags.hasFatalErrorOccurred() || !errorFound);
833+
if (sema.InstantiateClassTemplateSpecialization(
834+
NoLoc, specializationDecl,
835+
TemplateSpecializationKind::TSK_ImplicitInstantiation, true))
836+
return QualType();
839837
}
840838
return context.getTemplateSpecializationType(
841839
TemplateName(templateDecl), templateArgs.data(), templateArgs.size(),
@@ -846,19 +844,20 @@ GetOrCreateTemplateSpecialization(ASTContext &context, Sema &sema,
846844
context, TagDecl::TagKind::TTK_Class, currentDeclContext, NoLoc, NoLoc,
847845
templateDecl, templateArgsForDecl.data(), templateArgsForDecl.size(),
848846
nullptr);
849-
// InstantiateClassTemplateSpecialization returns true if it finds an error.
850-
bool errorFound = sema.InstantiateClassTemplateSpecialization(
851-
NoLoc, specializationDecl,
852-
TemplateSpecializationKind::TSK_ImplicitInstantiation, true);
853-
// Template specialization is suppressed if a fatal error has already been
854-
// registered so don't assert in such cases.
855-
DXVERIFY_NOMSG(sema.Diags.hasFatalErrorOccurred() || !errorFound);
847+
// template specialization isn't performed if a fatal error has occurred
848+
if (!sema.Diags.hasFatalErrorOccurred()) {
849+
// InstantiateClassTemplateSpecialization returns true if it finds an error.
850+
[[maybe_unused]] bool errorFound =
851+
sema.InstantiateClassTemplateSpecialization(
852+
NoLoc, specializationDecl,
853+
TemplateSpecializationKind::TSK_ImplicitInstantiation, true);
854+
assert(!errorFound && "template specialization failed");
855+
}
856856
templateDecl->AddSpecialization(specializationDecl, InsertPos);
857857
specializationDecl->setImplicit(true);
858-
859858
QualType canonType = context.getTypeDeclType(specializationDecl);
860-
DXASSERT(isa<RecordType>(canonType),
861-
"type of non-dependent specialization is not a RecordType");
859+
assert(isa<RecordType>(canonType) &&
860+
"type of non-dependent specialization is not a RecordType");
862861
TemplateArgumentListInfo templateArgumentList(NoLoc, NoLoc);
863862
TemplateArgumentLocInfo NoTemplateArgumentLocInfo;
864863
for (unsigned i = 0; i < templateArgs.size(); i++) {
@@ -893,18 +892,17 @@ static QualType GetOrCreateMatrixSpecialization(
893892
context, *sema, matrixTemplateDecl,
894893
ArrayRef<TemplateArgument>(templateArgs));
895894

896-
#ifndef NDEBUG
897-
// Verify that we can read the field member from the template record.
898-
DXASSERT(matrixSpecializationType->getAsCXXRecordDecl(),
895+
if (!matrixSpecializationType.isNull() &&
896+
!sema->Diags.hasFatalErrorOccurred()) {
897+
assert(matrixSpecializationType->getAsCXXRecordDecl() &&
899898
"type of non-dependent specialization is not a RecordType");
900-
DeclContext::lookup_result lookupResult =
901-
matrixSpecializationType->getAsCXXRecordDecl()->lookup(
902-
DeclarationName(&context.Idents.get(StringRef("h"))));
903-
// Template specialization is suppressed if a fatal error has been registered
904-
// so only assert if lookup failed for some other reason.
905-
DXASSERT(sema->Diags.hasFatalErrorOccurred() || !lookupResult.empty(),
899+
// Verify that we can read the field member from the template record.
900+
[[maybe_unused]] DeclContext::lookup_result lookupResult =
901+
matrixSpecializationType->getAsCXXRecordDecl()->lookup(
902+
DeclarationName(&context.Idents.get(StringRef("h"))));
903+
assert(!lookupResult.empty() &&
906904
"otherwise matrix handle cannot be looked up");
907-
#endif
905+
}
908906

909907
return matrixSpecializationType;
910908
}
@@ -930,18 +928,17 @@ GetOrCreateVectorSpecialization(ASTContext &context, Sema *sema,
930928
context, *sema, vectorTemplateDecl,
931929
ArrayRef<TemplateArgument>(templateArgs));
932930

933-
#ifndef NDEBUG
934-
// Verify that we can read the field member from the template record.
935-
DXASSERT(vectorSpecializationType->getAsCXXRecordDecl(),
931+
if (!vectorSpecializationType.isNull() &&
932+
!sema->Diags.hasFatalErrorOccurred()) {
933+
assert(vectorSpecializationType->getAsCXXRecordDecl() &&
936934
"type of non-dependent specialization is not a RecordType");
937-
DeclContext::lookup_result lookupResult =
938-
vectorSpecializationType->getAsCXXRecordDecl()->lookup(
939-
DeclarationName(&context.Idents.get(StringRef("h"))));
940-
// Template specialization is suppressed if a fatal error has been registered
941-
// so only assert if lookup failed for some other reason.
942-
DXASSERT(sema->Diags.hasFatalErrorOccurred() || !lookupResult.empty(),
935+
// Verify that we can read the field member from the template record.
936+
[[maybe_unused]] DeclContext::lookup_result lookupResult =
937+
vectorSpecializationType->getAsCXXRecordDecl()->lookup(
938+
DeclarationName(&context.Idents.get(StringRef("h"))));
939+
assert(!lookupResult.empty() &&
943940
"otherwise vector handle cannot be looked up");
944-
#endif
941+
}
945942

946943
return vectorSpecializationType;
947944
}
@@ -960,18 +957,16 @@ GetOrCreateNodeOutputRecordSpecialization(ASTContext &context, Sema *sema,
960957
QualType specializationType = GetOrCreateTemplateSpecialization(
961958
context, *sema, templateDecl, ArrayRef<TemplateArgument>(templateArgs));
962959

963-
#ifdef DBG
964-
// Verify that we can read the field member from the template record.
965-
DXASSERT(specializationType->getAsCXXRecordDecl(),
960+
if (!specializationType.isNull() && !sema->Diags.hasFatalErrorOccurred()) {
961+
assert(specializationType->getAsCXXRecordDecl() &&
966962
"type of non-dependent specialization is not a RecordType");
967-
DeclContext::lookup_result lookupResult =
968-
specializationType->getAsCXXRecordDecl()->lookup(
969-
DeclarationName(&context.Idents.get(StringRef("h"))));
970-
// Template specialization is suppressed if a fatal error has been registered
971-
// so only assert if lookup failed for some other reason.
972-
DXASSERT(sema->Diags.hasFatalErrorOccurred() || !lookupResult.empty(),
963+
// Verify that we can read the field member from the template record.
964+
[[maybe_unused]] DeclContext::lookup_result lookupResult =
965+
specializationType->getAsCXXRecordDecl()->lookup(
966+
DeclarationName(&context.Idents.get(StringRef("h"))));
967+
assert(!lookupResult.empty() &&
973968
"otherwise *NodeOutputRecords handle cannot be looked up");
974-
#endif
969+
}
975970

976971
return specializationType;
977972
}
@@ -5105,12 +5100,13 @@ class HLSLExternalSource : public ExternalSemaSource {
51055100
// This is a bit of a special case we need to handle. Because the
51065101
// buffer types don't use their template parameter in a way that would
51075102
// force instantiation, we need to force specialization here.
5108-
GetOrCreateTemplateSpecialization(
5103+
QualType Ty = GetOrCreateTemplateSpecialization(
51095104
*m_context, *m_sema,
51105105
cast<ClassTemplateDecl>(
51115106
TST->getTemplateName().getAsTemplateDecl()),
51125107
llvm::ArrayRef<TemplateArgument>(TST->getArgs(),
51135108
TST->getNumArgs()));
5109+
return Ty.isNull();
51145110
}
51155111
if (const RecordType *recordType = argType->getAs<RecordType>()) {
51165112
if (!recordType->getDecl()->isCompleteDefinition()) {

tools/clang/test/DXC/specialization_with_fatal_error.hlsl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
// Clang suppresses template specialization if a fatal error has been
44
// registered (this reduces the risk of a cascade of secondary errors).
5-
// However, DXC DXASSERTs if a template specialization fails - which
6-
// prevents the error diagnostic being generated.
7-
// We check here that a DXASSERT is no longer raised if a fatal error
5+
// However, DXC asserted if a template specialization failed - which
6+
// prevented the error diagnostic being generated.
7+
// We check here that an assert is no longer raised if a fatal error
88
// has been registered, and that the error diagnostic is generated.
99

1010
float a;
@@ -16,7 +16,7 @@ float a;
1616
void b() {};
1717

1818
int3 c(int X) {
19-
// DXASSERT was triggered if include file a.h doesn't exist, and the error
20-
// diagnostic was not produced.
21-
return X.xxx;
19+
// an assert was triggered for the expression below when include file a.h
20+
// doesn't exist, and the error diagnostic expected above was not produced.
21+
return X.xxx;
2222
}

0 commit comments

Comments
 (0)