PR c/71392 - SEGV calling integer overflow built-ins with a null pointer

gcc/ChangeLog:
2016-06-10  Martin Sebor  <msebor@redhat.com>

	PR c/71392
	* builtin-attrs.def (ATTR_NOTHROW_NONNULL_LEAF_LIST): New macro.
	(ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF): Same.
	* builtins.def (BUILT_IN_SADD_OVERFLOW, BUILT_IN_SADDL_OVERFLOW): Use
	them.
	(BUILT_IN_SADDLL_OVERFLOW, BUILT_IN_SSUB_OVERFLOW): Same.
	(BUILT_IN_SSUBL_OVERFLOW, BUILT_IN_SSUBLL_OVERFLOW): Same.
	(BUILT_IN_SMUL_OVERFLOW, BUILT_IN_SMULL_OVERFLOW): Same.
	(BUILT_IN_SMULLL_OVERFLOW, BUILT_IN_UADD_OVERFLOW): Same.
	(BUILT_IN_UADDL_OVERFLOW, BUILT_IN_UADDLL_OVERFLOW): Same.
	(BUILT_IN_USUB_OVERFLOW, BUILT_IN_USUBL_OVERFLOW): Same.
	(BUILT_IN_USUBLL_OVERFLOW, BUILT_IN_UMUL_OVERFLOW): Same.
	(BUILT_IN_UMULL_OVERFLOW, BUILT_IN_UMULLL_OVERFLOW):

gcc/ada/ChangeLog:
2016-06-10  Martin Sebor  <msebor@redhat.com>

	PR c/71392
	* gcc/ada/gcc-interface/utils.c (handle_nonnull_attribute): Accept
	the nonnull attribute in type-generic builtins.

gcc/c-family/ChangeLog:
2016-06-10  Martin Sebor  <msebor@redhat.com>

	PR c/71392
	* gcc/c-family/c-common.c (handle_nonnull_attribute): Accept
	the nonnull attribute in type-generic builtins.

gcc/lto/ChangeLog:
2016-06-10  Martin Sebor  <msebor@redhat.com>

	PR c/71392
	* gcc/lto/lto-lang.c (handle_nonnull_attribute): Accept the nonnull
	attribute in type-generic builtins.

gcc/testsuite/ChangeLog:
2016-06-10  Martin Sebor  <msebor@redhat.com>

	PR c/71392
	* c-c++-common/builtin-arith-overflow-1.c: Add test cases.

From-SVN: r237314
This commit is contained in:
Martin Sebor 2016-06-10 17:38:19 +00:00 committed by Martin Sebor
parent a102ee4ba8
commit 4d926e3493
11 changed files with 281 additions and 32 deletions

View File

@ -1,3 +1,19 @@
2016-06-10 Martin Sebor <msebor@redhat.com>
PR c/71392
* builtin-attrs.def (ATTR_NOTHROW_NONNULL_LEAF_LIST): New macro.
(ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF): Same.
* builtins.def (BUILT_IN_SADD_OVERFLOW, BUILT_IN_SADDL_OVERFLOW): Use
them.
(BUILT_IN_SADDLL_OVERFLOW, BUILT_IN_SSUB_OVERFLOW): Same.
(BUILT_IN_SSUBL_OVERFLOW, BUILT_IN_SSUBLL_OVERFLOW): Same.
(BUILT_IN_SMUL_OVERFLOW, BUILT_IN_SMULL_OVERFLOW): Same.
(BUILT_IN_SMULLL_OVERFLOW, BUILT_IN_UADD_OVERFLOW): Same.
(BUILT_IN_UADDL_OVERFLOW, BUILT_IN_UADDLL_OVERFLOW): Same.
(BUILT_IN_USUB_OVERFLOW, BUILT_IN_USUBL_OVERFLOW): Same.
(BUILT_IN_USUBLL_OVERFLOW, BUILT_IN_UMUL_OVERFLOW): Same.
(BUILT_IN_UMULL_OVERFLOW, BUILT_IN_UMULLL_OVERFLOW):
2016-06-10 Bernd Edlinger <bernd.edlinger@hotmail.de>
* config/arm/arm.h (pool_vector_label,

View File

@ -1,3 +1,9 @@
2016-06-10 Martin Sebor <msebor@redhat.com>
PR c/71392
* gcc/ada/gcc-interface/utils.c (handle_nonnull_attribute): Accept
the nonnull attribute in type-generic builtins.
2016-06-06 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (Gigi_Equivalent_Type): Make sure equivalent

View File

@ -5833,10 +5833,14 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
/* If no arguments are specified, all pointer arguments should be
non-null. Verify a full prototype is given so that the arguments
will have the correct types when we actually check them later. */
will have the correct types when we actually check them later.
Avoid diagnosing type-generic built-ins since those have no
prototype. */
if (!args)
{
if (!prototype_p (type))
if (!prototype_p (type)
&& (!TYPE_ATTRIBUTES (type)
|| !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))))
{
error ("nonnull attribute without arguments on a non-prototype");
*no_add_attrs = true;

View File

@ -165,6 +165,7 @@ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL, ATTR_NONNULL, ATTR_NULL, \
/* Nothrow leaf functions whose pointer parameter(s) are all nonnull. */
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_LEAF, ATTR_NONNULL, ATTR_NULL, \
ATTR_NOTHROW_LEAF_LIST)
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_LEAF_LIST, ATTR_LEAF, ATTR_NULL, ATTR_NOTHROW_NONNULL_LEAF)
/* Nothrow functions whose first parameter is a nonnull pointer. */
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, \
ATTR_NOTHROW_LIST)
@ -183,6 +184,10 @@ DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_5, ATTR_NONNULL, ATTR_LIST_5, \
/* Nothrow leaf functions which are type-generic. */
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_TYPEGENERIC_LEAF, ATTR_TYPEGENERIC, ATTR_NULL, \
ATTR_NOTHROW_LEAF_LIST)
/* Nothrow nonnull leaf functions that are type-generic. */
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF,
ATTR_TYPEGENERIC, ATTR_NULL,
ATTR_NOTHROW_NONNULL_LEAF)
/* Nothrow const functions whose pointer parameter(s) are all nonnull. */
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL, ATTR_CONST, ATTR_NULL, \
ATTR_NOTHROW_NONNULL)

View File

@ -707,31 +707,31 @@ DEF_C94_BUILTIN (BUILT_IN_TOWLOWER, "towlower", BT_FN_WINT_WINT, ATTR_PUR
DEF_C94_BUILTIN (BUILT_IN_TOWUPPER, "towupper", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
/* Category: integer overflow checking builtins. */
DEF_GCC_BUILTIN (BUILT_IN_ADD_OVERFLOW, "add_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_SUB_OVERFLOW, "sub_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_MUL_OVERFLOW, "mul_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_ADD_OVERFLOW, "add_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_SUB_OVERFLOW, "sub_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_MUL_OVERFLOW, "mul_overflow", BT_FN_BOOL_VAR, ATTR_NOTHROW_NONNULL_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_ADD_OVERFLOW_P, "add_overflow_p", BT_FN_BOOL_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_SUB_OVERFLOW_P, "sub_overflow_p", BT_FN_BOOL_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
DEF_GCC_BUILTIN (BUILT_IN_MUL_OVERFLOW_P, "mul_overflow_p", BT_FN_BOOL_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
/* Clang compatibility. */
DEF_GCC_BUILTIN (BUILT_IN_SADD_OVERFLOW, "sadd_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SADDL_OVERFLOW, "saddl_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SADDLL_OVERFLOW, "saddll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SSUB_OVERFLOW, "ssub_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SSUBL_OVERFLOW, "ssubl_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SSUBLL_OVERFLOW, "ssubll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SMUL_OVERFLOW, "smul_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SMULL_OVERFLOW, "smull_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SMULLL_OVERFLOW, "smulll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UADD_OVERFLOW, "uadd_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UADDL_OVERFLOW, "uaddl_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UADDLL_OVERFLOW, "uaddll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_USUB_OVERFLOW, "usub_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_USUBL_OVERFLOW, "usubl_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_USUBLL_OVERFLOW, "usubll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UMUL_OVERFLOW, "umul_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UMULL_OVERFLOW, "umull_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UMULLL_OVERFLOW, "umulll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SADD_OVERFLOW, "sadd_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SADDL_OVERFLOW, "saddl_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SADDLL_OVERFLOW, "saddll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SSUB_OVERFLOW, "ssub_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SSUBL_OVERFLOW, "ssubl_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SSUBLL_OVERFLOW, "ssubll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SMUL_OVERFLOW, "smul_overflow", BT_FN_BOOL_INT_INT_INTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SMULL_OVERFLOW, "smull_overflow", BT_FN_BOOL_LONG_LONG_LONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_SMULLL_OVERFLOW, "smulll_overflow", BT_FN_BOOL_LONGLONG_LONGLONG_LONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UADD_OVERFLOW, "uadd_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UADDL_OVERFLOW, "uaddl_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UADDLL_OVERFLOW, "uaddll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_USUB_OVERFLOW, "usub_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_USUBL_OVERFLOW, "usubl_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_USUBLL_OVERFLOW, "usubll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UMUL_OVERFLOW, "umul_overflow", BT_FN_BOOL_UINT_UINT_UINTPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UMULL_OVERFLOW, "umull_overflow", BT_FN_BOOL_ULONG_ULONG_ULONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UMULLL_OVERFLOW, "umulll_overflow", BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, ATTR_NOTHROW_NONNULL_LEAF_LIST)
/* Category: miscellaneous builtins. */
DEF_LIB_BUILTIN (BUILT_IN_ABORT, "abort", BT_FN_VOID, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)

View File

@ -1,3 +1,9 @@
2016-06-10 Martin Sebor <msebor@redhat.com>
PR c/71392
* gcc/c-family/c-common.c (handle_nonnull_attribute): Accept
the nonnull attribute in type-generic builtins.
2016-06-09 Martin Sebor <msebor@redhat.com>
PR c/70883

View File

@ -9040,10 +9040,14 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
/* If no arguments are specified, all pointer arguments should be
non-null. Verify a full prototype is given so that the arguments
will have the correct types when we actually check them later. */
will have the correct types when we actually check them later.
Avoid diagnosing type-generic built-ins since those have no
prototype. */
if (!args)
{
if (!prototype_p (type))
if (!prototype_p (type)
&& (!TYPE_ATTRIBUTES (type)
|| !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))))
{
error ("nonnull attribute without arguments on a non-prototype");
*no_add_attrs = true;

View File

@ -1,3 +1,9 @@
2016-06-10 Martin Sebor <msebor@redhat.com>
PR c/71392
* gcc/lto/lto-lang.c (handle_nonnull_attribute): Accept the nonnull
attribute in type-generic builtins.
2016-05-16 Jan Hubicka <hubicka@ucw.cz>
* lto-partition.c (add_symbol_to_partition_1): Likewise.

View File

@ -352,10 +352,15 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
/* If no arguments are specified, all pointer arguments should be
non-null. Verify a full prototype is given so that the arguments
will have the correct types when we actually check them later. */
will have the correct types when we actually check them later.
Avoid diagnosing type-generic built-ins since those have no
prototype. */
if (!args)
{
gcc_assert (prototype_p (type));
gcc_assert (prototype_p (type)
|| !TYPE_ATTRIBUTES (type)
|| lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
return NULL_TREE;
}

View File

@ -1,3 +1,8 @@
2016-06-10 Martin Sebor <msebor@redhat.com>
PR c/71392
* c-c++-common/builtin-arith-overflow-1.c: Add test cases.
2016-06-10 Jeff Law <law@redhat.com>
PR tree-optimization/71335

View File

@ -1,7 +1,18 @@
/* Test exercising invalid calls to arithmetic overflow checking built-ins,
including PR c/71392 - SEGV calling integer overflow built-ins with a null
pointer, (issuing a warning for such invocations). */
/* { dg-do compile } */
/* { dg-additional-options "-Wnonnull" }
/* Verify that calls with fewer or more than 3 arguments to the generic
__builtin_op_overflow functions are rejected. */
#ifndef __cplusplus
#define bool _Bool
#endif
int
f1 (void)
generic_0 (void)
{
int x = __builtin_add_overflow (); /* { dg-error "too few arguments to function" } */
x += __builtin_sub_overflow (); /* { dg-error "too few arguments to function" } */
@ -12,6 +23,191 @@ f1 (void)
return x;
}
int
generic_1 (int a)
{
int x = __builtin_add_overflow (a); /* { dg-error "too few arguments to function" } */
x += __builtin_sub_overflow (a); /* { dg-error "too few arguments to function" } */
x += __builtin_mul_overflow (a); /* { dg-error "too few arguments to function" } */
/* Literal argument. */
x += __builtin_add_overflow (1); /* { dg-error "too few arguments to function" } */
x += __builtin_sub_overflow (2); /* { dg-error "too few arguments to function" } */
x += __builtin_mul_overflow (3); /* { dg-error "too few arguments to function" } */
return x;
}
int
generic_2 (int a, int b)
{
int x = __builtin_add_overflow (a, b);/* { dg-error "too few arguments to function" } */
x += __builtin_sub_overflow (a, b); /* { dg-error "too few arguments to function" } */
x += __builtin_mul_overflow (a, b); /* { dg-error "too few arguments to function" } */
x += __builtin_add_overflow (a, 1); /* { dg-error "too few arguments to function" } */
x += __builtin_sub_overflow (a, 2); /* { dg-error "too few arguments to function" } */
x += __builtin_mul_overflow (a, 3); /* { dg-error "too few arguments to function" } */
x += __builtin_add_overflow (4, b); /* { dg-error "too few arguments to function" } */
x += __builtin_sub_overflow (5, b); /* { dg-error "too few arguments to function" } */
x += __builtin_mul_overflow (6, b); /* { dg-error "too few arguments to function" } */
return x;
}
/* Verify that calls with the correct number of arguments to the generic
__builtin_op_overflow functions are accepted. */
int
generic_3 (int a, int b, int c)
{
int x = __builtin_add_overflow (a, b, &c);
x += __builtin_sub_overflow (a, b, &c);
x += __builtin_mul_overflow (a, b, &c);
x += __builtin_add_overflow (a, 1, &c);
x += __builtin_sub_overflow (a, 2, &c);
x += __builtin_mul_overflow (a, 3, &c);
x += __builtin_add_overflow (4, b, &c);
x += __builtin_sub_overflow (5, b, &c);
x += __builtin_mul_overflow (6, b, &c);
x += __builtin_add_overflow (7, 8, &c);
x += __builtin_sub_overflow (9, 10, &c);
x += __builtin_mul_overflow (11, 12, &c);
/* Verify that a null pointer to an integer is diagnosed. */
/* The following two are rejected due to c/71479 - error on
__builtin_add_overflow with bool or enum pointer as last argument.
x += __builtin_add_overflow (0, 0, (bool *)0);
enum E { e0 };
x += __builtin_add_overflow (0, 0, (enum E *)0);
*/
x += __builtin_sub_overflow (0, 0, (char *)0); /* { dg-warning "null argument" } */
x += __builtin_add_overflow (0, 0, (short *)0); /* { dg-warning "null argument" } */
x += __builtin_add_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_sub_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_mul_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_add_overflow (a, 1, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_sub_overflow (a, 2, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_mul_overflow (a, 3, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_add_overflow (4, b, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_sub_overflow (5, b, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_mul_overflow (6, b, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_add_overflow (7, 8, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_sub_overflow (9, 10, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_mul_overflow (11, 12, (int *)0); /* { dg-warning "null argument" } */
return x;
}
int
generic_4 (int a, int b, int *c, int d)
{
int x = __builtin_add_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */
x += __builtin_sub_overflow (a, b, c, d, d, d); /* { dg-error "too many arguments to function" } */
x += __builtin_sub_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */
x += __builtin_mul_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */
return x;
}
/* Verify that calls with fewer or more than 3 arguments to the type
specific forms of the __builtin_op_overflow functions are rejected. */
int
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" } */
/* 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" } */
return x;
}
/* Verify that calls with fewer than 2 or more than 3 arguments to
the typed __builtin_op_overflow functions are rejected. */
int
typed_0 (void)
{
int x = __builtin_add_overflow (); /* { dg-error "too few arguments to function" } */
x += __builtin_sub_overflow (); /* { dg-error "too few arguments to function" } */
x += __builtin_mul_overflow (); /* { dg-error "too few arguments to function" } */
return x;
}
int
typed_1 (int a)
{
int x = __builtin_sadd_overflow (a); /* { dg-error "too few arguments to function" } */
x += __builtin_ssub_overflow (a); /* { dg-error "too few arguments to function" } */
x += __builtin_smul_overflow (a); /* { dg-error "too few arguments to function" } */
return x;
}
int
typed_2 (int a, int b)
{
int x = __builtin_sadd_overflow (a, b); /* { dg-error "too few arguments to function" } */
x += __builtin_ssub_overflow (a, b); /* { dg-error "too few arguments to function" } */
x += __builtin_smul_overflow (a, b); /* { dg-error "too few arguments to function" } */
return x;
}
/* Exercise PR c/71392 - SEGV calling integer overflow built-ins with
a null pointer. Verify that calls with a null argument are diagnosed
with -Wnonnull. */
int
typed_3_null (int a, int b)
{
int x = 0;
x += __builtin_sadd_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_uadd_overflow (a, b, (unsigned *)0); /* { dg-warning "null argument" } */
x += __builtin_saddl_overflow (a, b, (long *)0); /* { dg-warning "null argument" } */
x += __builtin_uaddl_overflow (a, b, (unsigned long *)0); /* { dg-warning "null argument" } */
x += __builtin_saddll_overflow (a, b, (long long *)0); /* { dg-warning "null argument" } */
x += __builtin_uaddll_overflow (a, b, (unsigned long long *)0); /* { dg-warning "null argument" } */
x += __builtin_ssub_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_usub_overflow (a, b, (unsigned *)0); /* { dg-warning "null argument" } */
x += __builtin_ssubl_overflow (a, b, (long *)0); /* { dg-warning "null argument" } */
x += __builtin_usubl_overflow (a, b, (unsigned long *)0); /* { dg-warning "null argument" } */
x += __builtin_ssubll_overflow (a, b, (long long *)0); /* { dg-warning "null argument" } */
x += __builtin_usubll_overflow (a, b, (unsigned long long *)0); /* { dg-warning "null argument" } */
x += __builtin_smul_overflow (a, b, (int *)0); /* { dg-warning "null argument" } */
x += __builtin_umul_overflow (a, b, (unsigned *)0); /* { dg-warning "null argument" } */
x += __builtin_smull_overflow (a, b, (long *)0); /* { dg-warning "null argument" } */
x += __builtin_umull_overflow (a, b, (unsigned long *)0); /* { dg-warning "null argument" } */
x += __builtin_smulll_overflow (a, b, (long long *)0); /* { dg-warning "null argument" } */
x += __builtin_umulll_overflow (a, b, (unsigned long long *)0); /* { dg-warning "null argument" } */
return x;
}
int
typed_4 (int a, int b, int *c, int d)
{
int x = __builtin_sadd_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */
x += __builtin_ssub_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */
x += __builtin_smul_overflow (a, b, c, d); /* { dg-error "too many arguments to function" } */
return x;
}
int
f2 (int a, int b, int *c, int d)
{
@ -27,10 +223,6 @@ f2 (int a, int b, int *c, int d)
enum E { e0 = 0, e1 = 1 };
#ifndef __cplusplus
#define bool _Bool
#endif
int
f3 (float fa, int a, _Complex long int ca, double fb, void *pb, int b, enum E eb, bool bb, int *c)
{