aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-07-02 21:00:41 +0000
committerDouglas Gregor <dgregor@apple.com>2012-07-02 21:00:41 +0000
commit8a50fe0d76b0f245b4cdd599230f2ee023be82cd (patch)
tree764627a1d04ce42d4f3c6d9759792c80298be54b
parent9224fb88ffe787a1b49e094cf23a03f0739dcb48 (diff)
Be more eager about setting the 'Invalid' bit on an invalid class
template instantiation. I wasn't able to reproduce this down to anything small enough to put in our test suite, but it's "obviously" okay to set the invalid bit earlier and precludes a known-broken-but-not-marked-broken class from being used elsewhere. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159584 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp23
-rw-r--r--test/SemaCXX/PR9460.cpp6
3 files changed, 15 insertions, 16 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index babeaf7bd7..ad650751d6 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1119,6 +1119,8 @@ Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
Virtual, Access, TInfo,
EllipsisLoc))
return BaseSpec;
+ else
+ Class->setInvalidDecl();
return true;
}
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index b80aaa2bbc..8973916f37 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1832,8 +1832,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
const MultiLevelTemplateArgumentList &TemplateArgs,
TemplateSpecializationKind TSK,
bool Complain) {
- bool Invalid = false;
-
CXXRecordDecl *PatternDef
= cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
if (DiagnoseUninstantiableTemplate(*this, PointOfInstantiation, Instantiation,
@@ -1879,7 +1877,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
// Do substitution on the base class specifiers.
if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
- Invalid = true;
+ Instantiation->setInvalidDecl();
TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
SmallVector<Decl*, 4> Fields;
@@ -1905,7 +1903,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
continue;
if ((*Member)->isInvalidDecl()) {
- Invalid = true;
+ Instantiation->setInvalidDecl();
continue;
}
@@ -1932,11 +1930,12 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
}
if (NewMember->isInvalidDecl())
- Invalid = true;
+ Instantiation->setInvalidDecl();
} else {
// FIXME: Eventually, a NULL return will mean that one of the
- // instantiations was a semantic disaster, and we'll want to set Invalid =
- // true. For now, we expect to skip some members that we can't yet handle.
+ // instantiations was a semantic disaster, and we'll want to mark the
+ // declaration invalid.
+ // For now, we expect to skip some members that we can't yet handle.
}
}
@@ -1995,9 +1994,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
Instantiation->setRBraceLoc(Pattern->getRBraceLoc());
}
- if (Instantiation->isInvalidDecl())
- Invalid = true;
- else {
+ if (!Instantiation->isInvalidDecl()) {
// Instantiate any out-of-line class template partial
// specializations now.
for (TemplateDeclInstantiator::delayed_partial_spec_iterator
@@ -2007,7 +2004,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
P->first,
P->second)) {
- Invalid = true;
+ Instantiation->setInvalidDecl();
break;
}
}
@@ -2016,7 +2013,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
// Exit the scope of this instantiation.
SavedContext.pop();
- if (!Invalid) {
+ if (!Instantiation->isInvalidDecl()) {
Consumer.HandleTagDeclDefinition(Instantiation);
// Always emit the vtable for an explicit instantiation definition
@@ -2025,7 +2022,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
MarkVTableUsed(PointOfInstantiation, Instantiation, true);
}
- return Invalid;
+ return Instantiation->isInvalidDecl();
}
/// \brief Instantiate the definition of an enum from a given pattern.
diff --git a/test/SemaCXX/PR9460.cpp b/test/SemaCXX/PR9460.cpp
index 0dd8446770..5b8b7b2cf6 100644
--- a/test/SemaCXX/PR9460.cpp
+++ b/test/SemaCXX/PR9460.cpp
@@ -8,11 +8,11 @@ struct basic_string{
basic_string(aT*);
};
-struct runtime_error{
- runtime_error(
+struct runtime_error{ // expected-note{{candidate constructor}}
+ runtime_error( // expected-note{{candidate constructor}}
basic_string<char> struct{ // expected-error {{cannot combine with previous 'type-name' declaration specifier}}
a(){ // expected-error {{requires a type specifier}}
- runtime_error(0);
+ runtime_error(0); // expected-error{{no matching conversion for functional-style cast from 'int' to 'runtime_error'}}
}
}
);