From 854686f0794b9d0695d5a0a85ea1e7e71ba8edfd Mon Sep 17 00:00:00 2001 From: Karl-Johan Karlsson Date: Fri, 14 Apr 2023 07:44:44 +0200 Subject: [PATCH] [compiler-rt] Fix signed shift overflows in absvdi2.c, absvsi2.c, negvdi2.c and negvsi2.c When compiling compiler-rt with -fsanitize=undefined and running testcases you end up with the following warnings: UBSan: absvdi2.c:21:23: left shift of 1 by 63 places cannot be represented in type 'di_int' (aka 'long long') UBSan: absvsi2.c:21:23: left shift of 1 by 31 places cannot be represented in type 'si_int' (aka 'long') UBSan: negvdi2.c:20:32: left shift of 1 by 63 places cannot be represented in type 'di_int' (aka 'long long') UBSan: negvsi2.c:20:32: left shift of 1 by 31 places cannot be represented in type 'si_int' (aka 'long') This can be avoided by doing the shift in a matching unsigned variant of the type. This was found in an out of tree target. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D146932 --- compiler-rt/lib/builtins/absvdi2.c | 2 +- compiler-rt/lib/builtins/absvsi2.c | 2 +- compiler-rt/lib/builtins/negvdi2.c | 3 ++- compiler-rt/lib/builtins/negvsi2.c | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/builtins/absvdi2.c b/compiler-rt/lib/builtins/absvdi2.c index b9566cd874fe..291ab5f7f91d 100644 --- a/compiler-rt/lib/builtins/absvdi2.c +++ b/compiler-rt/lib/builtins/absvdi2.c @@ -18,7 +18,7 @@ COMPILER_RT_ABI di_int __absvdi2(di_int a) { const int N = (int)(sizeof(di_int) * CHAR_BIT); - if (a == ((di_int)1 << (N - 1))) + if (a == ((di_int)((du_int)1 << (N - 1)))) compilerrt_abort(); const di_int t = a >> (N - 1); return (a ^ t) - t; diff --git a/compiler-rt/lib/builtins/absvsi2.c b/compiler-rt/lib/builtins/absvsi2.c index 9d5de7e8a3f2..9977c33d8f7e 100644 --- a/compiler-rt/lib/builtins/absvsi2.c +++ b/compiler-rt/lib/builtins/absvsi2.c @@ -18,7 +18,7 @@ COMPILER_RT_ABI si_int __absvsi2(si_int a) { const int N = (int)(sizeof(si_int) * CHAR_BIT); - if (a == ((si_int)1 << (N - 1))) + if (a == ((si_int)((su_int)1 << (N - 1)))) compilerrt_abort(); const si_int t = a >> (N - 1); return (a ^ t) - t; diff --git a/compiler-rt/lib/builtins/negvdi2.c b/compiler-rt/lib/builtins/negvdi2.c index 5c52b3ec2aa6..8c1cf2fa58d4 100644 --- a/compiler-rt/lib/builtins/negvdi2.c +++ b/compiler-rt/lib/builtins/negvdi2.c @@ -17,7 +17,8 @@ // Effects: aborts if -a overflows COMPILER_RT_ABI di_int __negvdi2(di_int a) { - const di_int MIN = (di_int)1 << ((int)(sizeof(di_int) * CHAR_BIT) - 1); + const di_int MIN = + (di_int)((du_int)1 << ((int)(sizeof(di_int) * CHAR_BIT) - 1)); if (a == MIN) compilerrt_abort(); return -a; diff --git a/compiler-rt/lib/builtins/negvsi2.c b/compiler-rt/lib/builtins/negvsi2.c index cccdee6dc5e5..70f214f9761d 100644 --- a/compiler-rt/lib/builtins/negvsi2.c +++ b/compiler-rt/lib/builtins/negvsi2.c @@ -17,7 +17,8 @@ // Effects: aborts if -a overflows COMPILER_RT_ABI si_int __negvsi2(si_int a) { - const si_int MIN = (si_int)1 << ((int)(sizeof(si_int) * CHAR_BIT) - 1); + const si_int MIN = + (si_int)((su_int)1 << ((int)(sizeof(si_int) * CHAR_BIT) - 1)); if (a == MIN) compilerrt_abort(); return -a;