diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -531,6 +531,9 @@ - Fixed a failing assertion when applying an attribute to an anonymous union. The assertion was benign outside of asserts builds and would only fire in C++. (`#48512 _`). +- Stop evaluating a constant expression if the condition expression which in + switch statement contains errors. + (`#63453 _`) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -5007,7 +5007,9 @@ APSInt LHS = CS->getLHS()->EvaluateKnownConstInt(Info.Ctx); APSInt RHS = CS->getRHS() ? CS->getRHS()->EvaluateKnownConstInt(Info.Ctx) : LHS; - if (LHS <= Value && Value <= RHS) { + if (Value.getBitWidth() == LHS.getBitWidth() && + Value.getBitWidth() == RHS.getBitWidth() && LHS <= Value && + Value <= RHS) { Found = SC; break; } diff --git a/clang/test/SemaCXX/switch.cpp b/clang/test/SemaCXX/switch.cpp --- a/clang/test/SemaCXX/switch.cpp +++ b/clang/test/SemaCXX/switch.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s void test() { bool x = true; @@ -146,3 +147,17 @@ } } // namespace EmptyEnum + +#if __cplusplus >= 201703L +constexpr int foo(unsigned char c) { + switch (unknown_value) { // expected-error {{use of undeclared identifier}} + case 0: + return 7; + default: + break; + } + return 0; +} + +static_assert(foo('d')); // expected-error {{static assertion expression is not an integral constant expression}} +#endif