diff --git a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp @@ -131,6 +131,10 @@ return; checkStmt(Result, S->getBody(), StartLoc); } else if (const auto *S = Result.Nodes.getNodeAs("if")) { + // "if consteval" always has braces. + if (S->isConsteval()) + return; + SourceLocation StartLoc = findRParenLoc(S, SM, Context); if (StartLoc.isInvalid()) return; diff --git a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp @@ -354,8 +354,9 @@ } bool VisitIfStmt(IfStmt *If) { - // Skip any if's that have a condition var or an init statement. - if (If->hasInitStorage() || If->hasVarStorage()) + // Skip any if's that have a condition var or an init statement, or are + // "if consteval" statements. + if (If->hasInitStorage() || If->hasVarStorage() || If->isConsteval()) return true; /* * if (true) ThenStmt(); -> ThenStmt(); @@ -467,7 +468,8 @@ * if (Cond) return false; return true; -> return !Cond; */ auto *If = cast(*First); - if (!If->hasInitStorage() && !If->hasVarStorage()) { + if (!If->hasInitStorage() && !If->hasVarStorage() && + !If->isConsteval()) { ExprAndBool ThenReturnBool = checkSingleStatement(If->getThen(), parseReturnLiteralBool); if (ThenReturnBool && @@ -491,7 +493,7 @@ : cast(*First)->getSubStmt(); auto *SubIf = dyn_cast(SubStmt); if (SubIf && !SubIf->getElse() && !SubIf->hasInitStorage() && - !SubIf->hasVarStorage()) { + !SubIf->hasVarStorage() && !SubIf->isConsteval()) { ExprAndBool ThenReturnBool = checkSingleStatement(SubIf->getThen(), parseReturnLiteralBool); if (ThenReturnBool && diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -149,6 +149,11 @@ copy assignment operators with nonstandard return types. The check is restricted to c++11-or-later. +- Fixed crashes in :doc:`readability-braces-around-statements + ` and + :doc:`readability-simplify-boolean-expr ` + when using a C++23 ``if consteval`` statement. + Removed checks ^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp @@ -0,0 +1,31 @@ +// RUN: clang-tidy %s -checks='-*,readability-braces-around-statements' -- -std=c++2b | count 0 + +constexpr void handle(bool) {} + +constexpr void shouldPass() { + if consteval { + handle(true); + } else { + handle(false); + } +} + +constexpr void shouldPassNegated() { + if !consteval { + handle(false); + } else { + handle(true); + } +} + +constexpr void shouldPassSimple() { + if consteval { + handle(true); + } +} + +void run() { + shouldPass(); + shouldPassNegated(); + shouldPassSimple(); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp @@ -0,0 +1,37 @@ +// RUN: clang-tidy %s -checks='-*,readability-simplify-boolean-expr' -- -std=c++2b | count 0 +template +constexpr int testIf() { + if consteval { + if constexpr (Cond) { + return 0; + } else { + return 1; + } + } else { + return 2; + } +} + +constexpr bool testCompound() { + if consteval { + return true; + } + return false; +} + +constexpr bool testCase(int I) { + switch (I) { + case 0: { + if consteval { + return true; + } + return false; + } + default: { + if consteval { + return false; + } + return true; + } + } +}