[clang-tools-extra] [clang-tidy] Add `modernize-use-if-consteval` check (PR #189743)
Daniil Dudkin via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 14 12:53:33 PDT 2026
https://github.com/unterumarmung updated https://github.com/llvm/llvm-project/pull/189743
>From 13d41d9ee6ea3ae9dd1a44c5fad77322e250fc8c Mon Sep 17 00:00:00 2001
From: Daniil Dudkin <unterumarmung at yandex.ru>
Date: Mon, 14 Sep 2026 20:55:19 +0300
Subject: [PATCH] [clang-tidy] Add modernize-use-if-consteval check
---
.../clang-tidy/modernize/CMakeLists.txt | 1 +
.../modernize/ModernizeTidyModule.cpp | 3 +
.../modernize/UseIfConstevalCheck.cpp | 147 ++++++++
.../modernize/UseIfConstevalCheck.h | 36 ++
clang-tools-extra/docs/ReleaseNotes.md | 6 +
.../docs/clang-tidy/checks/list.md | 1 +
.../checks/modernize/use-if-consteval.rst | 26 ++
.../checkers/modernize/use-if-consteval.cpp | 313 ++++++++++++++++++
8 files changed, 533 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/modernize/UseIfConstevalCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/modernize/UseIfConstevalCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-if-consteval.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-if-consteval.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 23aeb393ad0167..3972ea8436e919 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -39,6 +39,7 @@ add_clang_library(clangTidyModernizeModule STATIC
UseEmplaceCheck.cpp
UseEqualsDefaultCheck.cpp
UseEqualsDeleteCheck.cpp
+ UseIfConstevalCheck.cpp
UseIntegerSignComparisonCheck.cpp
UseNodiscardCheck.cpp
UseNoexceptCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 62676469aefe75..7368e83b709f59 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -39,6 +39,7 @@
#include "UseEmplaceCheck.h"
#include "UseEqualsDefaultCheck.h"
#include "UseEqualsDeleteCheck.h"
+#include "UseIfConstevalCheck.h"
#include "UseIntegerSignComparisonCheck.h"
#include "UseNodiscardCheck.h"
#include "UseNoexceptCheck.h"
@@ -91,6 +92,8 @@ class ModernizeModule : public ClangTidyModule {
CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value");
CheckFactories.registerCheck<UseDesignatedInitializersCheck>(
"modernize-use-designated-initializers");
+ CheckFactories.registerCheck<UseIfConstevalCheck>(
+ "modernize-use-if-consteval");
CheckFactories.registerCheck<UseIntegerSignComparisonCheck>(
"modernize-use-integer-sign-comparison");
CheckFactories.registerCheck<UseRangesCheck>("modernize-use-ranges");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseIfConstevalCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIfConstevalCheck.cpp
new file mode 100644
index 00000000000000..6b0d97d31fd667
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseIfConstevalCheck.cpp
@@ -0,0 +1,147 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseIfConstevalCheck.h"
+
+#include "../utils/BracesAroundStatement.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+
+struct BraceFix {
+ bool NeedsBraces = false;
+ utils::BraceInsertionHints Hints;
+};
+
+} // namespace
+
+static std::optional<SourceRange> getHeaderRange(const IfStmt *If,
+ const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ if (If->getLParenLoc().isMacroID() || If->getRParenLoc().isMacroID())
+ return std::nullopt;
+
+ const SourceRange HeaderRange(If->getLParenLoc(), If->getRParenLoc());
+ // Validate that the token range is safely rewriteable in file source before
+ // offering a fix-it.
+ if (Lexer::makeFileCharRange(CharSourceRange::getTokenRange(HeaderRange), SM,
+ LangOpts)
+ .isInvalid())
+ return std::nullopt;
+ return HeaderRange;
+}
+
+static std::optional<BraceFix>
+getBraceFix(const Stmt *S, const LangOptions &LangOpts, const SourceManager &SM,
+ SourceLocation StartLoc,
+ SourceLocation EndLocHint = SourceLocation()) {
+ if (S)
+ S = S->stripLabelLikeStatements();
+ if (!S || isa<CompoundStmt>(S))
+ return BraceFix();
+
+ const auto Hints =
+ utils::getBraceInsertionsHints(S, LangOpts, SM, StartLoc, EndLocHint);
+ if (!Hints || !Hints.offersFixIts())
+ return std::nullopt;
+
+ return BraceFix{true, Hints};
+}
+
+static bool needsLeadingSpaceBeforeConsteval(SourceLocation LParenLoc,
+ const SourceManager &SM) {
+ bool Invalid = false;
+ const char *LParen = SM.getCharacterData(LParenLoc, &Invalid);
+ return Invalid || !isWhitespace(LParen[-1]);
+}
+
+void UseIfConstevalCheck::registerMatchers(MatchFinder *Finder) {
+ const auto IsConstantEvaluatedCall =
+ callExpr(callee(functionDecl(hasName("is_constant_evaluated"),
+ isInStdNamespace())))
+ .bind("call");
+ const auto IsNegatedConstantEvaluatedExpr =
+ unaryOperator(hasOperatorName("!"),
+ hasUnaryOperand(ignoringParens(IsConstantEvaluatedCall)))
+ .bind("negation");
+ const auto IsConstantEvaluatedExpr = ignoringParenImpCasts(
+ anyOf(IsConstantEvaluatedCall, IsNegatedConstantEvaluatedExpr));
+
+ Finder->addMatcher(
+ ifStmt(unless(isConstexpr()),
+ anyOf(hasCondition(IsConstantEvaluatedExpr),
+ hasConditionVariableStatement(declStmt(hasSingleDecl(
+ varDecl(hasInitializer(IsConstantEvaluatedExpr)))))))
+ .bind("if"),
+ this);
+}
+
+void UseIfConstevalCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
+ const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");
+ assert(If && Call && "expected to match an if statement and its call");
+
+ const bool IsNegated = Result.Nodes.getNodeAs<UnaryOperator>("negation");
+ const llvm::StringRef ConstevalClause =
+ IsNegated ? "!consteval" : "consteval";
+ const SourceLocation DiagLoc =
+ Result.SourceManager->getExpansionLoc(Call->getExprLoc());
+
+ auto Diag = diag(DiagLoc, "use 'if %0' instead of checking "
+ "'std::is_constant_evaluated()'")
+ << ConstevalClause;
+
+ if (If->hasInitStorage() || If->hasVarStorage())
+ return;
+
+ std::optional<SourceRange> HeaderRange =
+ getHeaderRange(If, *Result.SourceManager, getLangOpts());
+ if (!HeaderRange)
+ return;
+
+ std::optional<BraceFix> ThenBraceFix =
+ getBraceFix(If->getThen(), getLangOpts(), *Result.SourceManager,
+ If->getRParenLoc(), If->getElseLoc());
+ if (!ThenBraceFix)
+ return;
+
+ std::optional<BraceFix> ElseBraceFix = BraceFix();
+ if (If->getElse()) {
+ ElseBraceFix = getBraceFix(If->getElse(), getLangOpts(),
+ *Result.SourceManager, If->getElseLoc());
+ }
+ if (!ElseBraceFix)
+ return;
+
+ const bool NeedsLeadingSpace = needsLeadingSpaceBeforeConsteval(
+ If->getLParenLoc(), *Result.SourceManager);
+ const std::string HeaderReplacement = [&] {
+ std::string Replacement = ConstevalClause.str();
+ if (NeedsLeadingSpace)
+ Replacement.insert(0, 1, ' ');
+ if (ThenBraceFix->NeedsBraces)
+ Replacement += " {";
+ return Replacement;
+ }();
+ Diag << FixItHint::CreateReplacement(*HeaderRange, HeaderReplacement);
+
+ if (ThenBraceFix->NeedsBraces)
+ Diag << ThenBraceFix->Hints.closingBraceFixIt();
+
+ if (ElseBraceFix && ElseBraceFix->NeedsBraces)
+ Diag << ElseBraceFix->Hints.openingBraceFixIt()
+ << ElseBraceFix->Hints.closingBraceFixIt();
+}
+
+} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseIfConstevalCheck.h b/clang-tools-extra/clang-tidy/modernize/UseIfConstevalCheck.h
new file mode 100644
index 00000000000000..a87c9e6c5c8df3
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseIfConstevalCheck.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEIFCONSTEVALCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEIFCONSTEVALCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::modernize {
+
+/// Use if consteval instead of std::is_constant_evaluated in if statements.
+///
+/// For the user-facing documentation see:
+/// https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-if-consteval.html
+class UseIfConstevalCheck : public ClangTidyCheck {
+public:
+ UseIfConstevalCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus23;
+ }
+ std::optional<TraversalKind> getCheckTraversalKind() const override {
+ return TK_IgnoreUnlessSpelledInSource;
+ }
+};
+
+} // namespace clang::tidy::modernize
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEIFCONSTEVALCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index f523c7b4dc4a95..b258df9e91998e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -132,6 +132,12 @@ infrastructure are described first, followed by tool-specific sections.
Finds casts from a scoped enumeration (`enum class`) to an integer type and
replaces them with a call to `std::to_underlying` (introduced in C++23).
+- New {doc}`modernize-use-if-consteval
+ <clang-tidy/checks/modernize/use-if-consteval>` check.
+
+ Replaces direct `std::is_constant_evaluated()` checks in `if` statements
+ with C++23's `if consteval` syntax.
+
- New {doc}`performance-expensive-value-or
<clang-tidy/checks/performance/expensive-value-or>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.md b/clang-tools-extra/docs/clang-tidy/checks/list.md
index ea6f13365e2068..f51fa3a4fe03e1 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.md
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.md
@@ -320,6 +320,7 @@ readability/*
| {doc}`modernize-use-emplace <modernize/use-emplace>` | Yes |
| {doc}`modernize-use-equals-default <modernize/use-equals-default>` | Yes |
| {doc}`modernize-use-equals-delete <modernize/use-equals-delete>` | Yes |
+| {doc}`modernize-use-if-consteval <modernize/use-if-consteval>` | Yes |
| {doc}`modernize-use-integer-sign-comparison <modernize/use-integer-sign-comparison>` | Yes |
| {doc}`modernize-use-nodiscard <modernize/use-nodiscard>` | Yes |
| {doc}`modernize-use-noexcept <modernize/use-noexcept>` | Yes |
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-if-consteval.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-if-consteval.rst
new file mode 100644
index 00000000000000..40cfab433b1bb6
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-if-consteval.rst
@@ -0,0 +1,26 @@
+.. title:: clang-tidy - modernize-use-if-consteval
+
+modernize-use-if-consteval
+==========================
+
+Replaces direct ``std::is_constant_evaluated()`` checks in ``if`` statements
+with C++23's ``if consteval`` syntax.
+
+.. code-block:: c++
+
+ if (std::is_constant_evaluated())
+ return slow_but_constexpr_path();
+ else
+ return fast_runtime_path();
+
+is rewritten as:
+
+.. code-block:: c++
+
+ if consteval {
+ return slow_but_constexpr_path();
+ } else {
+ return fast_runtime_path();
+ }
+
+The direct negated form is rewritten to ``if !consteval``.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-if-consteval.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-if-consteval.cpp
new file mode 100644
index 00000000000000..5a6000ebc03b75
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-if-consteval.cpp
@@ -0,0 +1,313 @@
+// RUN: %check_clang_tidy -std=c++23-or-later %s modernize-use-if-consteval %t
+
+namespace std {
+constexpr bool is_constant_evaluated() noexcept {
+ return true;
+}
+} // namespace std
+
+namespace mine {
+constexpr bool is_constant_evaluated() noexcept {
+ return __builtin_is_constant_evaluated();
+}
+} // namespace mine
+
+namespace alias = std;
+
+#define ICE_CALL() std::is_constant_evaluated()
+#define IF_ICE_HEADER if (std::is_constant_evaluated())
+#define IF_ONLY if
+#define RETURN_ONE() return 1;
+#define RETURN_THREE() return 3;
+
+bool runtime_predicate();
+
+int direct() {
+ if (std::is_constant_evaluated())
+ return 1;
+ else
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()' [modernize-use-if-consteval]
+ // CHECK-FIXES: if consteval {
+ // CHECK-FIXES-NEXT: return 1;
+ // CHECK-FIXES-NEXT: } else {
+ // CHECK-FIXES-NEXT: return 2;
+ // CHECK-FIXES-NEXT: }
+}
+
+int direct_global() {
+ if (::std::is_constant_evaluated()) {
+ return 1;
+ }
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+}
+
+int compact_spacing() {
+ if(std::is_constant_evaluated()) {
+ return 1;
+ }
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-4]]:6: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+}
+
+int using_decl() {
+ using std::is_constant_evaluated;
+ if (is_constant_evaluated()) {
+ return 1;
+ }
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+}
+
+int using_namespace() {
+ using namespace std;
+ if (is_constant_evaluated()) {
+ return 1;
+ }
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+}
+
+int namespace_alias() {
+ if (alias::is_constant_evaluated()) {
+ return 1;
+ }
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+}
+
+int negated() {
+ if (!std::is_constant_evaluated())
+ return 1;
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-3]]:8: warning: use 'if !consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if !consteval {
+ // CHECK-FIXES-NEXT: return 1;
+ // CHECK-FIXES-NEXT: }
+ // CHECK-FIXES-NEXT: return 2;
+}
+
+int negated_alternative_token() {
+ if (not std::is_constant_evaluated())
+ return 1;
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: use 'if !consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if !consteval {
+ // CHECK-FIXES-NEXT: return 1;
+ // CHECK-FIXES-NEXT: }
+ // CHECK-FIXES-NEXT: return 2;
+}
+
+int extra_parens() {
+ if ((((std::is_constant_evaluated())))) {
+ return 1;
+ }
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-4]]:10: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+}
+
+template <typename T>
+int templated() {
+ if (std::is_constant_evaluated()) {
+ return sizeof(T);
+ }
+ return 0;
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+}
+
+template int templated<int>();
+template int templated<long>();
+
+auto Lambda = [] {
+ if (std::is_constant_evaluated())
+ return 1;
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+ // CHECK-FIXES-NEXT: return 1;
+ // CHECK-FIXES-NEXT: }
+ // CHECK-FIXES-NEXT: return 2;
+};
+
+int attributed_then() {
+ if (std::is_constant_evaluated())
+ [[likely]] return 1;
+ return 0;
+ // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+ // CHECK-FIXES-NEXT: {{[[][[]}}likely{{[]][]]}} return 1;
+ // CHECK-FIXES-NEXT: }
+ // CHECK-FIXES-NEXT: return 0;
+}
+
+int labeled_then() {
+ if (std::is_constant_evaluated())
+ labeled_then:
+ return 1;
+ return 0;
+ // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+ // CHECK-FIXES-NEXT: labeled_then:
+ // CHECK-FIXES-NEXT: return 1;
+ // CHECK-FIXES-NEXT: }
+ // CHECK-FIXES-NEXT: return 0;
+}
+
+int else_if_chain(int Value) {
+ if (Value == 0)
+ return 0;
+ else if (std::is_constant_evaluated())
+ return 1;
+ else
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: else if consteval {
+ // CHECK-FIXES-NEXT: return 1;
+ // CHECK-FIXES-NEXT: } else {
+ // CHECK-FIXES-NEXT: return 2;
+ // CHECK-FIXES-NEXT: }
+}
+
+int outer_else_if() {
+ if (std::is_constant_evaluated())
+ return 1;
+ else if (runtime_predicate())
+ return 2;
+ return 0;
+ // CHECK-MESSAGES: :[[@LINE-5]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+ // CHECK-FIXES-NEXT: return 1;
+ // CHECK-FIXES-NEXT: } else { if (runtime_predicate())
+ // CHECK-FIXES-NEXT: return 2;
+ // CHECK-FIXES-NEXT: }
+ // CHECK-FIXES-NEXT: return 0;
+}
+
+int macro_header_safe() {
+ if (ICE_CALL()) {
+ return 1;
+ } else {
+ return 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if consteval {
+}
+
+int with_init() {
+ if (int X = 0; std::is_constant_evaluated()) {
+ return X + 1;
+ }
+ return 0;
+ // CHECK-MESSAGES: :[[@LINE-4]]:18: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if (int X = 0; std::is_constant_evaluated()) {
+}
+
+int with_condition_variable() {
+ if (bool B = std::is_constant_evaluated())
+ return B ? 1 : 2;
+ else
+ return 3;
+ // CHECK-MESSAGES: :[[@LINE-4]]:16: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if (bool B = std::is_constant_evaluated())
+ // CHECK-FIXES-NEXT: return B ? 1 : 2;
+ // CHECK-FIXES-NEXT: else
+ // CHECK-FIXES-NEXT: return 3;
+}
+
+int macro_header_unsafe() {
+ IF_ICE_HEADER {
+ return 1;
+ }
+ return 0;
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: IF_ICE_HEADER {
+}
+
+int macro_if_token_unsafe() {
+ IF_ONLY (std::is_constant_evaluated()) {
+ return 1;
+ }
+ return 0;
+ // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: IF_ONLY consteval {
+}
+
+int macro_body_unsafe() {
+ if (std::is_constant_evaluated())
+ RETURN_ONE()
+ return 2;
+ // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if (std::is_constant_evaluated())
+ // CHECK-FIXES-NEXT: RETURN_ONE()
+ // CHECK-FIXES-NEXT: return 2;
+}
+
+int macro_else_unsafe() {
+ if (std::is_constant_evaluated())
+ return 1;
+ else
+ RETURN_THREE()
+ return 4;
+ // CHECK-MESSAGES: :[[@LINE-5]]:7: warning: use 'if consteval' instead of checking 'std::is_constant_evaluated()'
+ // CHECK-FIXES: if (std::is_constant_evaluated())
+ // CHECK-FIXES-NEXT: return 1;
+ // CHECK-FIXES-NEXT: else
+ // CHECK-FIXES-NEXT: RETURN_THREE()
+ // CHECK-FIXES-NEXT: return 4;
+}
+
+int not_std() {
+ if (mine::is_constant_evaluated()) {
+ return 1;
+ }
+ return 0;
+}
+
+int composite_conditions() {
+ if (std::is_constant_evaluated() && runtime_predicate()) {
+ return 1;
+ }
+ if (!!std::is_constant_evaluated()) {
+ return 2;
+ }
+ return 0;
+}
+
+int if_constexpr() {
+ if constexpr (std::is_constant_evaluated()) {
+ return 1;
+ }
+ return 2;
+}
+
+int already_if_consteval() {
+ if consteval {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+int already_if_not_consteval() {
+ if !consteval {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+template <typename T>
+concept HasICE = requires {
+ std::is_constant_evaluated();
+};
+
+using ICEPtr = decltype(std::is_constant_evaluated()) *;
+ICEPtr Ptr = nullptr;
More information about the cfe-commits
mailing list