diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-13 03:54:03 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-13 03:54:03 +0000 |
commit | 86c3ae46250cdcc57778c27826060779a92f3815 (patch) | |
tree | 0d448fb2248c76e1339de8ad2c8c28d2b08d9b14 /lib/AST/ExprConstant.cpp | |
parent | 9b338a7bca39a68ae9f8c57d9210f19f7e45b665 (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.cpp | 17 |
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; |