yronglin updated this revision to Diff 536802. yronglin added a comment. Address comment.
- Change `EvaluateDependentExpr`. - Add more test for do/while/for/return/ctor. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D153296/new/ https://reviews.llvm.org/D153296 Files: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
Index: clang/test/SemaCXX/constexpr-function-recovery-crash.cpp =================================================================== --- clang/test/SemaCXX/constexpr-function-recovery-crash.cpp +++ clang/test/SemaCXX/constexpr-function-recovery-crash.cpp @@ -78,6 +78,132 @@ constexpr int test12() { return "wrong"; } // expected-error {{cannot initialize return object of type 'int'}} constexpr int force12 = test12(); // expected-error {{must be initialized by a constant}} +constexpr int test13() { + switch (invalid_value) { // expected-error {{use of undeclared identifier}} + case 0: + return 7; + default: + break; + } + return 0; +} + +static_assert(test13(), "should not crash"); // expected-error {{static assertion expression is not an integral constant expression}} + +constexpr int test14() { + int sum = 0; + for (int i = 0; i < invalid_value; ++i) // expected-error {{use of undeclared identifier}} + sum = sum + i; + return sum; +} + +static_assert(test14(), "should not crash"); // expected-error {{static assertion failed due to requirement}} + +constexpr int test15() { + int sum = 0; + for (int i = 0; i < 10; i += invalid_value) // expected-error {{use of undeclared identifier}} + sum = sum + i; + return sum; +} + +static_assert(test15(), "should not crash"); // expected-error {{static assertion expression is not an integral constant expression}} + +constexpr int test16() { + int sum = 0; + for (int i = invalid_value; i < 10; ++i) // expected-error {{use of undeclared identifier}} + sum = sum + i; + return sum; +} + +static_assert(test16(), "should not crash"); // expected-error {{static assertion expression is not an integral constant expression}} + +constexpr int test17() { + int sum = 0, i = 0; + do + sum += i; + while (invalid_value); // expected-error {{use of undeclared identifier}} + return sum; +} + +static_assert(test17(), "should not crash"); // expected-error {{static assertion failed due to requirement}} + +constexpr int test18() { + int sum = 0, i = 0; + while (invalid_value) // expected-error {{use of undeclared identifier}} + sum += i; + return sum; +} + +static_assert(test18(), "should not crash"); // expected-error {{static assertion expression is not an integral constant expression}} + +constexpr int test19() { + struct Test19 { + int a[2] = {0, 1}; + constexpr const int *begin() const { + return invalid_value; // expected-error {{use of undeclared identifier}} + } + constexpr const int *end() const { + return a + 2; + } + }; + + int sum = 0; + Test19 t; + for (const auto v : t) { + sum += v; + } + return sum; +} + +static_assert(test19(), "should not crash"); // expected-error {{static assertion expression is not an integral constant expression}} + +constexpr int test20() { + struct Test20 { + int a[2] = {0, 1}; + constexpr const int *begin() const { + return a; + } + constexpr const int *end() const { + return invalid_value; // expected-error {{use of undeclared identifier}} + } + }; + + int sum = 0; + Test20 t; + for (const auto v : t) { + sum += v; + } + return sum; +} + +static_assert(test20(), "should not crash"); // expected-error {{static assertion expression is not an integral constant expression}} + +constexpr int test21() { + return invalid_value; // expected-error {{use of undeclared identifier}} +} + +static_assert(test21(), "should not crash"); // expected-error {{static assertion expression is not an integral constant expression}} + +constexpr int test22() { + struct Test22 { + int value = invalid_value; // expected-error {{use of undeclared identifier}} + }; + return Test22().value; +} + +static_assert(test22(), "should not crash"); // expected-error {{static assertion expression is not an integral constant expression}} + +constexpr int test23() { + struct Test23 { + int value; + constexpr Test23(int v) : value(v) {} + constexpr Test23(int a, int b) : Test23(a * b * invalid_value) {} // expected-error {{use of undeclared identifier}} + }; + return Test23(1, 2).value; +} + +static_assert(test23(), "should not crash"); // expected-error {{static assertion expression is not an integral constant expression}} + #define TEST_EVALUATE(Name, X) \ constexpr int testEvaluate##Name() { \ X return 0; \ Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -4913,11 +4913,20 @@ static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info) { assert(E->isValueDependent()); - if (Info.noteSideEffect()) - return true; + // Note that we have a side effect that matters for constant evaluation. + bool SideEffects = Info.noteSideEffect(); + // If the reason we're here is because of a recovery expression, we don't + // want to continue to evaluate further as we will never know what the actual + // value is. + if (isa<RecoveryExpr>(E)) + return false; + + // Otherwise, return whether we want to continue after noting the side + // effects, which should only happen if the expression has errors but isn't + // a recovery expression on its own. assert(E->containsErrors() && "valid value-dependent expression should never " "reach invalid code path."); - return false; + return SideEffects; } /// Evaluate a condition (either a variable declaration or an expression). Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -568,6 +568,9 @@ - Clang now correctly evaluates ``__has_extension (cxx_defaulted_functions)`` and ``__has_extension (cxx_default_function_template_args)`` to 1. (`#61758 <https://github.com/llvm/llvm-project/issues/61758>`_) +- Stop evaluating a constant expression if the condition expression which in + switch statement contains errors. + (`#63453 <https://github.com/llvm/llvm-project/issues/63453>_`) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits