From: Jakub Jelinek Date: Fri, 24 Jun 2016 11:03:27 +0000 (+0200) Subject: internal-fn.c (expand_arith_set_overflow): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a86451b9b20415805e6316638c349cce86252893;p=gcc.git internal-fn.c (expand_arith_set_overflow): New function. * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e53614d339a..fdc489833f7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2016-06-24 Jakub Jelinek + + * 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 Bill Schmidt diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index cd463154da6..16e55726976 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2016-06-24 Jakub Jelinek + + * 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 PR c/70339 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 8f21fd1ad98..4988f066eb2 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -9983,10 +9983,22 @@ check_builtin_function_arguments (location_t loc, vec 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 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; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 06d52b8ce0d..604b441d184 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index c867ddc0ef7..de850fdb493 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -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, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 24944bd7b66..0276069ce1f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,32 @@ +2016-06-24 Jakub Jelinek + + * 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 * g++.dg/vect/pr33834_2.cc: Use dg-additional-options instead of diff --git a/gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c b/gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c index 3576748e1ee..e119d2491d3 100644 --- a/gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c +++ b/gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c @@ -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; } diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-12.c b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-12.c index a37d817205b..0fe0498635d 100644 --- a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-12.c +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-12.c @@ -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 index 00000000000..b90a649448b --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-1.c @@ -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 index 00000000000..bf514dd3042 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-10.c @@ -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 index 00000000000..7be9c0fc4b0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-11.c @@ -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 index 00000000000..2f38c185211 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-12.c @@ -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 index 00000000000..0859ef204e5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-13.c @@ -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 index 00000000000..57b1e5a923d --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-14.c @@ -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 index 00000000000..434ea35dde6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-15.c @@ -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 index 00000000000..0d6dd956194 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-16.c @@ -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 index 00000000000..18721d3fbfc --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-17.c @@ -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 index 00000000000..6f10073cf42 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-18.c @@ -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 index 00000000000..38f6d07536e --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-19.c @@ -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 index 00000000000..868bbbd2f5a --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-2.c @@ -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 index 00000000000..90fa9308079 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-3.c @@ -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 index 00000000000..e63a0591b19 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-4.c @@ -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 index 00000000000..14a7b61761d --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-5.c @@ -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 index 00000000000..ba05aba47ab --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-6.c @@ -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 index 00000000000..cb594a284c1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-7.c @@ -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 index 00000000000..5200be99d46 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-8.c @@ -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 index 00000000000..a26cc0674d6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow-p-9.c @@ -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" diff --git a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow.h b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow.h index 9bf3ecf1f21..c79999ebf6e 100644 --- a/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow.h +++ b/gcc/testsuite/c-c++-common/torture/builtin-arith-overflow.h @@ -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) diff --git a/gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C b/gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C index 669eea2cbd2..e0c93e54f55 100644 --- a/gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C +++ b/gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C @@ -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 foo (int); void bar () { - foo <__builtin_add_overflow_p (B, C, C) + 1> (0); + foo <__builtin_add_overflow_p (B, C, 0) + 1> (0); } diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index ecfab1f53ec..4333d60672f 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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);