"'enable_if' attribute expression never produces a constant expression">;
def err_constexpr_body_no_return : Error<
"no return statement in constexpr function">;
+def err_constexpr_return_missing_expr : Error<
+ "non-void constexpr function %0 should return a value">;
def warn_cxx11_compat_constexpr_body_no_return : Warning<
"constexpr function with no return statements is incompatible with C++ "
"standards before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr);
} else if (!RetValExp && !HasDependentReturnType) {
- unsigned DiagID = diag::warn_return_missing_expr; // C90 6.6.6.4p4
- // C99 6.8.6.4p1 (ext_ since GCC warns)
- if (getLangOpts().C99) DiagID = diag::ext_return_missing_expr;
+ FunctionDecl *FD = getCurFunctionDecl();
- if (FunctionDecl *FD = getCurFunctionDecl())
+ unsigned DiagID;
+ if (getLangOpts().CPlusPlus11 && FD && FD->isConstexpr()) {
+ // C++11 [stmt.return]p2
+ DiagID = diag::err_constexpr_return_missing_expr;
+ FD->setInvalidDecl();
+ } else if (getLangOpts().C99) {
+ // C99 6.8.6.4p1 (ext_ since GCC warns)
+ DiagID = diag::ext_return_missing_expr;
+ } else {
+ // C90 6.6.6.4p4
+ DiagID = diag::warn_return_missing_expr;
+ }
+
+ if (FD)
Diag(ReturnLoc, DiagID) << FD->getIdentifier() << 0/*fn*/;
else
Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/;
+
Result = new (Context) ReturnStmt(ReturnLoc);
} else {
assert(RetValExp || HasDependentReturnType);
static_assert(&Bar::x != nullptr, "");
static_assert(&Bar::x != &Bar::y, ""); // expected-error {{constant expression}}
}
+
+namespace PR21859 {
+ constexpr int Fun() { return; } // expected-error {{non-void constexpr function 'Fun' should return a value}}
+ constexpr int Var = Fun(); // expected-error {{constexpr variable 'Var' must be initialized by a constant expression}}
+}