The problem is internal to t32_expandimm_imm, the imm intermediate immediate value. This value is sourced from x, which always comes from the return of a deposit32 call, which returns uint32_t already.
It's extracted via: int imm = extract32(x, 0, 8);, so the value will be between 0-255 It is then multiplied by one of 1, 0x00010001, 0x01000100, 0x01010101, or 0x80. Values between 128-255 multiplied by 0x01000100 or 0x01010101 will cause the upper bit to get set, which is a signed integer overflow. From Chapter 6.5, paragraph 5 of the C11 spec: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf this is undefined behavior. Though this is a minor undefined behavior, I'd like to see this fixed, since the error is showing up when I enable clang's sanitizers while looking for other issues. Signed-off-by: Stephen Longfield <slongfi...@google.com> Signed-off-by: Roque Arcudia Hernandez <roq...@google.com> --- target/arm/tcg/translate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c index 68ac393415..8770f0ce1c 100644 --- a/target/arm/tcg/translate.c +++ b/target/arm/tcg/translate.c @@ -3508,9 +3508,9 @@ static int t32_expandimm_rot(DisasContext *s, int x) } /* Return the unrotated immediate from T32ExpandImm. */ -static int t32_expandimm_imm(DisasContext *s, int x) +static uint32_t t32_expandimm_imm(DisasContext *s, uint32_t x) { - int imm = extract32(x, 0, 8); + uint32_t imm = extract32(x, 0, 8); switch (extract32(x, 8, 4)) { case 0: /* XY */ -- 2.48.1.601.g30ceb7b040-goog