[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