internal-fn.c (expand_arith_set_overflow): New function.
authorJakub Jelinek <jakub@redhat.com>
Fri, 24 Jun 2016 11:03:27 +0000 (13:03 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 24 Jun 2016 11:03:27 +0000 (13:03 +0200)
* 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.

From-SVN: r237754

30 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/doc/extend.texi
gcc/internal-fn.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-12.c
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-10.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-11.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-12.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-13.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-14.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-15.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-16.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-17.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-18.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-19.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-3.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-4.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-5.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-6.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-7.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-8.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-9.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/torture/builtin-arith-overflow.h
gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C
gcc/tree-vrp.c

index e53614d339a9e800531a53baf25ae41f9ffb8d4b..fdc489833f71287c562c7da12df0224bf7476191 100644 (file)
@@ -1,3 +1,17 @@
+2016-06-24  Jakub Jelinek  <jakub@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.
+
 2016-06-23  Michael Meissner  <meissner@linux.vnet.ibm.com>
            Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
index cd463154da64b586d57de5df04c004721064aac3..16e557269768c6233f18221817650179c32215f5 100644 (file)
@@ -1,3 +1,10 @@
+2016-06-24  Jakub Jelinek  <jakub@redhat.com>
+
+       * 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.
+
 2016-06-22  David Malcolm  <dmalcolm@redhat.com>
 
        PR c/70339
index 8f21fd1ad98aca8b87f2b36104677244ac42f1e8..4988f066eb2489ee2bee6142a7b48a28a96fbf97 100644 (file)
@@ -9983,10 +9983,22 @@ check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
                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 (location_t loc, vec<location_t> arg_loc,
                          "%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;
index 06d52b8ce0d21e6638e21acf27a6ef219bf1b7b2..604b441d1845aeb2cd05cb73777ed9e040b22f43 100644 (file)
@@ -9833,8 +9833,8 @@ performed in infinite signed precision, these built-in functions have fully defi
 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
index c867ddc0ef7ddbe4841b00a1db1b49592db3f69b..de850fdb493f1bb05b24c991854b086e2bc59a2f 100644 (file)
@@ -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 lhs, rtx target,
       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, tree_code code, tree lhs,
       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, tree lhs, tree arg1, bool is_ubsan)
       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, tree lhs, tree arg0, tree arg1,
                                   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, tree lhs, tree arg0, tree arg1,
             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, tree lhs, tree arg0, tree arg1,
       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, tree lhs, tree arg0, tree arg1,
       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, tree lhs, tree arg0, tree arg1,
       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,
index 24944bd7b66e6033c02805ccd5355dedbd7e6dc9..0276069ce1fbaf82d0203aa463ebdb6a18736772 100644 (file)
@@ -1,3 +1,32 @@
+2016-06-24  Jakub Jelinek  <jakub@redhat.com>
+
+       * 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.
+
 2016-06-23  Uros Bizjak  <ubizjak@gmail.com>
 
        * g++.dg/vect/pr33834_2.cc: Use dg-additional-options instead of
index 3576748e1eeaa59bc89bc625f657ea0b2a5b0481..e119d2491d3feb98da1658c49f7e8a0ed1bc8319 100644 (file)
@@ -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 ca, double fb, void *pb, int b, enum E eb
   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 ca, double fb, void *pb, int b, enum E eb
 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;
 }
index a37d817205be974fae2e9f746f3c67b08653613c..0fe0498635d3eb0fdd1e726fc911674ae54fd0ed 100644 (file)
@@ -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" } } */
 
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-1.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-1.c
new file mode 100644 (file)
index 0000000..b90a649
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-10.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-10.c
new file mode 100644 (file)
index 0000000..bf514dd
--- /dev/null
@@ -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"
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-11.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-11.c
new file mode 100644 (file)
index 0000000..7be9c0f
--- /dev/null
@@ -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"
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-12.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-12.c
new file mode 100644 (file)
index 0000000..2f38c18
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-13.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-13.c
new file mode 100644 (file)
index 0000000..0859ef2
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-14.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-14.c
new file mode 100644 (file)
index 0000000..57b1e5a
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-15.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-15.c
new file mode 100644 (file)
index 0000000..434ea35
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-16.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-16.c
new file mode 100644 (file)
index 0000000..0d6dd95
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-17.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-17.c
new file mode 100644 (file)
index 0000000..18721d3
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-18.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-18.c
new file mode 100644 (file)
index 0000000..6f10073
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-19.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-19.c
new file mode 100644 (file)
index 0000000..38f6d07
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-2.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-2.c
new file mode 100644 (file)
index 0000000..868bbbd
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-3.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-3.c
new file mode 100644 (file)
index 0000000..90fa930
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-4.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-4.c
new file mode 100644 (file)
index 0000000..e63a059
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-5.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-5.c
new file mode 100644 (file)
index 0000000..14a7b61
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-6.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-6.c
new file mode 100644 (file)
index 0000000..ba05aba
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-7.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-7.c
new file mode 100644 (file)
index 0000000..cb594a2
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-8.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-8.c
new file mode 100644 (file)
index 0000000..5200be9
--- /dev/null
@@ -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"
diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-9.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-9.c
new file mode 100644 (file)
index 0000000..a26cc06
--- /dev/null
@@ -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"
index 9bf3ecf1f212b8426b8d5fc376fa6370486a456e..c79999ebf6ed9294f1392d79df86f9872832f697 100644 (file)
@@ -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)
index 669eea2cbd2972fe1e428d3c5cde226f8abd212a..e0c93e54f55b91c35e5bf0c3aa4fd15228ef0a3e 100644 (file)
@@ -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);
 }
index ecfab1f53ecd8115af07b02063f22434157f558c..4333d60672fe7bedd8fdbfcabb3d60ee0511b258 100644 (file)
@@ -4016,6 +4016,9 @@ extract_range_basic (value_range *vr, gimple *stmt)
                        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);