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/Sema/SemaDecl.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/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 52789c781c..3c73f689e7 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3991,8 +3991,15 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TemplateParamLists.release()); } - if (D.getDeclSpec().isConstexprSpecified()) + if (D.getDeclSpec().isConstexprSpecified()) { NewVD->setConstexpr(true); + SourceLocation ConstexprLoc = D.getDeclSpec().getConstexprSpecLoc(); + if (!NewVD->isInvalidDecl() && !R->isDependentType() && + RequireLiteralType(NewVD->getLocation(), R, + PDiag(diag::err_constexpr_var_non_literal) + << SourceRange(ConstexprLoc))) + NewVD->setInvalidDecl(); + } } // Set the lexical context. If the declarator has a C++ scope specifier, the @@ -5347,10 +5354,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Previous.getResultKind() != LookupResult::FoundOverloaded) && "previous declaration set still overloaded"); - if (NewFD->isConstexpr() && !NewFD->isInvalidDecl() && - !CheckConstexprFunctionDecl(NewFD, CCK_Declaration)) - NewFD->setInvalidDecl(); - NamedDecl *PrincipalDecl = (FunctionTemplate ? cast<NamedDecl>(FunctionTemplate) : NewFD); @@ -6223,8 +6226,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, if (DclT->isDependentType()) { // Allow any 'static constexpr' members, whether or not they are of literal - // type. We separately check that the initializer is a constant expression, - // which implicitly requires the member to be of literal type. + // type. We separately check that every constexpr variable is of literal + // type. } else if (VDecl->isConstexpr()) { // Require constness. @@ -7350,8 +7353,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, ActivePolicy = &WP; } - if (FD && FD->isConstexpr() && !FD->isInvalidDecl() && - !CheckConstexprFunctionBody(FD, Body, IsInstantiation)) + if (!IsInstantiation && FD && FD->isConstexpr() && !FD->isInvalidDecl() && + (!CheckConstexprFunctionDecl(FD) || + !CheckConstexprFunctionBody(FD, Body))) FD->setInvalidDecl(); assert(ExprCleanupObjects.empty() && "Leftover temporaries in function"); |