From 8a50fe0d76b0f245b4cdd599230f2ee023be82cd Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 2 Jul 2012 21:00:41 +0000 Subject: [PATCH] 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 --- lib/Sema/SemaDeclCXX.cpp | 2 ++ lib/Sema/SemaTemplateInstantiate.cpp | 23 ++++++++++------------- test/SemaCXX/PR9460.cpp | 6 +++--- 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(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 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 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'}} } } ); -- 2.40.0