[cfe-commits] r151486 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CXX/class/class.union/p1.cpp test/SemaCXX/cxx0x-nontrivial-union.cpp

Richard Smith richard-llvm at metafoo.co.uk
Sun Feb 26 02:50:33 PST 2012


Author: rsmith
Date: Sun Feb 26 04:50:32 2012
New Revision: 151486

URL: http://llvm.org/viewvc/llvm-project?rev=151486&view=rev
Log:
Don't assert when trying to diagnose why a class with a constructor template is
non-trivial.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CXX/class/class.union/p1.cpp
    cfe/trunk/test/SemaCXX/cxx0x-nontrivial-union.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=151486&r1=151485&r2=151486&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Feb 26 04:50:32 2012
@@ -8935,6 +8935,19 @@
   return false;
 }
 
+/// If the given constructor is user-provided, produce a diagnostic explaining
+/// that it makes the class non-trivial.
+static bool DiagnoseNontrivialUserProvidedCtor(Sema &S, QualType QT,
+                                               CXXConstructorDecl *CD,
+                                               Sema::CXXSpecialMember CSM) {
+  if (!CD->isUserProvided())
+    return false;
+
+  SourceLocation CtorLoc = CD->getLocation();
+  S.Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << CSM;
+  return true;
+}
+
 /// DiagnoseNontrivial - Given that a class has a non-trivial
 /// special member, figure out why.
 void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) {
@@ -8949,17 +8962,20 @@
   case CXXDefaultConstructor:
     if (RD->hasUserDeclaredConstructor()) {
       typedef CXXRecordDecl::ctor_iterator ctor_iter;
-      for (ctor_iter ci = RD->ctor_begin(), ce = RD->ctor_end(); ci != ce;++ci){
-        const FunctionDecl *body = 0;
-        ci->hasBody(body);
-        if (!body || !cast<CXXConstructorDecl>(body)->isImplicitlyDefined()) {
-          SourceLocation CtorLoc = ci->getLocation();
-          Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << member;
+      for (ctor_iter CI = RD->ctor_begin(), CE = RD->ctor_end(); CI != CE; ++CI)
+        if (DiagnoseNontrivialUserProvidedCtor(*this, QT, *CI, member))
           return;
-        }
-      }
 
-      llvm_unreachable("found no user-declared constructors");
+      // No user-provided constructors; look for constructor templates.
+      typedef CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl>
+          tmpl_iter;
+      for (tmpl_iter TI(RD->decls_begin()), TE(RD->decls_end());
+           TI != TE; ++TI) {
+        CXXConstructorDecl *CD =
+            dyn_cast<CXXConstructorDecl>(TI->getTemplatedDecl());
+        if (CD && DiagnoseNontrivialUserProvidedCtor(*this, QT, CD, member))
+          return;
+      }
     }
     break;
 

Modified: cfe/trunk/test/CXX/class/class.union/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.union/p1.cpp?rev=151486&r1=151485&r2=151486&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.union/p1.cpp (original)
+++ cfe/trunk/test/CXX/class/class.union/p1.cpp Sun Feb 26 04:50:32 2012
@@ -19,6 +19,9 @@
 class Ctor2 {
   Ctor2(); // expected-note 3 {{because type 'Ctor2' has a user-declared constructor}}
 };
+class CtorTmpl {
+  template<typename T> CtorTmpl(); // expected-note {{because type 'CtorTmpl' has a user-declared constructor}}
+};
 
 class CopyCtor {
   CopyCtor(CopyCtor &cc) { abort(); } // expected-note 4 {{because type 'CopyCtor' has a user-declared copy constructor}}
@@ -38,6 +41,7 @@
   VirtualBase vbase; // expected-error {{union member 'vbase' has a non-trivial copy constructor}}
   Ctor ctor; // expected-error {{union member 'ctor' has a non-trivial constructor}}
   Ctor2 ctor2; // expected-error {{union member 'ctor2' has a non-trivial constructor}}
+  CtorTmpl ctortmpl; // expected-error {{union member 'ctortmpl' has a non-trivial constructor}}
   CopyCtor copyctor; // expected-error {{union member 'copyctor' has a non-trivial copy constructor}}
   CopyAssign copyassign; // expected-error {{union member 'copyassign' has a non-trivial copy assignment operator}}
   Dtor dtor; // expected-error {{union member 'dtor' has a non-trivial destructor}}

Modified: cfe/trunk/test/SemaCXX/cxx0x-nontrivial-union.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-nontrivial-union.cpp?rev=151486&r1=151485&r2=151486&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-nontrivial-union.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-nontrivial-union.cpp Sun Feb 26 04:50:32 2012
@@ -25,3 +25,7 @@
     non_trivial nt;
   };
 };
+
+// Don't crash on this.
+struct TemplateCtor { template<typename T> TemplateCtor(T); };
+union TemplateCtorMember { TemplateCtor s; };





More information about the cfe-commits mailing list