[Bug c/102291] [9/10/11/12 Regression] wrong overflow warning for compound expression conversion and bit_and expressions
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Dec 6 16:03:33 GMT 2021
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102291
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I have tried:
--- gcc/convert.c.jj 2021-01-04 10:25:38.977232194 +0100
+++ gcc/convert.c 2021-12-06 16:28:51.279775640 +0100
@@ -398,6 +398,9 @@ do_narrow (location_t loc,
Exception: the LSHIFT_EXPR case above requires that
we perform this operation unsigned lest we produce
signed-overflow undefinedness.
+ Exception: for BIT_*_EXPR if type is unsigned, just
+ convert operands to that unsigned type, there is no
+ point converting to a singled type instead.
And we may need to do it as unsigned
if we truncate to the original size. */
if (TYPE_UNSIGNED (TREE_TYPE (expr))
@@ -424,7 +427,11 @@ do_narrow (location_t loc,
> outprec))
&& (ex_form == PLUS_EXPR
|| ex_form == MINUS_EXPR
- || ex_form == MULT_EXPR)))
+ || ex_form == MULT_EXPR))
+ || ((ex_form == BIT_AND_EXPR
+ || ex_form == BIT_IOR_EXPR
+ || ex_form == BIT_XOR_EXPR)
+ && TYPE_UNSIGNED (typex)))
{
if (!TYPE_UNSIGNED (typex))
typex = unsigned_type_for (typex);
--- gcc/testsuite/gcc.dg/pr102291.c.jj 2021-12-06 16:35:36.600984273 +0100
+++ gcc/testsuite/gcc.dg/pr102291.c 2021-12-06 16:35:25.531143307 +0100
@@ -0,0 +1,33 @@
+/* PR c/102291 */
+/* { dg-do compile } */
+
+extern void __assert_fail (const char *, const char *,
+ unsigned int, const char *)
+ __attribute__ ((__nothrow__ , __leaf__, __noreturn__));
+#define assert(expr) \
+ ((void) sizeof ((expr) ? 1 : 0), __extension__ ({ \
+ if (expr) \
+ ; /* empty */ \
+ else \
+ __assert_fail (#expr, __FILE__, __LINE__, \
+ __ASSERT_FUNCTION); \
+ }))
+#define __ASSERT_FUNCTION __extension__ __PRETTY_FUNCTION__
+
+#define A(c) assert (sizeof (c) == 1 || (((unsigned long) (c)) >> 8) == 0)
+#define B(c) (A (c), ((unsigned char) (c)))
+#define C(c) (((unsigned char) (c)))
+#define D(c) ((c) | 0)
+#define E(old, new) ((((unsigned long) (old)) << 6) | (((unsigned char) D
(new)) & 0x3f))
+
+unsigned long
+foo (unsigned long x)
+{
+ return E (x, B (0x80));
+}
+
+unsigned long
+bar (unsigned long x)
+{
+ return E (x, C (0x80));
+}
but it regressed:
FAIL: gcc.dg/overflow-warn-5.c (test for warnings, line 6)
FAIL: gcc.dg/tree-ssa/pr94882-3.c scan-tree-dump-times optimized "_[0-9] \\^
_[0-9]" 4
FAIL: gcc.dg/tree-ssa/pr94882-3.c scan-tree-dump-times optimized "~_[0-9]+" 8
FAIL: gcc.dg/vect/vect-over-widen-3-big-array.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-3-big-array.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 9"
FAIL: gcc.dg/vect/vect-over-widen-3.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-3.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 9"
FAIL: gcc.dg/vect/vect-over-widen-1-big-array.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-1-big-array.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 8"
FAIL: gcc.dg/vect/vect-over-widen-4-big-array.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-4-big-array.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 8"
FAIL: gcc.dg/vect/vect-over-widen-1.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-1.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 8"
FAIL: gcc.dg/vect/vect-over-widen-4.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-4.c scan-tree-dump vect
"vect_recog_over_widening_pattern: detected:[^\\n]* << 8"
FAIL: gcc.dg/vect/vect-over-widen-1-big-array.c -flto -ffat-lto-objects
scan-tree-dump vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-1-big-array.c -flto -ffat-lto-objects
scan-tree-dump vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 8"
FAIL: gcc.dg/vect/vect-over-widen-4-big-array.c -flto -ffat-lto-objects
scan-tree-dump vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-4-big-array.c -flto -ffat-lto-objects
scan-tree-dump vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 8"
FAIL: gcc.dg/vect/vect-over-widen-1.c -flto -ffat-lto-objects scan-tree-dump
vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-1.c -flto -ffat-lto-objects scan-tree-dump
vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 8"
FAIL: gcc.dg/vect/vect-over-widen-4.c -flto -ffat-lto-objects scan-tree-dump
vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-4.c -flto -ffat-lto-objects scan-tree-dump
vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 8"
FAIL: gcc.dg/vect/vect-over-widen-3-big-array.c -flto -ffat-lto-objects
scan-tree-dump vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-3-big-array.c -flto -ffat-lto-objects
scan-tree-dump vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 9"
FAIL: gcc.dg/vect/vect-over-widen-3.c -flto -ffat-lto-objects scan-tree-dump
vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 3"
FAIL: gcc.dg/vect/vect-over-widen-3.c -flto -ffat-lto-objects scan-tree-dump
vect "vect_recog_over_widening_pattern: detected:[^\\n]* << 9"
The overflow-warn-5.c case is just weird, there is no overflow, the function
does return p & 512; where p and return type are unsigned char,
just briefly looked at vect-over-widen-1.c and we vectorize one loop before and
after, just the detected cases are different.
More information about the Gcc-bugs
mailing list