]> granicus.if.org Git - clang/commitdiff
Don't poke at an undefined class type of a field. Fixes PR7355.
authorDouglas Gregor <dgregor@apple.com>
Wed, 16 Jun 2010 16:54:04 +0000 (16:54 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 16 Jun 2010 16:54:04 +0000 (16:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106111 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/SemaTemplate/instantiate-field.cpp

index f10927d18e987e46fbd522a05592b439403501f8..fbd4ff446acc326d4a3088f0f2acc1f84073627e 100644 (file)
@@ -5803,41 +5803,42 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
 
     if (const RecordType *RT = EltTy->getAs<RecordType>()) {
       CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
-
-      if (!RDecl->hasTrivialConstructor())
-        CXXRecord->setHasTrivialConstructor(false);
-      if (!RDecl->hasTrivialCopyConstructor())
-        CXXRecord->setHasTrivialCopyConstructor(false);
-      if (!RDecl->hasTrivialCopyAssignment())
-        CXXRecord->setHasTrivialCopyAssignment(false);
-      if (!RDecl->hasTrivialDestructor())
-        CXXRecord->setHasTrivialDestructor(false);
-
-      // C++ 9.5p1: An object of a class with a non-trivial
-      // constructor, a non-trivial copy constructor, a non-trivial
-      // destructor, or a non-trivial copy assignment operator
-      // cannot be a member of a union, nor can an array of such
-      // objects.
-      // TODO: C++0x alters this restriction significantly.
-      if (Record->isUnion()) {
-        // We check for copy constructors before constructors
-        // because otherwise we'll never get complaints about
-        // copy constructors.
-
-        CXXSpecialMember member = CXXInvalid;
+      if (RDecl->getDefinition()) {
+        if (!RDecl->hasTrivialConstructor())
+          CXXRecord->setHasTrivialConstructor(false);
         if (!RDecl->hasTrivialCopyConstructor())
-          member = CXXCopyConstructor;
-        else if (!RDecl->hasTrivialConstructor())
-          member = CXXConstructor;
-        else if (!RDecl->hasTrivialCopyAssignment())
-          member = CXXCopyAssignment;
-        else if (!RDecl->hasTrivialDestructor())
-          member = CXXDestructor;
-
-        if (member != CXXInvalid) {
-          Diag(Loc, diag::err_illegal_union_member) << Name << member;
-          DiagnoseNontrivial(RT, member);
-          NewFD->setInvalidDecl();
+          CXXRecord->setHasTrivialCopyConstructor(false);
+        if (!RDecl->hasTrivialCopyAssignment())
+          CXXRecord->setHasTrivialCopyAssignment(false);
+        if (!RDecl->hasTrivialDestructor())
+          CXXRecord->setHasTrivialDestructor(false);
+
+        // C++ 9.5p1: An object of a class with a non-trivial
+        // constructor, a non-trivial copy constructor, a non-trivial
+        // destructor, or a non-trivial copy assignment operator
+        // cannot be a member of a union, nor can an array of such
+        // objects.
+        // TODO: C++0x alters this restriction significantly.
+        if (Record->isUnion()) {
+          // We check for copy constructors before constructors
+          // because otherwise we'll never get complaints about
+          // copy constructors.
+
+          CXXSpecialMember member = CXXInvalid;
+          if (!RDecl->hasTrivialCopyConstructor())
+            member = CXXCopyConstructor;
+          else if (!RDecl->hasTrivialConstructor())
+            member = CXXConstructor;
+          else if (!RDecl->hasTrivialCopyAssignment())
+            member = CXXCopyAssignment;
+          else if (!RDecl->hasTrivialDestructor())
+            member = CXXDestructor;
+
+          if (member != CXXInvalid) {
+            Diag(Loc, diag::err_illegal_union_member) << Name << member;
+            DiagnoseNontrivial(RT, member);
+            NewFD->setInvalidDecl();
+          }
         }
       }
     }
index a260635778ca2d6f68cacc82980f964949e4b3dc..d825cd7cc613c4ca7654faca714ea0eb8f5613cd 100644 (file)
@@ -81,3 +81,12 @@ namespace PR7123 {
     sort(x,x);
   }
 }
+
+namespace PR7355 {
+  template<typename T1> class A {
+    class D; // expected-note{{declared here}}
+    D d; //expected-error{{implicit instantiation of undefined member 'PR7355::A<int>::D'}}
+  };
+
+  A<int> ai; // expected-note{{in instantiation of}}
+}