[PATCH] D55097: [constexpr][c++2a] Try-catch blocks in constexpr functions
Richard Smith - zygoloid via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 29 17:42:33 PST 2018
rsmith added inline comments.
================
Comment at: lib/AST/ExprConstant.cpp:4278-4287
+ // Evaluate try blocks by evaluating all sub statements and keep track
+ // whether there's a return.
+ EvalStmtResult ESR = ESR_Succeeded;
+ for (const Stmt *SubStmt : S->children()) {
+ EvalStmtResult SubStmtESR = EvaluateStmt(Result, Info, SubStmt, Case);
+ if (SubStmtESR != ESR_Succeeded && SubStmtESR != ESR_Returned)
+ return ESR_Failed;
----------------
The children of a `try` statement are the `try` body followed by the `catch` statements, in order. We only want to evaluate the normal body, so you should just recurse to evaluating `cast<CXXTryStmt>(S)->getTryBlock()`...
================
Comment at: lib/AST/ExprConstant.cpp:4290-4294
+ case Stmt::CXXCatchStmtClass:
+ // No need to evaluate catch since it will be ignored in case the try block
+ // is successfully evaluated.
+ return ESR_Succeeded;
}
----------------
... and this should then be unreachable.
================
Comment at: lib/Sema/SemaDeclCXX.cpp:1904-1905
+ case Stmt::CXXTryStmtClass:
+ if (!SemaRef.getLangOpts().CPlusPlus2a)
+ break;
+ if (!Cxx1yLoc.isValid())
----------------
Is there a reason to not allow this as an extension in earlier language modes?
================
Comment at: lib/Sema/SemaDeclCXX.cpp:1906-1907
+ break;
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = S->getBeginLoc();
+ for (Stmt *SubStmt : S->children())
----------------
`Cxx1yLoc` isn't right here; we should produce a -Wc++17-compat diagnostic, not a -Wc++14-compat diagnostic. We should probably prefer the `Cxx1zLoc` warning over the `Cxx1yLoc` warning if we have both.
================
Comment at: lib/Sema/SemaDeclCXX.cpp:1915-1922
+ case Stmt::CXXCatchStmtClass:
+ if (!SemaRef.getLangOpts().CPlusPlus2a)
+ break;
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = S->getBeginLoc();
+ // In case we got a valid constexpr try block, the catch block can be
+ // ignored since it will never be evaluated in a constexpr context.
----------------
We should just unconditionally allow `CXXCatchStmt`s (that is, don't bother checking the language mode, just walk the children), since whenever we encounter one we must also have a `CXXTryStmt`, which we'll already have checked.
================
Comment at: lib/Sema/SemaDeclCXX.cpp:1962-1983
+ // constexpr function try blocks are allowed in c++2a, assuming that the
+ // inner statements do also apply to general constexpr rules.
+ SourceLocation Cxx1yLoc;
+ for (Stmt *SubStmt : Body->children())
+ if (SubStmt &&
+ !CheckConstexprFunctionStmt(*this, Dcl, SubStmt, ReturnStmts,
+ Cxx1yLoc))
----------------
The repetition can be avoided here by walking the children of `Body` (regardless of what kind of statement it is), and checking them all. (We can't *quite* just pass `Body` directly to `CheckConstexprFunctionStmt` because (nested) compound statements aren't permitted until C++14.)
================
Comment at: lib/Sema/SemaDeclCXX.cpp:1973
+ << isa<CXXConstructorDecl>(Dcl);
+ return true;
+ }
----------------
Don't return here: we still need to do the other checks below.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D55097/new/
https://reviews.llvm.org/D55097
More information about the cfe-commits
mailing list