aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-13 03:54:03 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-13 03:54:03 +0000
commit86c3ae46250cdcc57778c27826060779a92f3815 (patch)
tree0d448fb2248c76e1339de8ad2c8c28d2b08d9b14 /lib/AST/ExprConstant.cpp
parent9b338a7bca39a68ae9f8c57d9210f19f7e45b665 (diff)
Update constexpr implementation to match CWG's chosen approach for core issues
1358, 1360, 1452 and 1453. - Instantiations of constexpr functions are always constexpr. This removes the need for separate declaration/definition checking, which is now gone. - This makes it possible for a constexpr function to be virtual, if they are only dependently virtual. Virtual calls to such functions are not constant expressions. - Likewise, it's now possible for a literal type to have virtual base classes. A constexpr constructor for such a type cannot actually produce a constant expression, though, so add a special-case diagnostic for a constructor call to such a type rather than trying to evaluate it. - Classes with trivial default constructors (for which value initialization can produce a fully-initialized value) are considered literal types. - Classes with volatile members are not literal types. - constexpr constructors can be members of non-literal types. We do not yet use static initialization for global objects constructed in this way. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150359 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 998bb705f9..520e3cbbaf 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -2033,6 +2033,12 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
if (!Info.CheckCallLimit(CallLoc))
return false;
+ const CXXRecordDecl *RD = Definition->getParent();
+ if (RD->getNumVBases()) {
+ Info.Diag(CallLoc, diag::note_constexpr_virtual_base) << RD;
+ return false;
+ }
+
CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues.data());
// If it's a delegating constructor, just delegate.
@@ -2044,7 +2050,6 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
// For a trivial copy or move constructor, perform an APValue copy. This is
// essential for unions, where the operations performed by the constructor
// cannot be represented by ctor-initializers.
- const CXXRecordDecl *RD = Definition->getParent();
if (Definition->isDefaulted() &&
((Definition->isCopyConstructor() && RD->hasTrivialCopyConstructor()) ||
(Definition->isMoveConstructor() && RD->hasTrivialMoveConstructor()))) {
@@ -2083,7 +2088,7 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
QualType BaseType((*I)->getBaseClass(), 0);
#ifndef NDEBUG
// Non-virtual base classes are initialized in the order in the class
- // definition. We cannot have a virtual base class for a literal type.
+ // definition. We have already checked for virtual base classes.
assert(!BaseIt->isVirtual() && "virtual base for literal type");
assert(Info.Ctx.hasSameType(BaseIt->getType(), BaseType) &&
"base class initializers not in expected order");
@@ -2414,6 +2419,7 @@ public:
const FunctionDecl *FD = 0;
LValue *This = 0, ThisVal;
llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs());
+ bool HasQualifier = false;
// Extract function decl and 'this' pointer from the callee.
if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
@@ -2424,6 +2430,7 @@ public:
return false;
Member = ME->getMemberDecl();
This = &ThisVal;
+ HasQualifier = ME->hasQualifier();
} else if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
// Indirect bound member calls ('.*' or '->*').
Member = HandleMemberPointerAccess(Info, BE, ThisVal, false);
@@ -2472,6 +2479,12 @@ public:
if (This && !This->checkSubobject(Info, E, CSK_This))
return false;
+ // DR1358 allows virtual constexpr functions in some cases. Don't allow
+ // calls to such functions in constant expressions.
+ if (This && !HasQualifier &&
+ isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
+ return Error(E, diag::note_constexpr_virtual_call);
+
const FunctionDecl *Definition = 0;
Stmt *Body = FD->getBody(Definition);
APValue Result;