sberg created this revision. The assert.h in glibc 2.25 defines assert as a GNU-extension "statement expression", see https://sourceware.org/git/?p=glibc.git;a=commit;h=e077349ce589466eecd47213db4fae6b80ec18c4 "assert.h: allow gcc to detect assert(a = 1) errors". That caused Clang's -std=gnu++14 to no longer treat constexpr functions containing assert as actually being constant expressions. (And I ran into that when trying to build LibreOffice master with Clang trunk against Fedora 26 glibc.)
https://reviews.llvm.org/D35562 Files: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constant-expression-cxx1y.cpp Index: clang/test/SemaCXX/constant-expression-cxx1y.cpp =================================================================== --- clang/test/SemaCXX/constant-expression-cxx1y.cpp +++ clang/test/SemaCXX/constant-expression-cxx1y.cpp @@ -781,9 +781,8 @@ return ({ int n; n; }); // expected-note {{object of type 'int' is not initialized}} } - // FIXME: We should handle the void statement expression case. - constexpr int h() { // expected-error {{never produces a constant}} - ({ if (true) {} }); // expected-note {{not supported}} + constexpr int h() { + ({ if (true) {} }); return 0; } } Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -4838,16 +4838,10 @@ for (CompoundStmt::const_body_iterator BI = CS->body_begin(), BE = CS->body_end(); - /**/; ++BI) { - if (BI + 1 == BE) { - const Expr *FinalExpr = dyn_cast<Expr>(*BI); - if (!FinalExpr) { - Info.FFDiag((*BI)->getLocStart(), - diag::note_constexpr_stmt_expr_unsupported); - return false; - } - return this->Visit(FinalExpr); - } + BI != BE; ++BI) { + if (BI + 1 == BE) + if (const Expr *FinalExpr = dyn_cast<Expr>(*BI)) + return this->Visit(FinalExpr); APValue ReturnValue; StmtResult Result = { ReturnValue, nullptr }; @@ -4863,7 +4857,7 @@ } } - llvm_unreachable("Return from function from the loop above."); + return true; } /// Visit a value which is evaluated, but whose value is ignored.
Index: clang/test/SemaCXX/constant-expression-cxx1y.cpp =================================================================== --- clang/test/SemaCXX/constant-expression-cxx1y.cpp +++ clang/test/SemaCXX/constant-expression-cxx1y.cpp @@ -781,9 +781,8 @@ return ({ int n; n; }); // expected-note {{object of type 'int' is not initialized}} } - // FIXME: We should handle the void statement expression case. - constexpr int h() { // expected-error {{never produces a constant}} - ({ if (true) {} }); // expected-note {{not supported}} + constexpr int h() { + ({ if (true) {} }); return 0; } } Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -4838,16 +4838,10 @@ for (CompoundStmt::const_body_iterator BI = CS->body_begin(), BE = CS->body_end(); - /**/; ++BI) { - if (BI + 1 == BE) { - const Expr *FinalExpr = dyn_cast<Expr>(*BI); - if (!FinalExpr) { - Info.FFDiag((*BI)->getLocStart(), - diag::note_constexpr_stmt_expr_unsupported); - return false; - } - return this->Visit(FinalExpr); - } + BI != BE; ++BI) { + if (BI + 1 == BE) + if (const Expr *FinalExpr = dyn_cast<Expr>(*BI)) + return this->Visit(FinalExpr); APValue ReturnValue; StmtResult Result = { ReturnValue, nullptr }; @@ -4863,7 +4857,7 @@ } } - llvm_unreachable("Return from function from the loop above."); + return true; } /// Visit a value which is evaluated, but whose value is ignored.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits