Skip to content

Commit 5143a12

Browse files
committed
[clang][Interp] Add __builtin_is_constant_evaluated warnings
Add the same warnings the current interpreter emits.
1 parent ca87671 commit 5143a12

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

clang/lib/AST/Interp/InterpBuiltin.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,36 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result,
119119
#undef RET_CASE
120120
}
121121

122+
static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC,
123+
const InterpFrame *Frame,
124+
const CallExpr *Call) {
125+
// The current frame is the one for __builtin_is_constant_evaluated.
126+
// The one above that, potentially the one for std::is_constant_evaluated().
127+
if (S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
128+
Frame->Caller && S.getEvalStatus().Diag) {
129+
auto isStdCall = [](const FunctionDecl *F) -> bool {
130+
return F && F->isInStdNamespace() && F->getIdentifier() &&
131+
F->getIdentifier()->isStr("is_constant_evaluated");
132+
};
133+
const InterpFrame *Caller = Frame->Caller;
134+
135+
if (Caller->Caller && isStdCall(Caller->getCallee())) {
136+
const Expr *E = Caller->Caller->getExpr(Caller->getRetPC());
137+
S.report(E->getExprLoc(),
138+
diag::warn_is_constant_evaluated_always_true_constexpr)
139+
<< "std::is_constant_evaluated";
140+
} else {
141+
const Expr *E = Frame->Caller->getExpr(Frame->getRetPC());
142+
S.report(E->getExprLoc(),
143+
diag::warn_is_constant_evaluated_always_true_constexpr)
144+
<< "__builtin_is_constant_evaluated";
145+
}
146+
}
147+
148+
S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
149+
return true;
150+
}
151+
122152
static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
123153
const InterpFrame *Frame,
124154
const CallExpr *Call) {
@@ -924,7 +954,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
924954

925955
switch (F->getBuiltinID()) {
926956
case Builtin::BI__builtin_is_constant_evaluated:
927-
S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
957+
if (!interp__builtin_is_constant_evaluated(S, OpPC, Frame, Call))
958+
return false;
928959
break;
929960
case Builtin::BI__builtin_assume:
930961
case Builtin::BI__assume:

clang/lib/AST/Interp/InterpFrame.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ SourceRange InterpFrame::getCallRange() const {
190190
}
191191

192192
const FunctionDecl *InterpFrame::getCallee() const {
193+
if (!Func)
194+
return nullptr;
193195
return Func->getDecl();
194196
}
195197

clang/test/AST/Interp/builtins.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -verify -fms-extensions
2-
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -fms-extensions -S -emit-llvm -o - | FileCheck %s
1+
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -Wno-constant-evaluated -verify -fms-extensions
2+
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -Wno-constant-evaluated -fms-extensions -S -emit-llvm -o - | FileCheck %s
33
// RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated -fms-extensions
44
// RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated %s -fms-extensions -S -emit-llvm -o - | FileCheck %s
55

clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s
2+
// RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s -fexperimental-new-constant-interpreter
23

34
namespace std {
45
constexpr bool is_constant_evaluated() noexcept {

0 commit comments

Comments
 (0)