[cfe-commits] r106111 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/SemaTemplate/instantiate-field.cpp

Douglas Gregor dgregor at apple.com
Wed Jun 16 09:54:04 PDT 2010


Author: dgregor
Date: Wed Jun 16 11:54:04 2010
New Revision: 106111

URL: http://llvm.org/viewvc/llvm-project?rev=106111&view=rev
Log:
Don't poke at an undefined class type of a field. Fixes PR7355.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaTemplate/instantiate-field.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=106111&r1=106110&r2=106111&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jun 16 11:54:04 2010
@@ -5803,41 +5803,42 @@
 
     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();
+          }
         }
       }
     }

Modified: cfe/trunk/test/SemaTemplate/instantiate-field.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-field.cpp?rev=106111&r1=106110&r2=106111&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-field.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-field.cpp Wed Jun 16 11:54:04 2010
@@ -81,3 +81,12 @@
     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}}
+}





More information about the cfe-commits mailing list