summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-12-13 08:12:56 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-12-13 08:12:56 +0000
commit2887ad35c58d353c42513fcbf3c6019d0b72e5cb (patch)
tree7cd9a85e5ae2cb73dfc3d8f4a46f4395d97efb64 /clang/lib/Sema/SemaStmt.cpp
parentf2ef94e770e388add98d992e1c4d3eb365e21767 (diff)
downloadbcm5719-llvm-2887ad35c58d353c42513fcbf3c6019d0b72e5cb.tar.gz
bcm5719-llvm-2887ad35c58d353c42513fcbf3c6019d0b72e5cb.zip
Sema: Constexpr functions must have return statements which have an expr
clang lets programmers be pretty cavalier when it comes to void return statements in functions which have non-void return types. However, we cannot be so forgiving in constexpr functions: evaluation will go off the rails very quickly. Instead, keep the return statement in the AST but mark the function as invalid. Doing so gives us nice diagnostics while making constexpr evaluation halt. This fixes PR21859. llvm-svn: 224189
Diffstat (limited to 'clang/lib/Sema/SemaStmt.cpp')
-rw-r--r--clang/lib/Sema/SemaStmt.cpp20
1 files changed, 16 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 78e33c3bf8c..8f6c5c6fe34 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3039,14 +3039,26 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
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);
OpenPOWER on IntegriCloud