[cfe-commits] r148094 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclCXX.cpp test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp

Richard Smith richard-llvm at metafoo.co.uk
Thu Jan 12 20:54:01 PST 2012


Author: rsmith
Date: Thu Jan 12 22:54:00 2012
New Revision: 148094

URL: http://llvm.org/viewvc/llvm-project?rev=148094&view=rev
Log:
PR11754: Reject non-static constexpr member functions in classes with virtual
base classes.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=148094&r1=148093&r2=148094&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jan 12 22:54:00 2012
@@ -1308,11 +1308,13 @@
 def err_constexpr_virtual : Error<"virtual function cannot be constexpr">;
 def note_constexpr_tmpl_virtual : Note<"function template instantiation is not "
   "constexpr because it is virtual">;
-def err_constexpr_virtual_base : Error<"constexpr constructor not allowed in "
-  "%select{class|struct}0 with virtual base %plural{1:class|:classes}1">;
-def note_constexpr_tmpl_virtual_base : Note<"constructor template instantiation is "
-  "not constexpr because %select{class|struct}0 has virtual base "
-  "%plural{1:class|:classes}1">;
+def err_constexpr_virtual_base : Error<
+  "constexpr %select{member function|constructor}0 not allowed in "
+  "%select{class|struct}1 with virtual base %plural{1:class|:classes}2">;
+def note_constexpr_tmpl_virtual_base : Note<
+  "%select{function|constructor}0 template instantiation is "
+  "not constexpr because %select{class|struct}1 has virtual base "
+  "%plural{1:class|:classes}2">;
 def note_non_literal_virtual_base : Note<"%select{class|struct}0 with virtual "
   "base %plural{1:class|:classes}1 is not a literal type">;
 def note_constexpr_virtual_base_here : Note<"virtual base class declared here">;

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=148094&r1=148093&r2=148094&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jan 12 22:54:00 2012
@@ -648,7 +648,7 @@
 // the requirements of a constexpr function declaration or a constexpr
 // constructor declaration. Return true if it does, false if not.
 //
-// This implements C++0x [dcl.constexpr]p3,4, as amended by N3308.
+// This implements C++11 [dcl.constexpr]p3,4, as amended by N3308.
 //
 // \param CCK Specifies whether to produce diagnostics if the function does not
 // satisfy the requirements.
@@ -659,17 +659,16 @@
            NewFD->getTemplateInstantiationPattern()->isConstexpr())) &&
          "only constexpr templates can be instantiated non-constexpr");
 
-  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(NewFD)) {
-    // C++0x [dcl.constexpr]p4:
-    //  In the definition of a constexpr constructor, each of the parameter
-    //  types shall be a literal type.
-    if (!CheckConstexprParameterTypes(*this, NewFD, CCK))
-      return false;
-
+  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
+  if (MD && MD->isInstance()) {
+    // C++11 [dcl.constexpr]p4: In the definition of a constexpr constructor...
     //  In addition, either its function-body shall be = delete or = default or
     //  it shall satisfy the following constraints:
     //  - the class shall not have any virtual base classes;
-    const CXXRecordDecl *RD = CD->getParent();
+    //
+    // We apply this to constexpr member functions too: the class cannot be a
+    // literal type, so the members are not permitted to be constexpr.
+    const CXXRecordDecl *RD = MD->getParent();
     if (RD->getNumVBases()) {
       // Note, this is still illegal if the body is = default, since the
       // implicit body does not satisfy the requirements of a constexpr
@@ -679,7 +678,8 @@
         Diag(NewFD->getLocation(),
              CCK == CCK_Declaration ? diag::err_constexpr_virtual_base
                                     : diag::note_constexpr_tmpl_virtual_base)
-          << RD->isStruct() << RD->getNumVBases();
+          << isa<CXXConstructorDecl>(NewFD) << RD->isStruct()
+          << RD->getNumVBases();
         for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
                E = RD->vbases_end(); I != E; ++I)
           Diag(I->getSourceRange().getBegin(),
@@ -687,8 +687,10 @@
       }
       return false;
     }
-  } else {
-    // C++0x [dcl.constexpr]p3:
+  }
+
+  if (!isa<CXXConstructorDecl>(NewFD)) {
+    // C++11 [dcl.constexpr]p3:
     //  The definition of a constexpr function shall satisfy the following
     //  constraints:
     // - it shall not be virtual;
@@ -705,7 +707,7 @@
         while (!WrittenVirtual->isVirtualAsWritten())
           WrittenVirtual = *WrittenVirtual->begin_overridden_methods();
         if (WrittenVirtual != Method)
-          Diag(WrittenVirtual->getLocation(), 
+          Diag(WrittenVirtual->getLocation(),
                diag::note_overridden_virtual_function);
       }
       return false;
@@ -723,12 +725,12 @@
              diag::note_constexpr_tmpl_non_literal_return) << RT;
       return false;
     }
-
-    // - each of its parameter types shall be a literal type;
-    if (!CheckConstexprParameterTypes(*this, NewFD, CCK))
-      return false;
   }
 
+  // - each of its parameter types shall be a literal type;
+  if (!CheckConstexprParameterTypes(*this, NewFD, CCK))
+    return false;
+
   return true;
 }
 

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp?rev=148094&r1=148093&r2=148094&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp Thu Jan 12 22:54:00 2012
@@ -63,6 +63,10 @@
   constexpr int SelfParam(U);
 };
 
+struct V : virtual U { // expected-note {{here}}
+  constexpr int F(); // expected-error {{constexpr member function not allowed in struct with virtual base class}}
+};
+
 //  or a compound-statememt that contains only
 constexpr int AllowedStmts() {
   //  - null statements





More information about the cfe-commits mailing list