diff options
author | OverMighty <its.overmighty@gmail.com> | 2024-03-29 21:01:19 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-29 14:01:19 -0700 |
commit | cf73f136c5e22e7e4090fc762456ace47752a898 (patch) | |
tree | af02bb98098c871b2535ee313d8b8e881a966589 /clang/lib/AST/ExprConstant.cpp | |
parent | 12fdf04ff8962c9e902669a1b600b27a960f0c11 (diff) | |
download | llvm-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.cpp | 30 |
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); } |