This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Reject boolean/enum types in last arg of __builtin_*_overflow_p (take 2)


I thought I already approved that patch.  If not, consider this approval.

Jason


On Wed, Jun 22, 2016 at 12:34 AM, Jeff Law <law@redhat.com> wrote:
> 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  <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.
>>
>>         * 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
>>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]