On 06/15/2016 05:47 AM, Jakub Jelinek wrote:
On Tue, Jun 14, 2016 at 11:13:28AM -0600, Martin Sebor wrote:
Here is an untested patch for that.  Except that the middle-end considers
conversions between BOOLEAN_TYPE and single bit unsigned type as useless,
so in theory this can't work well, and in practice only if we are lucky
enough (plus it generates terrible code right now), so we'd probably need
to come up with a different way of expressing whether the internal fn
should have a bool/_Bool-ish behavior or not (optional 3rd argument or
something ugly like that).  Plus add lots of testcases to cover the weirdo
cases.  Is it really worth it, even when we don't want to support overflow
into enumeration type and thus will not cover all integral types anyway?

If it's cumbersome to get to work I agree that it's not worth
the effort.  Thanks for taking the time to prototype it.

Ok, so here is an updated patch.  In addition to diagnostic wording changes
this (as also the earlier posted patch) fixes the handling of sub-mode
precision, it adds hopefully sufficient testsuite coverage for
__builtin_{add,sub,mul}_overflow_p.

The only thing I'm unsure about is what to do with bitfield types.
For __builtin_{add,sub,mul}_overflow it is not an issue, as one can't take
address of a bitfield.  For __builtin_{add,sub,mul}_overflow_p right now,
the C FE doesn't promote the last argument in any way, therefore for C
the builtin-arith-overflow-p-19.c testcase tests the behavior of bitfield
overflows.  The C++ FE even for type-generic builtins promotes the argument
to the underlying type (as part of decay_conversion), therefore for C++
overflow to bit-fields doesn't work.  Is that acceptable that because the
bitfields in the two languages behave generally slightly differently it is
ok that it differs even here, or should the C FE promote bitfields to the
underlying type for the last argument of __builtin_{add,sub,mul}_overflow_p,
or should the C++ FE special case __builtin_{add,sub,mul}_overflow_p and
not decay_conversion on the last argument to these, something else?

2016-06-15  Jakub Jelinek  <ja...@redhat.com>

        * internal-fn.c (expand_arith_set_overflow): New function.
        (expand_addsub_overflow, expand_neg_overflow, expand_mul_overflow):
        Use it.
        (expand_arith_overflow_result_store): Likewise.  Handle precision
        smaller than mode precision.
        * tree-vrp.c (extract_range_basic): For imag part, handle
        properly signed 1-bit precision result.
        * doc/extend.texi (__builtin_add_overflow): Document that last
        argument can't be pointer to enumerated or boolean type.
        (__builtin_add_overflow_p): Document that last argument can't
        have enumerated or boolean type.

        * c-common.c (check_builtin_function_arguments): Require last
        argument of BUILT_IN_*_OVERFLOW_P to have INTEGER_TYPE type.
        Adjust wording of diagnostics for BUILT_IN_*_OVERLFLOW
        if the last argument is pointer to enumerated or boolean type.

        * c-c++-common/builtin-arith-overflow-1.c (generic_wrong_type, f3,
        f4): Adjust expected diagnostics.
        * c-c++-common/torture/builtin-arith-overflow.h (TP): New macro.
        (T): If OVFP is defined, redefine to TP.
        * c-c++-common/torture/builtin-arith-overflow-12.c: Adjust comment.
        * c-c++-common/torture/builtin-arith-overflow-p-1.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-2.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-3.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-4.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-5.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-6.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-7.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-8.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-9.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-10.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-11.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-12.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-13.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-14.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-15.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-16.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-17.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-18.c: New test.
        * c-c++-common/torture/builtin-arith-overflow-p-19.c: New test.
        * g++.dg/ext/builtin-arith-overflow-1.C: Pass 0 instead of C
        as last argument to __builtin_add_overflow_p.
I think this is OK -- however, please don't install until you've received an ACK from Jason on the follow-up patch which prevents promotion of bitfields in the last arg of __builtin_*_overflow_p.

Jeff

--- gcc/internal-fn.c.jj        2016-06-14 21:38:37.759308842 +0200
+++ gcc/internal-fn.c   2016-06-15 12:38:52.708677650 +0200
@@ -405,9 +405,23 @@ get_min_precision (tree arg, signop sign
   return prec + (orig_sign != sign);
 }

+/* Helper for expand_*_overflow.  Set the __imag__ part to true
+   (1 except for signed:1 type, in which case store -1).  */
+
+static void
+expand_arith_set_overflow (tree lhs, rtx target)
+{
+  if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1
+      && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs))))
+    write_complex_part (target, constm1_rtx, true);
+  else
+    write_complex_part (target, const1_rtx, true);
+}
+
 /* Helper for expand_*_overflow.  Store RES into the __real__ part
    of TARGET.  If RES has larger MODE than __real__ part of TARGET,
-   set the __imag__ part to 1 if RES doesn't fit into it.  */
+   set the __imag__ part to 1 if RES doesn't fit into it.  Similarly
+   if LHS has smaller precision than its mode.  */

 static void
 expand_arith_overflow_result_store (tree lhs, rtx target,
@@ -424,7 +438,35 @@ expand_arith_overflow_result_store (tree
       do_compare_rtx_and_jump (res, convert_modes (mode, tgtmode, lres, uns),
                               EQ, true, mode, NULL_RTX, NULL, done_label,
                               PROB_VERY_LIKELY);
-      write_complex_part (target, const1_rtx, true);
+      expand_arith_set_overflow (lhs, target);
+      emit_label (done_label);
+    }
+  int prec = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs)));
+  int tgtprec = GET_MODE_PRECISION (tgtmode);
+  if (prec < tgtprec)
+    {
+      rtx_code_label *done_label = gen_label_rtx ();
+      int uns = TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)));
+      res = lres;
+      if (uns)
+       {
+         rtx mask
+           = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec),
+                                   tgtmode);
+         lres = expand_simple_binop (tgtmode, AND, res, mask, NULL_RTX,
+                                     true, OPTAB_DIRECT);
+       }
+      else
+       {
+         lres = expand_shift (LSHIFT_EXPR, tgtmode, res, tgtprec - prec,
+                              NULL_RTX, 1);
+         lres = expand_shift (RSHIFT_EXPR, tgtmode, lres, tgtprec - prec,
+                              NULL_RTX, 0);
+       }
+      do_compare_rtx_and_jump (res, lres,
+                              EQ, true, tgtmode, NULL_RTX, NULL, done_label,
+                              PROB_VERY_LIKELY);
+      expand_arith_set_overflow (lhs, target);
       emit_label (done_label);
     }
   write_complex_part (target, lres, false);
@@ -861,7 +903,7 @@ expand_addsub_overflow (location_t loc,
       do_pending_stack_adjust ();
     }
   else if (lhs)
-    write_complex_part (target, const1_rtx, true);
+    expand_arith_set_overflow (lhs, target);

   /* We're done.  */
   emit_label (done_label);
@@ -956,7 +998,7 @@ expand_neg_overflow (location_t loc, tre
       do_pending_stack_adjust ();
     }
   else if (lhs)
-    write_complex_part (target, const1_rtx, true);
+    expand_arith_set_overflow (lhs, target);

   /* We're done.  */
   emit_label (done_label);
@@ -1082,7 +1124,7 @@ expand_mul_overflow (location_t loc, tre
                                   NULL, do_main_label, PROB_VERY_LIKELY);
          do_compare_rtx_and_jump (op1, const0_rtx, EQ, true, mode, NULL_RTX,
                                   NULL, do_main_label, PROB_VERY_LIKELY);
-         write_complex_part (target, const1_rtx, true);
+         expand_arith_set_overflow (lhs, target);
          emit_label (do_main_label);
          goto do_main;
        default:
@@ -1213,7 +1255,7 @@ expand_mul_overflow (location_t loc, tre
             is, thus we can keep do_main code oring in overflow as is.  */
          do_compare_rtx_and_jump (tem, const0_rtx, EQ, true, mode, NULL_RTX,
                                   NULL, do_main_label, PROB_VERY_LIKELY);
-         write_complex_part (target, const1_rtx, true);
+         expand_arith_set_overflow (lhs, target);
          emit_label (do_main_label);
          goto do_main;
        default:
@@ -1617,7 +1659,7 @@ expand_mul_overflow (location_t loc, tre
       do_pending_stack_adjust ();
     }
   else if (lhs)
-    write_complex_part (target, const1_rtx, true);
+    expand_arith_set_overflow (lhs, target);

   /* We're done.  */
   emit_label (done_label);
@@ -1628,7 +1670,7 @@ expand_mul_overflow (location_t loc, tre
       rtx_code_label *all_done_label = gen_label_rtx ();
       do_compare_rtx_and_jump (res, const0_rtx, GE, false, mode, NULL_RTX,
                               NULL, all_done_label, PROB_VERY_LIKELY);
-      write_complex_part (target, const1_rtx, true);
+      expand_arith_set_overflow (lhs, target);
       emit_label (all_done_label);
     }

@@ -1639,7 +1681,7 @@ expand_mul_overflow (location_t loc, tre
       rtx_code_label *set_noovf = gen_label_rtx ();
       do_compare_rtx_and_jump (op1, const0_rtx, GE, false, mode, NULL_RTX,
                               NULL, all_done_label, PROB_VERY_LIKELY);
-      write_complex_part (target, const1_rtx, true);
+      expand_arith_set_overflow (lhs, target);
       do_compare_rtx_and_jump (op0, const0_rtx, EQ, true, mode, NULL_RTX,
                               NULL, set_noovf, PROB_VERY_LIKELY);
       do_compare_rtx_and_jump (op0, constm1_rtx, NE, true, mode, NULL_RTX,
--- gcc/tree-vrp.c.jj   2016-06-14 12:17:19.000000000 +0200
+++ gcc/tree-vrp.c      2016-06-15 12:44:01.181649211 +0200
@@ -4016,6 +4016,9 @@ extract_range_basic (value_range *vr, gi
                        set_value_range_to_value (vr,
                                                  build_int_cst (type, ovf),
                                                  NULL);
+                     else if (TYPE_PRECISION (type) == 1
+                              && !TYPE_UNSIGNED (type))
+                       set_value_range_to_varying (vr);
                      else
                        set_value_range (vr, VR_RANGE, build_int_cst (type, 0),
                                         build_int_cst (type, 1), NULL);
--- gcc/doc/extend.texi.jj      2016-06-14 21:38:37.677309903 +0200
+++ gcc/doc/extend.texi 2016-06-15 09:23:17.909744444 +0200
@@ -9833,8 +9833,8 @@ performed in infinite signed precision,
 behavior for all argument values.

 The first built-in function allows arbitrary integral types for operands and
-the result type must be pointer to some integer type, the rest of the built-in
-functions have explicit integer types.
+the result type must be pointer to some integral type other than enumerated or
+Boolean type, the rest of the built-in functions have explicit integer types.

 The compiler will attempt to use hardware instructions to implement
 these built-in functions where possible, like conditional jump on overflow
@@ -9879,7 +9879,8 @@ would overflow.
 These built-in functions are similar to @code{__builtin_add_overflow},
 @code{__builtin_sub_overflow}, or @code{__builtin_mul_overflow}, except that
 they don't store the result of the arithmetic operation anywhere and the
-last argument is not a pointer, but some integral expression.
+last argument is not a pointer, but some expression with integral type other
+than enumerated or Boolean type.

 The built-in functions promote the first two operands into infinite precision 
signed type
 and perform addition on those promoted operands. The result is then
--- gcc/c-family/c-common.c.jj  2016-06-14 21:38:37.849307678 +0200
+++ gcc/c-family/c-common.c     2016-06-15 09:23:17.904744508 +0200
@@ -9983,10 +9983,22 @@ check_builtin_function_arguments (locati
                return false;
              }
          if (TREE_CODE (TREE_TYPE (args[2])) != POINTER_TYPE
-             || TREE_CODE (TREE_TYPE (TREE_TYPE (args[2]))) != INTEGER_TYPE)
+             || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (args[2]))))
            {
              error_at (ARG_LOCATION (2), "argument 3 in call to function %qE "
-                       "does not have pointer to integer type", fndecl);
+                       "does not have pointer to integral type", fndecl);
+             return false;
+           }
+         else if (TREE_CODE (TREE_TYPE (TREE_TYPE (args[2]))) == ENUMERAL_TYPE)
+           {
+             error_at (ARG_LOCATION (2), "argument 3 in call to function %qE "
+                       "has pointer to enumerated type", fndecl);
+             return false;
+           }
+         else if (TREE_CODE (TREE_TYPE (TREE_TYPE (args[2]))) == BOOLEAN_TYPE)
+           {
+             error_at (ARG_LOCATION (2), "argument 3 in call to function %qE "
+                       "has pointer to boolean type", fndecl);
              return false;
            }
          return true;
@@ -10006,6 +10018,18 @@ check_builtin_function_arguments (locati
                          "%qE does not have integral type", i + 1, fndecl);
                return false;
              }
+         if (TREE_CODE (TREE_TYPE (args[2])) == ENUMERAL_TYPE)
+           {
+             error_at (ARG_LOCATION (2), "argument 3 in call to function "
+                       "%qE has enumerated type", fndecl);
+             return false;
+           }
+         else if (TREE_CODE (TREE_TYPE (args[2])) == BOOLEAN_TYPE)
+           {
+             error_at (ARG_LOCATION (2), "argument 3 in call to function "
+                       "%qE has boolean type", fndecl);
+             return false;
+           }
          return true;
        }
       return false;
--- gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c.jj    2016-06-14 
21:38:37.512312038 +0200
+++ gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c       2016-06-15 
09:23:17.900744560 +0200
@@ -118,14 +118,14 @@ generic_wrong_type (int a, int b)
 {
   void *p = 0;
   double d = 0;
-  int x = __builtin_add_overflow (a, b, p);   /* { dg-error "does not have pointer 
to integer type" } */
-  x += __builtin_sub_overflow (a, b, &p);     /* { dg-error "does not have pointer 
to integer type" } */
-  x += __builtin_mul_overflow (a, b, &d);     /* { dg-error "does not have pointer 
to integer type" } */
+  int x = __builtin_add_overflow (a, b, p);   /* { dg-error "does not have pointer 
to integral type" } */
+  x += __builtin_sub_overflow (a, b, &p);     /* { dg-error "does not have pointer 
to integral type" } */
+  x += __builtin_mul_overflow (a, b, &d);     /* { dg-error "does not have pointer 
to integral type" } */

   /* Also verify literal arguments.  */
-  x += __builtin_add_overflow (1, 1, p);   /* { dg-error "does not have pointer to 
integer type" } */
-  x += __builtin_sub_overflow (1, 1, &p);     /* { dg-error "does not have pointer 
to integer type" } */
-  x += __builtin_mul_overflow (1, 1, &d);     /* { dg-error "does not have pointer 
to integer type" } */
+  x += __builtin_add_overflow (1, 1, p);   /* { dg-error "does not have pointer to 
integral type" } */
+  x += __builtin_sub_overflow (1, 1, &p);     /* { dg-error "does not have pointer 
to integral type" } */
+  x += __builtin_mul_overflow (1, 1, &d);     /* { dg-error "does not have pointer 
to integral type" } */
   return x;
 }

@@ -236,8 +236,8 @@ f3 (float fa, int a, _Complex long int c
   x += __builtin_sub_overflow_p (ca, b, eb);   /* { dg-error "argument 1 in call to 
function\[^\n\r]*does not have integral type" } */
   x += __builtin_mul_overflow_p (a, fb, bb);   /* { dg-error "argument 2 in call to 
function\[^\n\r]*does not have integral type" } */
   x += __builtin_add_overflow_p (a, pb, a);    /* { dg-error "argument 2 in call to 
function\[^\n\r]*does not have integral type" } */
-  x += __builtin_sub_overflow_p (a, eb, eb);
-  x += __builtin_mul_overflow_p (a, bb, bb);
+  x += __builtin_sub_overflow_p (a, eb, eb);   /* { dg-error "argument 3 in call to 
function\[^\n\r]*has enumerated type" } */
+  x += __builtin_mul_overflow_p (a, bb, bb);   /* { dg-error "argument 3 in call to 
function\[^\n\r]*has boolean type" } */
   x += __builtin_add_overflow_p (a, b, fa);    /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have integral type" } */
   x += __builtin_sub_overflow_p (a, b, ca);    /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have integral type" } */
   x += __builtin_mul_overflow_p (a, b, c);     /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have integral type" } */
@@ -247,11 +247,11 @@ f3 (float fa, int a, _Complex long int c
 int
 f4 (float *fp, double *dp, _Complex int *cp, enum E *ep, bool *bp, long long 
int *llp)
 {
-  int x = __builtin_add_overflow (1, 2, fp);   /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have pointer to integer type" } */
-  x += __builtin_sub_overflow (1, 2, dp);      /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have pointer to integer type" } */
-  x += __builtin_mul_overflow (1, 2, cp);      /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have pointer to integer type" } */
-  x += __builtin_add_overflow (1, 2, ep);      /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have pointer to integer type" } */
-  x += __builtin_sub_overflow (1, 2, bp);      /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have pointer to integer type" } */
+  int x = __builtin_add_overflow (1, 2, fp);   /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have pointer to integral type" } */
+  x += __builtin_sub_overflow (1, 2, dp);      /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have pointer to integral type" } */
+  x += __builtin_mul_overflow (1, 2, cp);      /* { dg-error "argument 3 in call to 
function\[^\n\r]*does not have pointer to integral type" } */
+  x += __builtin_add_overflow (1, 2, ep);      /* { dg-error "argument 3 in call to 
function\[^\n\r]*has pointer to enumerated type" } */
+  x += __builtin_sub_overflow (1, 2, bp);      /* { dg-error "argument 3 in call to 
function\[^\n\r]*has pointer to boolean type" } */
   x += __builtin_mul_overflow (1, 2, llp);
   return x;
 }
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow.h.jj      
2014-11-12 13:28:47.000000000 +0100
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow.h 2016-06-15 
09:51:09.379126122 +0200
@@ -90,5 +90,70 @@ t##n##b (void)                                       \
   if (r2 != (tr) (vr) || v != 7 * o)           \
     __builtin_abort ();                                \
 }
+#define TP(n, t1, t2, er, v1, v2, b, o) \
+__attribute__((noinline, noclone)) void                \
+t##n##_1##b (t1 x, t2 y)                       \
+{                                              \
+  if (__builtin_##b##_overflow_p (x, y, er))   \
+    bar ();                                    \
+}                                              \
+                                               \
+__attribute__((noinline, noclone)) void                \
+t##n##_2##b (t2 y)                             \
+{                                              \
+  t1 x = (v1);                                 \
+  if (__builtin_##b##_overflow_p (x, y, er))   \
+    bar ();                                    \
+}                                              \
+                                               \
+__attribute__((noinline, noclone)) void                \
+t##n##_3##b (t2 y)                             \
+{                                              \
+  if (__builtin_##b##_overflow_p ((t1) (v1), y,        \
+                                 er))          \
+    bar ();                                    \
+}                                              \
+                                               \
+__attribute__((noinline, noclone)) void                \
+t##n##_4##b (t1 x)                             \
+{                                              \
+  t2 y = (v2);                                 \
+  if (__builtin_##b##_overflow_p (x, y, er))   \
+    bar ();                                    \
+}                                              \
+                                               \
+__attribute__((noinline, noclone)) void                \
+t##n##_5##b (t1 x)                             \
+{                                              \
+  if (__builtin_##b##_overflow_p (x, (t2) (v2),        \
+                                 er))          \
+    bar ();                                    \
+}                                              \
+                                               \
+__attribute__((noinline, noclone)) void                \
+t##n##b (void)                                 \
+{                                              \
+  t1 x = (v1);                                 \
+  t2 y = (v2);                                 \
+  v = 0;                                       \
+  t##n##_1##b (x, y);                          \
+  t##n##_2##b (y);                             \
+  t##n##_3##b (y);                             \
+  t##n##_4##b (x);                             \
+  t##n##_5##b (x);                             \
+  if (__builtin_##b##_overflow_p (x, y, er))   \
+    bar ();                                    \
+  if (__builtin_##b##_overflow_p ((t1) (v1),   \
+                                 (t2) (v2),    \
+                                 er))          \
+    bar ();                                    \
+  if (v != 7 * o)                              \
+    __builtin_abort ();                                \
+}
+#ifdef OVFP
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) \
+TP(n, t1, t2, (tr) 0, v1, v2, b, o)
+#endif
 #define ST(n, t, v1, v2, vr, b, o) \
 T (n, t, t, t, v1, v2, vr, b, o)
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-12.c.jj   
2014-11-12 13:28:47.000000000 +0100
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-12.c      
2016-06-15 10:03:04.958872148 +0200
@@ -1,4 +1,4 @@
-/* Test __builtin_{add,sub,mul_overflow.  */
+/* Test __builtin_{add,sub,mul}_overflow.  */
 /* { dg-do run } */
 /* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */

--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-1.c.jj  
2016-06-15 09:51:29.411867056 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-1.c     
2016-06-15 09:52:19.287222061 +0200
@@ -0,0 +1,19 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-1.h"
+
+#define U(s, op) op
+TESTS (int, INT_MIN, INT_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (int, INT_MIN, INT_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-2.c.jj  
2016-06-15 09:53:08.039591589 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-2.c     
2016-06-15 09:53:35.291239167 +0200
@@ -0,0 +1,19 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-1.h"
+
+#define U(s, op) op
+TESTS (long, LONG_MIN, LONG_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (long, LONG_MIN, LONG_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-3.c.jj  
2016-06-15 09:54:00.489913294 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-3.c     
2016-06-15 09:54:25.262592930 +0200
@@ -0,0 +1,19 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-1.h"
+
+#define U(s, op) op
+TESTS (long long, LLONG_MIN, LLONG_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (long long, LLONG_MIN, LLONG_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-4.c.jj  
2016-06-15 09:56:09.843240479 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-4.c     
2016-06-15 09:56:53.504675844 +0200
@@ -0,0 +1,19 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-1.h"
+
+#define U(s, op) op
+TESTS (char, SCHAR_MIN, SCHAR_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (char, SCHAR_MIN, SCHAR_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-5.c.jj  
2016-06-15 09:56:09.844240466 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-5.c     
2016-06-15 09:57:08.574480959 +0200
@@ -0,0 +1,19 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-1.h"
+
+#define U(s, op) op
+TESTS (short, SHRT_MIN, SHRT_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (short, SHRT_MIN, SHRT_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-6.c.jj  
2016-06-15 09:56:09.846240441 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-6.c     
2016-06-15 09:57:22.241304218 +0200
@@ -0,0 +1,22 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run { target int128 } } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-1.h"
+
+#define INT128_MAX ((signed __int128) (((unsigned __int128) 1 << 
(__SIZEOF_INT128__ * __CHAR_BIT__ - 1)) - 1))
+#define INT128_MIN (-INT128_MAX - 1)
+
+#define U(s, op) op
+TESTS (__int128, INT128_MIN, INT128_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (__int128, INT128_MIN, INT128_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-7.c.jj  
2016-06-15 09:56:09.847240428 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-7.c     
2016-06-15 10:01:32.847063350 +0200
@@ -0,0 +1,79 @@
+/* Test __builtin_{add,sub}_overflow_p on {,un}signed char.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define UCHAR_MAX ((unsigned char) ~0)
+#ifndef SHIFT
+typedef signed char S;
+typedef unsigned char U;
+typedef int W;
+#define SHIFT 0
+#define S_MAX __SCHAR_MAX__
+#define S_MIN (-__SCHAR_MAX__ - 1)
+#define COND (__SIZEOF_INT__ > 1)
+#endif
+
+#define F(n, t1, t2, tr, b) \
+__attribute__((noinline, noclone)) void                \
+n (t1 x, t2 y, int *ovf)                       \
+{                                              \
+  *ovf = __builtin_##b##_overflow_p (x, y,     \
+                                    (tr) 0);   \
+}
+
+F (spses, S, S, S, add)
+F (upueu, U, U, U, add)
+F (spseu, S, S, U, add)
+F (upues, U, U, S, add)
+F (spues, S, U, S, add)
+F (upses, U, S, S, add)
+F (spueu, S, U, U, add)
+F (upseu, U, S, U, add)
+F (ssses, S, S, S, sub)
+F (usueu, U, U, U, sub)
+F (ssseu, S, S, U, sub)
+F (usues, U, U, S, sub)
+F (ssues, S, U, S, sub)
+F (usses, U, S, S, sub)
+F (ssueu, S, U, U, sub)
+F (usseu, U, S, U, sub)
+
+int
+main ()
+{
+#if COND
+  int i, j;
+  for (i = 0; i < UCHAR_MAX; i++)
+    for (j = 0; j < UCHAR_MAX; j++)
+      {
+       S s1 = ((W) i << SHIFT) + S_MIN;
+       U u1 = ((W) i << SHIFT);
+       S s2 = ((W) j << SHIFT) + S_MIN;
+       U u2 = ((W) j << SHIFT);
+       W w;
+       int ovf;
+#define T(n, t1, t2, tr, op) \
+       w = ((W) t1##1) op ((W) t2##2);         \
+       n (t1##1, t2##2, &ovf);                     \
+       if (ovf != (w != (tr) w))               \
+         __builtin_abort ();
+       T (spses, s, s, S, +)
+       T (upueu, u, u, U, +)
+       T (spseu, s, s, U, +)
+       T (upues, u, u, S, +)
+       T (spues, s, u, S, +)
+       T (upses, u, s, S, +)
+       T (spueu, s, u, U, +)
+       T (upseu, u, s, U, +)
+       T (ssses, s, s, S, -)
+       T (usueu, u, u, U, -)
+       T (ssseu, s, s, U, -)
+       T (usues, u, u, S, -)
+       T (ssues, s, u, S, -)
+       T (usses, u, s, S, -)
+       T (ssueu, s, u, U, -)
+       T (usseu, u, s, U, -)
+      }
+#endif
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-8.c.jj  
2016-06-15 09:56:09.849240402 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-8.c     
2016-06-15 10:01:11.223342991 +0200
@@ -0,0 +1,23 @@
+/* Test __builtin_{add,sub}_overflow_p on {,un}signed short.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+typedef signed short int S;
+typedef unsigned short int U;
+#define COND 1
+#define SHIFT ((__SIZEOF_SHORT__ - 1) * __CHAR_BIT__)
+#define S_MAX __SHRT_MAX__
+#define S_MIN (-__SHRT_MAX__ - 1)
+#if __SIZEOF_INT__ > __SIZEOF_SHORT__
+typedef int W;
+#elif __SIZEOF_LONG__ > __SIZEOF_SHORT__
+typedef long int W;
+#elif __SIZEOF_LONG_LONG__ > __SIZEOF_SHORT__
+typedef long long int W;
+#elif __SIZEOF_INT128__ > __SIZEOF_SHORT__
+typedef __int128 W;
+#else
+#undef COND
+#define COND 0
+#endif
+#include "builtin-arith-overflow-p-7.c"
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-9.c.jj  
2016-06-15 09:56:09.850240389 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-9.c     
2016-06-15 10:01:59.683716295 +0200
@@ -0,0 +1,21 @@
+/* Test __builtin_{add,sub}_overflow_p on {,un}signed int.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+typedef signed int S;
+typedef unsigned int U;
+#define COND 1
+#define SHIFT ((__SIZEOF_INT__ - 1) * __CHAR_BIT__)
+#define S_MAX __INT_MAX__
+#define S_MIN (-__INT_MAX__ - 1)
+#if __SIZEOF_LONG__ > __SIZEOF_INT__
+typedef long int W;
+#elif __SIZEOF_LONG_LONG__ > __SIZEOF_INT__
+typedef long long int W;
+#elif __SIZEOF_INT128__ > __SIZEOF_INT__
+typedef __int128 W;
+#else
+#undef COND
+#define COND 0
+#endif
+#include "builtin-arith-overflow-p-7.c"
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-10.c.jj 
2016-06-15 09:56:09.828240673 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-10.c    
2016-06-15 10:02:23.783404634 +0200
@@ -0,0 +1,19 @@
+/* Test __builtin_{add,sub}_overflow_p on {,un}signed long int.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+typedef signed long int S;
+typedef unsigned long int U;
+#define COND 1
+#define SHIFT ((__SIZEOF_LONG__ - 1) * __CHAR_BIT__)
+#define S_MAX __LONG_MAX__
+#define S_MIN (-__LONG_MAX__ - 1)
+#if __SIZEOF_LONG_LONG__ > __SIZEOF_LONG__
+typedef long long int W;
+#elif __SIZEOF_INT128__ > __SIZEOF_LONG__
+typedef __int128 W;
+#else
+#undef COND
+#define COND 0
+#endif
+#include "builtin-arith-overflow-p-7.c"
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-11.c.jj 
2016-06-15 09:56:09.829240660 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-11.c    
2016-06-15 10:02:37.969221181 +0200
@@ -0,0 +1,17 @@
+/* Test __builtin_{add,sub}_overflow_p on {,un}signed long long int.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+typedef signed long long int S;
+typedef unsigned long long int U;
+#define COND 1
+#define SHIFT ((__SIZEOF_LONG_LONG__ - 1) * __CHAR_BIT__)
+#define S_MAX __LONG_LONG_MAX__
+#define S_MIN (-__LONG_LONG_MAX__ - 1)
+#if __SIZEOF_INT128__ > __SIZEOF_LONG_LONG__
+typedef __int128 W;
+#else
+#undef COND
+#define COND 0
+#endif
+#include "builtin-arith-overflow-p-7.c"
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-12.c.jj 
2016-06-15 09:56:09.831240634 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-12.c    
2016-06-15 10:03:46.227338458 +0200
@@ -0,0 +1,18 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-12.h"
+
+TESTS (int, INT_MIN, INT_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (int, INT_MIN, INT_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-13.c.jj 
2016-06-15 09:56:09.833240609 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-13.c    
2016-06-15 10:03:58.357181593 +0200
@@ -0,0 +1,18 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-12.h"
+
+TESTS (long, LONG_MIN, LONG_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (long, LONG_MIN, LONG_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-14.c.jj 
2016-06-15 09:56:09.834240596 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-14.c    
2016-06-15 10:04:08.983044178 +0200
@@ -0,0 +1,18 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-12.h"
+
+TESTS (long long, LLONG_MIN, LLONG_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (long long, LLONG_MIN, LLONG_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-15.c.jj 
2016-06-15 09:56:09.836240570 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-15.c    
2016-06-15 10:04:21.896876838 +0200
@@ -0,0 +1,18 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-12.h"
+
+TESTS (char, SCHAR_MIN, SCHAR_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (char, SCHAR_MIN, SCHAR_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-16.c.jj 
2016-06-15 09:56:09.838240544 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-16.c    
2016-06-15 10:04:46.170562270 +0200
@@ -0,0 +1,18 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-12.h"
+
+TESTS (short, SHRT_MIN, SHRT_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (short, SHRT_MIN, SHRT_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-17.c.jj 
2016-06-15 09:56:09.840240518 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-17.c    
2016-06-15 10:05:05.049317617 +0200
@@ -0,0 +1,21 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run { target int128 } } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow-12.h"
+
+#define INT128_MAX ((signed __int128) (((unsigned __int128) 1 << 
(__SIZEOF_INT128__ * __CHAR_BIT__ - 1)) - 1))
+#define INT128_MIN (-INT128_MAX - 1)
+
+TESTS (__int128, INT128_MIN, INT128_MAX)
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS (__int128, INT128_MIN, INT128_MAX)
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-18.c.jj 
2016-06-15 09:56:09.841240505 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-18.c    
2016-06-15 10:05:20.846112903 +0200
@@ -0,0 +1,37 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#define OVFP
+#include "builtin-arith-overflow.h"
+
+#ifdef __SIZEOF_INT128__
+#define WTYPE __int128
+#else
+#define WTYPE long long int
+#endif
+
+#define TESTS \
+T (100, signed char, signed char, unsigned WTYPE, -1, 0, -1, add, 1) \
+T (101, unsigned char, unsigned char, unsigned WTYPE, 5, 5, 10, add, 0) \
+T (102, signed char, unsigned short, unsigned WTYPE, 5, 5, 0, sub, 0) \
+T (103, signed char, unsigned short, unsigned WTYPE, 5, 6, -1, sub, 1) \
+T (104, signed char, signed char, unsigned WTYPE, -1, -1, 1, mul, 0) \
+T (105, unsigned char, signed char, unsigned WTYPE, 17, -2, -34, mul, 1) \
+T (106, unsigned WTYPE, signed WTYPE, signed char, 5, -2, -10, mul, 0) \
+T (107, long long int, long long int, unsigned char, -3, 5, 2, add, 0) \
+T (108, long long int, int, unsigned char, -5, 3, -2, add, 1) \
+T (109, int, WTYPE, unsigned char, -3, 5, 2, add, 0) \
+T (110, unsigned char, unsigned char, unsigned WTYPE, SCHAR_MAX - 1, (unsigned 
char) SCHAR_MAX + 4, -5, sub, 1)
+
+TESTS
+
+#undef T
+#define T(n, t1, t2, tr, v1, v2, vr, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS
+  return 0;
+}
--- gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-19.c.jj 
2016-06-15 10:35:09.267196173 +0200
+++ gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-19.c    
2016-06-15 13:05:21.000000000 +0200
@@ -0,0 +1,73 @@
+/* Test __builtin_{add,sub,mul}_overflow_p.  */
+/* { dg-do run { target c } } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+
+#include "builtin-arith-overflow.h"
+
+#ifdef __SIZEOF_INT128__
+#define WTYPE __int128
+#else
+#define WTYPE long long int
+#endif
+
+struct S
+{
+  signed int s1 : 1;
+  unsigned int u1 : 1;
+  signed int s2 : 2;
+  unsigned int u2 : 2;
+  signed int s3 : 3;
+  unsigned int u3 : 3;
+  signed int s4 : 4;
+  unsigned int u4 : 4;
+  signed int s5 : 5;
+  unsigned int u5 : 5;
+  signed int s6 : 6;
+  unsigned int u6 : 6;
+  signed int s7 : 7;
+  unsigned int u7 : 7;
+} vs;
+
+#define TESTS \
+TP (100, signed char, signed char, vs.u2, -1, 0, add, 1) \
+TP (101, unsigned char, unsigned char, vs.u4, 5, 5, add, 0) \
+TP (102, unsigned char, unsigned char, vs.u3, 5, 3, add, 1) \
+TP (103, signed char, unsigned short, vs.u1, 5, 5, sub, 0) \
+TP (104, signed char, unsigned short, vs.u1, 6, 5, sub, 0) \
+TP (105, signed char, unsigned short, vs.u1, 7, 5, sub, 1) \
+TP (106, signed char, unsigned short, vs.u4, 5, 6, sub, 1) \
+TP (107, signed char, signed char, vs.u1, -1, -1, mul, 0) \
+TP (108, signed char, signed char, vs.s1, -1, -1, mul, 1) \
+TP (109, unsigned char, signed char, vs.u6, 17, -2, mul, 1) \
+TP (110, unsigned char, signed char, vs.s6, 17, -2, mul, 1) \
+TP (111, unsigned char, signed char, vs.s7, 17, -2, mul, 0) \
+TP (112, unsigned WTYPE, signed WTYPE, vs.s5, 5, -2, mul, 0) \
+TP (113, unsigned WTYPE, signed WTYPE, vs.s4, 5, -2, mul, 1) \
+TP (114, long long int, long long int, vs.u2, -3, 5, add, 0) \
+TP (115, long long int, long long int, vs.u1, -3, 5, add, 1) \
+TP (116, long long int, int, vs.u3, -5, 3, add, 1) \
+TP (117, long long int, int, vs.s1, -5, 3, add, 1) \
+TP (118, long long int, int, vs.s2, -5, 3, add, 0) \
+TP (119, int, WTYPE, vs.u2, -3, 5, add, 0) \
+TP (120, int, WTYPE, vs.u1, -3, 5, add, 1) \
+TP (121, unsigned char, unsigned char, vs.u6, SCHAR_MAX - 1, (unsigned char) 
SCHAR_MAX + 4, sub, 1) \
+TP (122, unsigned char, unsigned char, vs.s3, SCHAR_MAX - 1, (unsigned char) 
SCHAR_MAX + 4, sub, 1) \
+TP (123, unsigned char, unsigned char, vs.s4, SCHAR_MAX - 1, (unsigned char) 
SCHAR_MAX + 4, sub, 0) \
+TP (124, unsigned int, unsigned int, vs.u7, INT_MAX, 1, add, 1) \
+TP (125, unsigned int, unsigned int, vs.u7, 127, 1, add, 1) \
+TP (126, unsigned int, unsigned int, vs.u7, 1, 63, add, 0) \
+TP (127, int, int, vs.s7, INT_MIN, 1, sub, 1) \
+TP (128, int, int, vs.s7, -64, 1, sub, 1) \
+TP (129, int, int, vs.s7, -63, 1, sub, 0)
+
+TESTS
+
+#undef TP
+#define TP(n, t1, t2, er, v1, v2, b, o) t##n##b ();
+
+int
+main ()
+{
+  TESTS
+  return 0;
+}
--- gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C.jj      2016-06-14 
21:38:37.442312944 +0200
+++ gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C 2016-06-15 
09:23:17.900744560 +0200
@@ -1,11 +1,11 @@
 // { dg-do compile }

-enum A { B = 1, C = 2, D = __builtin_add_overflow_p (B, C, C) };
-int e[__builtin_add_overflow_p (B, C, C) + 1];
+enum A { B = 1, C = 2, D = __builtin_add_overflow_p (B, C, 0) };
+int e[__builtin_add_overflow_p (B, C, 0) + 1];
 template <int N> int foo (int);

 void
 bar ()
 {
-  foo <__builtin_add_overflow_p (B, C, C) + 1> (0);
+  foo <__builtin_add_overflow_p (B, C, 0) + 1> (0);
 }


        Jakub


Reply via email to