constexpr: semantic checking for constexpr functions and constructors. Based in
part on patches by Peter Collingbourne.
We diverge from the C++11 standard in a few areas, mostly related to checking
constexpr function declarations, and not just definitions. See WG21 paper
N3308=11-0078 for details.
Function invocation substitution is not available in this patch; constexpr
functions cannot yet be used from within constant expressions.
llvm-svn: 140926
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 942c1bc..f4b6ce9 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4770,15 +4770,11 @@
// are implicitly inline.
NewFD->setImplicitlyInline();
- // FIXME: If this is a redeclaration, check the original declaration was
- // marked constepr.
-
// C++0x [dcl.constexpr]p3: functions declared constexpr are required to
// be either constructors or to return a literal type. Therefore,
// destructors cannot be declared constexpr.
if (isa<CXXDestructorDecl>(NewFD))
- Diag(D.getDeclSpec().getConstexprSpecLoc(),
- diag::err_constexpr_dtor);
+ Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_constexpr_dtor);
}
// If __module_private__ was specified, mark the function accordingly.
@@ -5050,6 +5046,10 @@
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);
@@ -6963,6 +6963,10 @@
ActivePolicy = &WP;
}
+ if (FD && FD->isConstexpr() && !FD->isInvalidDecl() &&
+ !CheckConstexprFunctionBody(FD, Body))
+ FD->setInvalidDecl();
+
assert(ExprTemporaries.empty() && "Leftover temporaries in function");
assert(!ExprNeedsCleanups && "Unaccounted cleanups in function");
}