]> granicus.if.org Git - clang/commitdiff
When we run into a constructor or destructor that is defined in the
authorDouglas Gregor <dgregor@apple.com>
Tue, 1 Nov 2011 22:13:30 +0000 (22:13 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 1 Nov 2011 22:13:30 +0000 (22:13 +0000)
wrong class, make sure to drop it immediately; we don't want that
constructor to be available within the DeclContext. Fixes
<rdar://problem/9677163>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143506 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/member-class-11.cpp [new file with mode: 0644]

index 6bd0d25f754685dfe3cd0c91bc0c5394bb35452c..806608cf439c88c447886f0f6cac990e007a8681 100644 (file)
@@ -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<CXXRecordDecl>(CurContext))))
+            return 0;
+        }
+
         // Pretend that this qualifier was not here.
         D.getCXXScopeSpec().clear();
       }
index 60a128165fc8280d6433c14eb6ccb70e568bd535..61385f9348185c7ed72dd87952ec5570e25effa7 100644 (file)
@@ -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 (file)
index 0000000..c230c53
--- /dev/null
@@ -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}}
+};