Commit 00085092 by Jakub Jelinek Committed by Jakub Jelinek

call.c (magic_varargs_p): Return 3 for __builtin_*_overflow_p.

	* call.c (magic_varargs_p): Return 3 for __builtin_*_overflow_p.
	(build_over_call): For magic == 3, do no conversion only on 3rd
	argument.

	* c-c++-common/torture/builtin-arith-overflow-p-19.c: Run for C++ too.
	* g++.dg/ext/builtin-arith-overflow-2.C: New test.

From-SVN: r237755
parent a86451b9
2016-06-24 Jakub Jelinek <jakub@redhat.com>
* call.c (magic_varargs_p): Return 3 for __builtin_*_overflow_p.
(build_over_call): For magic == 3, do no conversion only on 3rd
argument.
2016-06-23 Andi Kleen <ak@linux.intel.com> 2016-06-23 Andi Kleen <ak@linux.intel.com>
* Make-lang.in: Add support for autofdo. * Make-lang.in: Add support for autofdo.
......
...@@ -7132,7 +7132,8 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain) ...@@ -7132,7 +7132,8 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
which just decay_conversion or no conversions at all should be done. which just decay_conversion or no conversions at all should be done.
This is true for some builtins which don't act like normal functions. This is true for some builtins which don't act like normal functions.
Return 2 if no conversions at all should be done, 1 if just Return 2 if no conversions at all should be done, 1 if just
decay_conversion. */ decay_conversion. Return 3 for special treatment of the 3rd argument
for __builtin_*_overflow_p. */
int int
magic_varargs_p (tree fn) magic_varargs_p (tree fn)
...@@ -7149,6 +7150,11 @@ magic_varargs_p (tree fn) ...@@ -7149,6 +7150,11 @@ magic_varargs_p (tree fn)
case BUILT_IN_VA_START: case BUILT_IN_VA_START:
return 1; return 1;
case BUILT_IN_ADD_OVERFLOW_P:
case BUILT_IN_SUB_OVERFLOW_P:
case BUILT_IN_MUL_OVERFLOW_P:
return 3;
default:; default:;
return lookup_attribute ("type generic", return lookup_attribute ("type generic",
TYPE_ATTRIBUTES (TREE_TYPE (fn))) != 0; TYPE_ATTRIBUTES (TREE_TYPE (fn))) != 0;
...@@ -7606,14 +7612,14 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ...@@ -7606,14 +7612,14 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
for (; arg_index < vec_safe_length (args); ++arg_index) for (; arg_index < vec_safe_length (args); ++arg_index)
{ {
tree a = (*args)[arg_index]; tree a = (*args)[arg_index];
if (magic == 2) if ((magic == 3 && arg_index == 2) || magic == 2)
{ {
/* Do no conversions for certain magic varargs. */ /* Do no conversions for certain magic varargs. */
a = mark_type_use (a); a = mark_type_use (a);
if (TREE_CODE (a) == FUNCTION_DECL && reject_gcc_builtin (a)) if (TREE_CODE (a) == FUNCTION_DECL && reject_gcc_builtin (a))
return error_mark_node; return error_mark_node;
} }
else if (magic == 1) else if (magic != 0)
/* For other magic varargs only do decay_conversion. */ /* For other magic varargs only do decay_conversion. */
a = decay_conversion (a, complain); a = decay_conversion (a, complain);
else if (DECL_CONSTRUCTOR_P (fn) else if (DECL_CONSTRUCTOR_P (fn)
......
2016-06-24 Jakub Jelinek <jakub@redhat.com> 2016-06-24 Jakub Jelinek <jakub@redhat.com>
* c-c++-common/torture/builtin-arith-overflow-p-19.c: Run for C++ too.
* g++.dg/ext/builtin-arith-overflow-2.C: New test.
* c-c++-common/builtin-arith-overflow-1.c (generic_wrong_type, f3, * c-c++-common/builtin-arith-overflow-1.c (generic_wrong_type, f3,
f4): Adjust expected diagnostics. f4): Adjust expected diagnostics.
* c-c++-common/torture/builtin-arith-overflow.h (TP): New macro. * c-c++-common/torture/builtin-arith-overflow.h (TP): New macro.
......
/* Test __builtin_{add,sub,mul}_overflow_p. */ /* Test __builtin_{add,sub,mul}_overflow_p. */
/* { dg-do run { target c } } */ /* { dg-do run } */
/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ /* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */
#include "builtin-arith-overflow.h" #include "builtin-arith-overflow.h"
......
// { dg-do run }
// { dg-options "-O2" }
struct A { int i : 1; };
struct B { int j : 3; };
template <typename S>
int
foo (int x, int y)
{
A a = {};
S s = {};
return __builtin_add_overflow_p (x, y, a.i) + 2 * __builtin_mul_overflow_p (x, y, s.j);
}
__attribute__((noinline, noclone)) int
bar (int x, int y)
{
return foo <B> (x, y);
}
#if __cplusplus >= 201402L
template <typename S>
constexpr int
baz (int x, int y)
{
A a = {};
S s = {};
return __builtin_add_overflow_p (x, y, a.i) + 2 * __builtin_mul_overflow_p (x, y, s.j);
}
constexpr int t1 = baz <B> (0, 0);
constexpr int t2 = baz <B> (1, -1);
constexpr int t3 = baz <B> (1, -4);
constexpr int t4 = baz <B> (-4, 4);
constexpr int t5 = baz <B> (4, 2);
static_assert (t1 == 0, "");
static_assert (t2 == 0, "");
static_assert (t3 == 1, "");
static_assert (t4 == 2, "");
static_assert (t5 == 3, "");
#endif
int
main ()
{
if (bar (0, 0) != 0
|| bar (-1, 1) != 0
|| bar (-4, 1) != 1
|| bar (4, -4) != 2
|| bar (2, 4) != 3)
__builtin_abort ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment