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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits