Commit cd5da983 by Martin Sebor Committed by Martin Sebor

PR c/83656 - missing -Wbuiltin-declaration-mismatch on declaration without prototype

gcc/c/ChangeLog:

	PR c/83656
	* c-decl.c (header_for_builtin_fn): Declare.
	(diagnose_mismatched_decls): Diagnose declarations of built-in
	functions without a prototype.
	* c-typeck.c (maybe_warn_builtin_no_proto_arg): New function.
	(convert_argument): Same.
	(convert_arguments): Factor code out into convert_argument.
	Detect mismatches between built-in formal arguments in calls
	to built-in without prototype.
	(build_conditional_expr): Same.
	(type_or_builtin_type): New function.
	(convert_for_assignment): Add argument.  Conditionally issue
	warnings instead of errors for mismatches.

gcc/testsuite/ChangeLog:

	PR c/83656
	* gcc.dg/20021006-1.c
	* gcc.dg/Wbuiltin-declaration-mismatch.c: New test.
	* gcc.dg/Wbuiltin-declaration-mismatch-2.c: New test.
	* gcc.dg/Wbuiltin-declaration-mismatch-3.c: New test.
	* gcc.dg/Wbuiltin-declaration-mismatch-4.c: New test.
	* gcc.dg/Walloca-16.c: Adjust.
	* gcc.dg/Wrestrict-4.c: Adjust.
	* gcc.dg/Wrestrict-5.c: Adjust.
	* gcc.dg/atomic/stdatomic-generic.c: Adjust.
	* gcc.dg/atomic/stdatomic-lockfree.c: Adjust.
	* gcc.dg/initpri1.c: Adjust.
	* gcc.dg/pr15698-1.c: Adjust.
	* gcc.dg/pr69156.c: Adjust.
	* gcc.dg/pr83463.c: Adjust.
	* gcc.dg/redecl-4.c: Adjust.
	* gcc.dg/tls/thr-init-2.c: Adjust.
	* gcc.dg/torture/pr55890-2.c: Adjust.
	* gcc.dg/torture/pr55890-3.c: Adjust.
	* gcc.dg/torture/pr67741.c: Adjust.
	* gcc.dg/torture/stackalign/sibcall-1.c: Adjust.
	* gcc.dg/torture/tls/thr-init-1.c: Adjust.
	* gcc.dg/tree-ssa/builtins-folding-gimple-ub.c: Adjust.

From-SVN: r266194
parent 2a4030ef
2018-11-15 Martin Sebor <msebor@redhat.com>
PR c/83656
* c-decl.c (header_for_builtin_fn): Declare.
(diagnose_mismatched_decls): Diagnose declarations of built-in
functions without a prototype.
* c-typeck.c (maybe_warn_builtin_no_proto_arg): New function.
(convert_argument): Same.
(convert_arguments): Factor code out into convert_argument.
Detect mismatches between built-in formal arguments in calls
to built-in without prototype.
(build_conditional_expr): Same.
(type_or_builtin_type): New function.
(convert_for_assignment): Add argument. Conditionally issue
warnings instead of errors for mismatches.
2018-11-13 David Malcolm <dmalcolm@redhat.com>
* c-decl.c: Replace "source_location" with "location_t".
......
......@@ -604,6 +604,7 @@ static tree grokparms (struct c_arg_info *, bool);
static void layout_array_type (tree);
static void warn_defaults_to (location_t, int, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4);
static const char *header_for_builtin_fn (enum built_in_function);
/* T is a statement. Add it to the statement-tree. This is the
C/ObjC version--C++ has a slightly different version of this
......@@ -1887,12 +1888,25 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
*oldtypep = oldtype = trytype;
else
{
const char *header
= header_for_builtin_fn (DECL_FUNCTION_CODE (olddecl));
location_t loc = DECL_SOURCE_LOCATION (newdecl);
if (warning_at (loc, OPT_Wbuiltin_declaration_mismatch,
"conflicting types for built-in function %q+D; "
"expected %qT",
newdecl, oldtype)
&& header)
{
/* Suggest the right header to include as the preferred
solution rather than the spelling of the declaration. */
rich_location richloc (line_table, loc);
maybe_add_include_fixit (&richloc, header, true);
inform (&richloc,
"%qD is declared in header %qs", olddecl, header);
}
/* If types don't match for a built-in, throw away the
built-in. No point in calling locate_old_decl here, it
won't print anything. */
warning (OPT_Wbuiltin_declaration_mismatch,
"conflicting types for built-in function %q+D",
newdecl);
return false;
}
}
......@@ -2026,15 +2040,33 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
can't validate the argument list) the built-in definition is
overridden, but optionally warn this was a bad choice of name. */
if (fndecl_built_in_p (olddecl)
&& !C_DECL_DECLARED_BUILTIN (olddecl)
&& (!TREE_PUBLIC (newdecl)
|| (DECL_INITIAL (newdecl)
&& !prototype_p (TREE_TYPE (newdecl)))))
&& !C_DECL_DECLARED_BUILTIN (olddecl))
{
warning (OPT_Wshadow, "declaration of %q+D shadows "
"a built-in function", newdecl);
/* Discard the old built-in function. */
return false;
if (!TREE_PUBLIC (newdecl)
|| (DECL_INITIAL (newdecl)
&& !prototype_p (TREE_TYPE (newdecl))))
{
warning_at (DECL_SOURCE_LOCATION (newdecl),
OPT_Wshadow, "declaration of %qD shadows "
"a built-in function", newdecl);
/* Discard the old built-in function. */
return false;
}
if (!prototype_p (TREE_TYPE (newdecl)))
{
/* Set for built-ins that take no arguments. */
bool func_void_args = false;
if (tree at = TYPE_ARG_TYPES (oldtype))
func_void_args = VOID_TYPE_P (TREE_VALUE (at));
if (extra_warnings && !func_void_args)
warning_at (DECL_SOURCE_LOCATION (newdecl),
OPT_Wbuiltin_declaration_mismatch,
"declaration of built-in function %qD without "
"a prototype; expected %qT",
newdecl, TREE_TYPE (olddecl));
}
}
if (DECL_INITIAL (newdecl))
......
......@@ -7063,9 +7063,26 @@ attributes.
@item -Wno-builtin-declaration-mismatch
@opindex Wno-builtin-declaration-mismatch
@opindex Wbuiltin-declaration-mismatch
Warn if a built-in function is declared with the wrong signature or
as non-function.
This warning is enabled by default.
Warn if a built-in function is declared with an incompatible signature
or as a non-function, or when a built-in function declared with a type
that does not include a prototype is called with arguments whose promoted
types do not match those expected by the function. When @option{-Wextra}
is specified, also warn when a built-in function that takes arguments is
declared without a prototype. The @option{-Wno-builtin-declaration-mismatch}
warning is enabled by default. To avoid the warning include the appropriate
header to bring the prototypes of built-in functions into scope.
For example, the call to @code{memset} below is diagnosed by the warning
because the function expects a value of type @code{size_t} as its argument
but the type of @code{32} is @code{int}. With @option{-Wextra},
the declaration of the function is diagnosed as well.
@smallexample
extern void* memset ();
void f (void *d)
@{
memset (d, '\0', 32);
@}
@end smallexample
@item -Wno-builtin-macro-redefined
@opindex Wno-builtin-macro-redefined
2018-11-15 Martin Sebor <msebor@redhat.com>
PR c/83656
* gcc.dg/20021006-1.c
* gcc.dg/Wbuiltin-declaration-mismatch.c: New test.
* gcc.dg/Wbuiltin-declaration-mismatch-2.c: New test.
* gcc.dg/Wbuiltin-declaration-mismatch-3.c: New test.
* gcc.dg/Wbuiltin-declaration-mismatch-4.c: New test.
* gcc.dg/Walloca-16.c: Adjust.
* gcc.dg/Wrestrict-4.c: Adjust.
* gcc.dg/Wrestrict-5.c: Adjust.
* gcc.dg/atomic/stdatomic-generic.c: Adjust.
* gcc.dg/atomic/stdatomic-lockfree.c: Adjust.
* gcc.dg/initpri1.c: Adjust.
* gcc.dg/pr15698-1.c: Adjust.
* gcc.dg/pr69156.c: Adjust.
* gcc.dg/pr83463.c: Adjust.
* gcc.dg/redecl-4.c: Adjust.
* gcc.dg/tls/thr-init-2.c: Adjust.
* gcc.dg/torture/pr55890-2.c: Adjust.
* gcc.dg/torture/pr55890-3.c: Adjust.
* gcc.dg/torture/pr67741.c: Adjust.
* gcc.dg/torture/stackalign/sibcall-1.c: Adjust.
* gcc.dg/torture/tls/thr-init-1.c: Adjust.
* gcc.dg/tree-ssa/builtins-folding-gimple-ub.c: Adjust.
2018-11-15 Nathan Sidwell <nathan@acm.org>
PR c++/86246
......
......@@ -2,7 +2,7 @@
This testcase was miscompiled on x86-64 due to wrong access to the struct
members. */
extern void abort();
extern void abort(void);
struct A {
long x;
......
......@@ -5,3 +5,5 @@
void *alloca ();
__typeof__(alloca ()) a () { return alloca (); }
/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch]" } */
/* PR c/83656 - missing -Wbuiltin-declaration-mismatch on declaration
without prototype
{ dg-do compile }
{ dg-options "-Wall -Wextra" } */
typedef __SIZE_TYPE__ size_t;
/* Verify that ordinary library built-ins are not diagnosed with -Wextra
when they take no arguments (except in cases of return type mismatches).
This is in anticipation that C may some day adopt the same syntax as
C++ for declaring functions that take no arguments. */
void abort ();
/* Verify that ordinary library built-ins are diagnosed with -Wextra
when they take arguments. */
void* memcpy (); /* { dg-warning "declaration of built-in function .memcpy. without a prototype; expected .void \\\*\\\(void \\\*, const void \\\*, \(long \)*unsigned int\\\)." } */
void* memset (); /* { dg-warning "declaration of built-in function .memset. without a prototype; expected .void \\\*\\\(void \\\*, int, *\(long \)*unsigned int\\\)." } */
size_t strlen (); /* { dg-warning "declaration of built-in function .strlen. without a prototype; expected .\(long \)*unsigned int\\\(const char \\\*\\\)." } */
/* Variadic built-ins are diagnosed even without -Wextra (they are,
in fact, diagnosed by default). */
int printf (); /* { dg-warning "\\\[-Wbuiltin-declaration-mismatch]" } */
int sprintf (); /* { dg-warning "\\\[-Wbuiltin-declaration-mismatch]" } */
/* PR c/83656 - missing -Wbuiltin-declaration-mismatch on declaration
without prototype
{ dg-do compile }
{ dg-options "-Wbuiltin-declaration-mismatch" } */
typedef __SIZE_TYPE__ size_t;
/* Built-ins declared without a prototype are not diagnosed by default
(without -Wextra) except when their return type doesn't match. */
int abort (); /* { dg-warning "\\\[-Wbuiltin-declaration-mismatch]" } */
/* Built-ins declared without a prototype are not diagnosed without -Wextra. */
void exit ();
void* memcpy ();
void* memset ();
void test_call_abort (void)
{
/* Verify that a valid call to abort() is not diagnosed. */
abort ();
/* Unfortunately, the incompatible declaration above makes GCC "forget"
that abort() is a built-in and so the invalid calls below aren't
diagnosed. The only saving grace is that the invalid declaration
that differs in the return type is diagnosed by default. */
abort (1); /* { dg-warning "too many arguments to built-in function .abort. expecting 0" "pr?????" { xfail *-*-* } } */
abort (1, 2); /* { dg-warning "too many arguments" "pr?????" { xfail *-*-* } } */
}
void test_call_exit (void)
{
/* Verify that valid calls to exit are not diagnosed. */
exit ('\0');
exit (0);
/* Also verify calls to the built-in. */
__builtin_exit ('\0');
__builtin_exit (0);
__builtin_exit (0.0);
exit (); /* { dg-warning "too few arguments to built-in function 'exit' expecting 1" } */
exit (1, 2); /* { dg-warning "too many arguments" } */
/* Verify that passing incompatible arguments triggers a warning. */
exit (""); /* { dg-warning "\\\[-Wint-conversion]" } */
struct S { int i; } s = { 0 };
exit (s); /* { dg-warning "incompatible type for argument 1" } */
}
void test_call_memcpy (void *p, const void *q, size_t n)
{
memcpy (p, q, n);
memcpy (); /* { dg-warning "too few arguments to built-in function 'memcpy' expecting 3" } */
memcpy (p); /* { dg-warning "too few arguments to built-in function 'memcpy' expecting 3" } */
memcpy (p, q); /* { dg-warning "too few arguments to built-in function 'memcpy' expecting 3" } */
memcpy (q, p, n); /* { dg-warning "\\\[-Wdiscarded-qualifiers]" } */
memcpy (p, n, q); /* { dg-warning "\\\[-Wint-conversion]" } */
memcpy (p, q, n, 0); /* { dg-warning "too many arguments to built-in function 'memcpy' expecting 3" } */
}
typedef void* (memcpy_t)(void*, const void*, size_t);
typedef void* (memset_t)(void*, int, size_t);
void test_init (void)
{
/* Verify that initialization of a pointer by the address of a built-in
function of a matching type declared without a prototype doesn't
trigger a warning... */
memset_t *pmemset = memset;
/* ...but initialization by the address of an incompatible built-in
does even without -Wextra. */
memcpy_t *pmemcpy = memset; /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
}
void test_assign (void)
{
/* Same as above but for assignment. */
memset_t *pmemset;
pmemset = memset;
memcpy_t *pmemcpy;
pmemcpy = memset; /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
}
/* Verify that passing built-ins declared without a prototype to
functions that expect a pointer to a function of a specific type
is diagnosed. Ditto for return statements. */
void take_memcpy (memcpy_t*);
void take_any (int, ...);
memset_t* pass_args (int i)
{
take_memcpy (memcpy);
take_memcpy (memset); /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
take_any (0, i ? memcpy : memset); /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
return memcpy; /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
}
/* PR c/83656 - missing -Wbuiltin-declaration-mismatch on declaration
without prototype
{ dg-do compile }
{ dg-options "-Wbuiltin-declaration-mismatch" } */
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __SIZE_TYPE__ size_t;
char c;
signed char sc;
unsigned char uc;
short si;
unsigned short usi;
int i;
unsigned ui;
long li;
unsigned long uli;
size_t szi;
typedef size_t SizeType;
SizeType szti;
ptrdiff_t diffi;
enum E { e0 } e;
float f;
double d;
long double ld;
/* Verify warnings for undefined calls to built-ins expecting integer
arguments. */
int abs (); /* { dg-message "built-in .abs. declared here" } */
void test_integer_conversion_abs (void)
{
i = abs (c);
i = abs (sc);
i = abs (uc);
i = abs (si);
i = abs (usi);
i = abs (i);
i = abs (ui); /* { dg-warning ".abs. argument 1 type is .unsigned int. where .int. is expected in a call to built-in function declared without prototype" } */
/* Verify that the same call as above but to the built-in doesn't
trigger a warning. */
i = __builtin_abs (ui);
i = abs (li); /* { dg-warning ".abs. argument 1 type is .long int. where .int. is expected in a call to built-in function declared without prototype" } */
i = abs (uli); /* { dg-warning ".abs. argument 1 type is .long unsigned int. where .int. is expected in a call to built-in function declared without prototype" } */
i = abs (e0);
i = abs (e);
i = abs (-1.0); /* { dg-warning ".abs. argument 1 type is .double. where .int. is expected in a call to built-in function declared without prototype" } */
i = abs (f); /* { dg-warning ".abs. argument 1 promotes to .double. where .int. is expected in a call to built-in function declared without prototype" } */
i = abs (ld); /* { dg-warning ".abs. argument 1 type is .long double. where .int. is expected in a call to built-in function declared without prototype" } */
/* Verify that the same call as above but to the built-in doesn't
trigger a warning. */
i = __builtin_abs (ld);
}
extern void* memset ();
void test_integer_conversion_memset (void *d)
{
memset (d, 0, sizeof (int));
memset (d, '\0', szi);
memset (d, i, szti);
/* Passing a ptrdiff_t where size_t is expected may not be unsafe
but because GCC may emits suboptimal code for such calls warning
for them helps improve efficiency. */
memset (d, 0, diffi); /* { dg-warning ".memset. argument 3 promotes to .ptrdiff_t. {aka .long int.} where .long unsigned int. is expected" } */
memset (d, 0, 2.0); /* { dg-warning ".memset. argument 3 type is .double. where 'long unsigned int' is expected" } */
/* Verify that the same call as above but to the built-in doesn't
trigger a warning. */
__builtin_memset (d, 0.0, 4.0);
}
/* Verify warnings for undefined calls to built-ins expecting floating
arguments. */
double fabs (); /* { dg-message "built-in .fabs. declared here" } */
/* Expect a warning for fabsf below because even a float argument promotes
to double. Unfortunately, invalid calls to fabsf() are not diagnosed. */
float fabsf (); /* { dg-warning "conflicting types for built-in function .fabsf.; expected .float\\\(float\\\)." } */
long double fabsl (); /* { dg-message "built-in .fabsl. declared here" } */
void test_real_conversion_fabs (void)
{
d = fabs (c); /* { dg-warning ".fabs. argument 1 promotes to .int. where .double. is expected in a call to built-in function declared without prototype" } */
d = fabs (i); /* { dg-warning ".fabs. argument 1 type is .int. where .double. is expected in a call to built-in function declared without prototype" } */
d = fabs (li); /* { dg-warning ".fabs. argument 1 type is .long int. where .double. is expected in a call to built-in function declared without prototype" } */
/* In C, the type of an enumeration constant is int. */
d = fabs (e0); /* { dg-warning ".fabs. argument 1 type is .int. where .double. is expected in a call to built-in function declared without prototype" } */
d = fabs (e); /* { dg-warning ".fabs. argument 1 type is .enum E. where .double. is expected in a call to built-in function declared without prototype" } */
/* No warning here since float is promoted to double. */
d = fabs (f);
d = fabs (ld); /* { dg-warning ".fabs. argument 1 type is .long double. where .double. is expected in a call to built-in function declared without prototype" } */
d = fabsf (c); /* { dg-warning ".fabsf. argument 1 promotes to .int. where .float. is expected in a call to built-in function declared without prototype" "pr87890" { xfail *-*-* } } */
d = fabsl (c); /* { dg-warning ".fabsl. argument 1 promotes to .int. where .long double. is expected in a call to built-in function declared without prototype" } */
d = fabsl (f); /* { dg-warning ".fabsl. argument 1 promotes to .double. where .long double. is expected in a call to built-in function declared without prototype" } */
/* Verify that the same call as above but to the built-in doesn't
trigger a warning. */
d = __builtin_fabsl (f);
}
/* Verify warnings for calls to a two-argument real function. */
double pow (); /* { dg-message "built-in .pow. declared here" } */
void test_real_conversion_pow (void)
{
d = pow (2.0, 2.0);
d = pow (d, 3.0);
d = pow (d, d);
d = pow (2, 3.0); /* { dg-warning ".pow. argument 1 type is .int. where .double. is expected in a call to built-in function declared without prototype" } */
d = pow (3.0, 2); /* { dg-warning ".pow. argument 2 type is .int. where .double. is expected in a call to built-in function declared without prototype" } */
}
/* Verify warnings for calls that discard qualifiers. */
extern void* memcpy ();
void test_qual_conversion_memcpy (void *d, const void *s)
{
memcpy (d, s, sizeof (int));
memcpy (s, d, sizeof (int)); /* { dg-warning "passing argument 1 of .memcpy. discards 'const' qualifier from pointer target type" } */
}
/* PR c/83656 - missing -Wbuiltin-declaration-mismatch on declaration
without prototype
{ dg-do compile }
{ dg-options "-Wall" } */
typedef __SIZE_TYPE__ size_t;
/* Verify that ordinary library built-ins are not diagnosed with -Wall
(or by default) whether or not they take arguments (even though they
should be). */
void abort ();
void* memcpy ();
void* memset ();
size_t strlen ();
/* Verify mismatches in return types are diagnosed. */
int exit (); /* { dg-warning "\\\[-Wbuiltin-declaration-mismatch]" } */
/* Variadic built-ins are diagnosed with -Wall (they are, in fact,
diagnosed by default). */
int printf (); /* { dg-warning "\\\[-Wbuiltin-declaration-mismatch]" } */
int sprintf (); /* { dg-warning "\\\[-Wbuiltin-declaration-mismatch]" } */
......@@ -109,3 +109,5 @@ void* test_strncpy_2 (char *d, const char *s)
{
return strncpy (d, s);
}
/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch]" } */
......@@ -42,3 +42,6 @@ void test_strncpy_nowarn (char *d)
{
strncpy (d + 1, d + 3, "");
}
/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch]" }
{ dg-prune-output "\\\[-Wint-conversion]" } */
......@@ -4,7 +4,7 @@
#include <stdatomic.h>
extern void abort ();
extern void abort (void);
extern int memcmp (const void *, const void *, __SIZE_TYPE__);
typedef struct test {
......
......@@ -5,7 +5,7 @@
#include <stdatomic.h>
#include <stdint.h>
extern void abort ();
extern void abort (void);
_Atomic _Bool aba;
atomic_bool abt;
......
/* { dg-do run { target init_priority } } */
extern void abort ();
extern void abort (void);
int i;
int j;
......
......@@ -21,3 +21,5 @@ char *rindex(a, b)
{
return 0;
}
/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch]" } */
......@@ -5,6 +5,6 @@
_Bool
foo ()
{
_Bool (*f) () = __builtin_abs; /* { dg-warning "initialization of '_Bool \\(\\*\\)\\(\\)' from incompatible pointer type" } */
_Bool (*f) () = __builtin_abs; /* { dg-warning "initialization of '_Bool \\(\\*\\)\\(\\)' from pointer to .__builtin_abs. with incompatible type .int \\\(\\\*\\\)." } */
return f (0);
}
......@@ -16,3 +16,5 @@ p ()
{
m (p + (long) a);
}
/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch]" } */
......@@ -27,3 +27,6 @@ f (void)
/* Should still diagnose incompatible prototype for strcmp. */
int strcmp (void); /* { dg-error "conflict" } */
/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch]" }
{ dg-prune-output "\\\[-Wint-conversion]" } */
......@@ -2,7 +2,7 @@
/* { dg-require-effective-target tls_runtime } */
/* { dg-add-options tls } */
extern void abort() ;
extern void abort (void);
static __thread int fstat ;
static __thread int fstat = 1;
......
......@@ -3,3 +3,5 @@
extern void *memcpy();
int main() { memcpy(); }
/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch]" } */
......@@ -8,3 +8,5 @@ bar ()
{
return memmove ();
}
/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch]" } */
......@@ -9,5 +9,6 @@ float cabsf(fc)
{
struct doublecomplex dc ;
dc.real=fc.real; dc.imag=fc.imag;
return (float) cabs(dc);
return (float) cabs(dc); /* { dg-warning "incompatible type for argument 1 of .cabs." } */
}
/* { dg-do compile } */
/* { dg-prune-output "conflicting types for built-in" } */
/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch" } */
void *ext2fs_resize_mem_p;
struct ext2_icount_el {
......
/* { dg-do run } */
extern int ok (int);
extern void exit ();
extern void exit (int);
static int gen_x86_64_shrd (int);
static int
gen_x86_64_shrd(int a __attribute__ ((__unused__)))
......
......@@ -3,7 +3,7 @@
/* { dg-add-options tls } */
extern int printf (char *,...);
extern void abort() ;
extern void abort(void) ;
int test_code(int b)
{
......
......@@ -31,4 +31,5 @@ main (void)
return 0;
}
/* { dg-final { scan-tree-dump-times "__builtin_memchr" 2 "optimized" } } */
/* { dg-prune-output "-Wbuiltin-declaration-mismatch" }
{ dg-final { scan-tree-dump-times "__builtin_memchr" 2 "optimized" } } */
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