aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorOverMighty <its.overmighty@gmail.com>2024-03-29 21:01:19 +0000
committerGitHub <noreply@github.com>2024-03-29 14:01:19 -0700
commitcf73f136c5e22e7e4090fc762456ace47752a898 (patch)
treeaf02bb98098c871b2535ee313d8b8e881a966589 /clang/lib/AST/ExprConstant.cpp
parent12fdf04ff8962c9e902669a1b600b27a960f0c11 (diff)
downloadllvm-cf73f136c5e22e7e4090fc762456ace47752a898.zip
llvm-cf73f136c5e22e7e4090fc762456ace47752a898.tar.gz
llvm-cf73f136c5e22e7e4090fc762456ace47752a898.tar.bz2
[clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (#86742)
Even if we don't actually use the value of the second argument, we have to evaluate it for side-effects. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r--clang/lib/AST/ExprConstant.cpp30
1 files changed, 20 insertions, 10 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 5a36621..dae8f32 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -12361,12 +12361,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;
+ std::optional<APSInt> Fallback;
+ if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) {
+ APSInt FallbackTemp;
+ if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
+ return false;
+ Fallback = FallbackTemp;
+ }
+
if (!Val) {
- if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) {
- if (!EvaluateInteger(E->getArg(1), Val, Info))
- return false;
- return Success(Val, E);
- }
+ if (Fallback)
+ return Success(*Fallback, E);
// When the argument is 0, the result of GCC builtins is undefined,
// whereas for Microsoft intrinsics, the result is the bit-width of the
@@ -12425,12 +12430,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;
+ std::optional<APSInt> Fallback;
+ if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) {
+ APSInt FallbackTemp;
+ if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
+ return false;
+ Fallback = FallbackTemp;
+ }
+
if (!Val) {
- if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) {
- if (!EvaluateInteger(E->getArg(1), Val, Info))
- return false;
- return Success(Val, E);
- }
+ if (Fallback)
+ return Success(*Fallback, E);
return Error(E);
}