[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