This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Reject boolean/enum types in last arg of __builtin_*_overflow_p (take 2)
- From: Jason Merrill <jason at redhat dot com>
- To: Jeff Law <law at redhat dot com>
- Cc: Jakub Jelinek <jakub at redhat dot com>, "Joseph S. Myers" <joseph at codesourcery dot com>, Marek Polacek <polacek at redhat dot com>, Martin Sebor <msebor at gmail dot com>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 24 Jun 2016 00:27:10 +0300
- Subject: Re: [PATCH] Reject boolean/enum types in last arg of __builtin_*_overflow_p (take 2)
- Authentication-results: sourceware.org; auth=none
- References: <20160610190835 dot GF7387 at tucnak dot redhat dot com> <575B14F7 dot 3070907 at gmail dot com> <20160614083359 dot GA7387 at tucnak dot redhat dot com> <20160614101602 dot GB7387 at tucnak dot redhat dot com> <57603B38 dot 9080302 at gmail dot com> <20160615114756 dot GJ7387 at tucnak dot redhat dot com> <49f9fbc0-9fb0-d0e0-06f4-a33546148eb7 at redhat dot com>
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
>>
>