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.
llvm-svn: 150359
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 52789c7..3c73f68 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3991,8 +3991,15 @@
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 @@
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 @@
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 @@
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");