From: Douglas Gregor Date: Tue, 1 Nov 2011 22:13:30 +0000 (+0000) Subject: When we run into a constructor or destructor that is defined in the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d8419c12a1ffaf710fa11fb1091f10f03f2c1dc;p=clang When we run into a constructor or destructor that is defined in the wrong class, make sure to drop it immediately; we don't want that constructor to be available within the DeclContext. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143506 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6bd0d25f75..806608cf43 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3233,13 +3233,23 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, // class X { // void X::f(); // }; - if (CurContext->Equals(DC)) + if (CurContext->Equals(DC)) { Diag(D.getIdentifierLoc(), diag::warn_member_extra_qualification) << Name << FixItHint::CreateRemoval(D.getCXXScopeSpec().getRange()); - else + } else { Diag(D.getIdentifierLoc(), diag::err_member_qualification) << Name << D.getCXXScopeSpec().getRange(); - + + // C++ constructors and destructors with incorrect scopes can break + // our AST invariants by having the wrong underlying types. If + // that's the case, then drop this declaration entirely. + if ((Name.getNameKind() == DeclarationName::CXXConstructorName || + Name.getNameKind() == DeclarationName::CXXDestructorName) && + !Context.hasSameType(Name.getCXXNameType(), + Context.getTypeDeclType(cast(CurContext)))) + return 0; + } + // Pretend that this qualifier was not here. D.getCXXScopeSpec().clear(); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 60a128165f..61385f9348 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1534,11 +1534,11 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, DeclContext *DC = 0; if ((DC = computeDeclContext(SS, false)) && DC->Equals(CurContext)) Diag(D.getIdentifierLoc(), diag::warn_member_extra_qualification) - << Name << FixItHint::CreateRemoval(SS.getRange()); + << Name << FixItHint::CreateRemoval(SS.getRange()); else Diag(D.getIdentifierLoc(), diag::err_member_qualification) << Name << SS.getRange(); - + SS.clear(); } diff --git a/test/SemaCXX/member-class-11.cpp b/test/SemaCXX/member-class-11.cpp new file mode 100644 index 0000000000..c230c5305e --- /dev/null +++ b/test/SemaCXX/member-class-11.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +struct rdar9677163 { + struct Y { ~Y(); }; + struct Z { ~Z(); }; + Y::~Y() { } // expected-error{{non-friend class member '~Y' cannot have a qualified name}} + ~Z(); // expected-error{{expected the class name after '~' to name the enclosing class}} +};