[clang] 5143a12 - [clang][Interp] Add __builtin_is_constant_evaluated warnings

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 17 10:08:17 PDT 2024


Author: Timm Bäder
Date: 2024-03-17T18:07:51+01:00
New Revision: 5143a1241362616840af826d18c067025dae1111

URL: https://github.com/llvm/llvm-project/commit/5143a1241362616840af826d18c067025dae1111
DIFF: https://github.com/llvm/llvm-project/commit/5143a1241362616840af826d18c067025dae1111.diff

LOG: [clang][Interp] Add __builtin_is_constant_evaluated warnings

Add the same warnings the current interpreter emits.

Added: 
    

Modified: 
    clang/lib/AST/Interp/InterpBuiltin.cpp
    clang/lib/AST/Interp/InterpFrame.cpp
    clang/test/AST/Interp/builtins.cpp
    clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 45bac41ff7782a..1bf5d55314f1f2 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -119,6 +119,36 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result,
 #undef RET_CASE
 }
 
+static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC,
+                                                  const InterpFrame *Frame,
+                                                  const CallExpr *Call) {
+  // The current frame is the one for __builtin_is_constant_evaluated.
+  // The one above that, potentially the one for std::is_constant_evaluated().
+  if (S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
+      Frame->Caller && S.getEvalStatus().Diag) {
+    auto isStdCall = [](const FunctionDecl *F) -> bool {
+      return F && F->isInStdNamespace() && F->getIdentifier() &&
+             F->getIdentifier()->isStr("is_constant_evaluated");
+    };
+    const InterpFrame *Caller = Frame->Caller;
+
+    if (Caller->Caller && isStdCall(Caller->getCallee())) {
+      const Expr *E = Caller->Caller->getExpr(Caller->getRetPC());
+      S.report(E->getExprLoc(),
+               diag::warn_is_constant_evaluated_always_true_constexpr)
+          << "std::is_constant_evaluated";
+    } else {
+      const Expr *E = Frame->Caller->getExpr(Frame->getRetPC());
+      S.report(E->getExprLoc(),
+               diag::warn_is_constant_evaluated_always_true_constexpr)
+          << "__builtin_is_constant_evaluated";
+    }
+  }
+
+  S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
+  return true;
+}
+
 static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
                                    const InterpFrame *Frame,
                                    const CallExpr *Call) {
@@ -924,7 +954,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
 
   switch (F->getBuiltinID()) {
   case Builtin::BI__builtin_is_constant_evaluated:
-    S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
+    if (!interp__builtin_is_constant_evaluated(S, OpPC, Frame, Call))
+      return false;
     break;
   case Builtin::BI__builtin_assume:
   case Builtin::BI__assume:

diff  --git a/clang/lib/AST/Interp/InterpFrame.cpp b/clang/lib/AST/Interp/InterpFrame.cpp
index f69ff06b5e81b5..12e2e6ff9155b9 100644
--- a/clang/lib/AST/Interp/InterpFrame.cpp
+++ b/clang/lib/AST/Interp/InterpFrame.cpp
@@ -190,6 +190,8 @@ SourceRange InterpFrame::getCallRange() const {
 }
 
 const FunctionDecl *InterpFrame::getCallee() const {
+  if (!Func)
+    return nullptr;
   return Func->getDecl();
 }
 

diff  --git a/clang/test/AST/Interp/builtins.cpp b/clang/test/AST/Interp/builtins.cpp
index 06a22b16b2dcbb..9095d1bf8d6a3a 100644
--- a/clang/test/AST/Interp/builtins.cpp
+++ b/clang/test/AST/Interp/builtins.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -verify -fms-extensions
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -fms-extensions -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -Wno-constant-evaluated -verify -fms-extensions
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -Wno-constant-evaluated -fms-extensions -S -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated -fms-extensions
 // RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated %s -fms-extensions -S -emit-llvm -o - | FileCheck %s
 

diff  --git a/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp b/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
index 35dc69cccb3a2e..fa40c13971118d 100644
--- a/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
+++ b/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s -fexperimental-new-constant-interpreter
 
 namespace std {
 constexpr bool is_constant_evaluated() noexcept {


        


More information about the cfe-commits mailing list