[clang] [clang][bytecode] Fix right shfits greater than bitwidth (PR #202851)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 9 22:00:40 PDT 2026
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/202851
We're not erroring in C, but we did compute the wrong result.
>From 9f56abe132dd57b0f4735f7e94a6727c2dfdae06 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 10 Jun 2026 06:57:49 +0200
Subject: [PATCH] [clang][bytecode] Fix right shfits greater than bitwidth
We're not erroring in C, but we did compute the wrong result.
---
clang/lib/AST/ByteCode/Interp.h | 20 ++++++++++----------
clang/test/AST/ByteCode/codegen.c | 3 +++
2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index c25531ecedd47..4c0a7040f46aa 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -3245,16 +3245,16 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS,
return true;
}
- // Right shift.
- if (Compare(RHS, RT::from(MaxShiftAmount, RHS.bitWidth())) ==
- ComparisonCategoryResult::Greater) {
- R = LT::AsUnsigned::from(-1);
- } else {
- // Do the shift on potentially signed LT, then convert to unsigned type.
- LT A;
- LT::shiftRight(LHS, LT::from(RHS, Bits), Bits, &A);
- R = LT::AsUnsigned::from(A);
- }
+ // Right shift.
+ if (Compare(RHS, RT::from(MaxShiftAmount, RHS.bitWidth())) ==
+ ComparisonCategoryResult::Greater) {
+ R = LT::AsUnsigned::from(0);
+ } else {
+ // Do the shift on potentially signed LT, then convert to unsigned type.
+ LT A;
+ LT::shiftRight(LHS, LT::from(RHS, Bits), Bits, &A);
+ R = LT::AsUnsigned::from(A);
+ }
S.Stk.push<LT>(LT::from(R));
return true;
diff --git a/clang/test/AST/ByteCode/codegen.c b/clang/test/AST/ByteCode/codegen.c
index 3c6f17e2b8726..7f877bb4240fe 100644
--- a/clang/test/AST/ByteCode/codegen.c
+++ b/clang/test/AST/ByteCode/codegen.c
@@ -9,6 +9,9 @@ const intptr_t Z1 = (intptr_t)(((char*)-1LL) + 1);
const intptr_t Z2 = (intptr_t)(((char*)1LL) - 1);
// CHECK: @Z2 = constant i64 0
+const int Shift = 2 >> 32;
+// CHECK: @Shift = constant i32 0
+
struct A {
char num_fields;
};
More information about the cfe-commits
mailing list