re PR c/86125 (missing -Wbuiltin-declaration-mismatch on a mismatched return type)
PR c/86125 * c-decl.c (last_fileptr_type): Remove. (last_structptr_types): New variable. (match_builtin_function_types): Compare TYPE_MAIN_VARIANT of {old,new}rettype instead of the types themselves. Assert last_structptr_types array has the same number of elements as builtin_structptr_types array. Use TYPE_MAIN_VARIANT for argument oldtype and newtype. Instead of handling just fileptr_type_node specially, handle all builtin_structptr_types pointer nodes. Formatting fix. * c-common.c (c_common_nodes_and_builtins): Build type variants for builtin_structptr_types types even for C. * gcc.dg/Wbuiltin-declaration-mismatch-7.c: Guard testcase for lp64, ilp32 and llp64 only. (fputs): Use unsigned long long instead of size_t for return type. (vfprintf, vfscanf): Accept arbitrary target specific type for va_list. From-SVN: r268348
This commit is contained in:
parent
ab1be99f2b
commit
6a335b9669
|
@ -1,3 +1,9 @@
|
|||
2019-01-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/86125
|
||||
* c-common.c (c_common_nodes_and_builtins): Build type variants for
|
||||
builtin_structptr_types types even for C.
|
||||
|
||||
2019-01-28 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
|
||||
* c-warn.c (check_address_or_pointer_of_packed_member): Handle the case
|
||||
|
|
|
@ -4296,18 +4296,13 @@ c_common_nodes_and_builtins (void)
|
|||
COMPLEX_FLOATN_NX_TYPE_NODE (i)));
|
||||
}
|
||||
|
||||
if (c_dialect_cxx ())
|
||||
{
|
||||
/* For C++, make fileptr_type_node a distinct void * type until
|
||||
FILE type is defined. Likewise for const struct tm*. */
|
||||
for (unsigned i = 0;
|
||||
i < sizeof (builtin_structptr_types)
|
||||
/ sizeof (builtin_structptr_type);
|
||||
++i)
|
||||
builtin_structptr_types[i].node =
|
||||
build_variant_type_copy (builtin_structptr_types[i].base);
|
||||
|
||||
}
|
||||
/* Make fileptr_type_node a distinct void * type until
|
||||
FILE type is defined. Likewise for const struct tm*. */
|
||||
for (unsigned i = 0;
|
||||
i < sizeof (builtin_structptr_types) / sizeof (builtin_structptr_type);
|
||||
++i)
|
||||
builtin_structptr_types[i].node
|
||||
= build_variant_type_copy (builtin_structptr_types[i].base);
|
||||
|
||||
record_builtin_type (RID_VOID, NULL, void_type_node);
|
||||
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
2019-01-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/86125
|
||||
* c-decl.c (last_fileptr_type): Remove.
|
||||
(last_structptr_types): New variable.
|
||||
(match_builtin_function_types): Compare TYPE_MAIN_VARIANT of
|
||||
{old,new}rettype instead of the types themselves. Assert
|
||||
last_structptr_types array has the same number of elements
|
||||
as builtin_structptr_types array. Use TYPE_MAIN_VARIANT for
|
||||
argument oldtype and newtype. Instead of handling
|
||||
just fileptr_type_node specially, handle all builtin_structptr_types
|
||||
pointer nodes. Formatting fix.
|
||||
|
||||
2019-01-24 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/86125
|
||||
|
|
|
@ -1632,13 +1632,13 @@ c_bind (location_t loc, tree decl, bool is_global)
|
|||
}
|
||||
|
||||
|
||||
/* Stores the first FILE* argument type (whatever it is) seen in
|
||||
a declaration of a file I/O built-in. Subsequent declarations
|
||||
of such built-ins are expected to refer to it rather than to
|
||||
fileptr_type_node which is just void* (or to any other type).
|
||||
/* Stores the first FILE*, const struct tm* etc. argument type (whatever it
|
||||
is) seen in a declaration of a file I/O etc. built-in. Subsequent
|
||||
declarations of such built-ins are expected to refer to it rather than to
|
||||
fileptr_type_node etc. which is just void* (or to any other type).
|
||||
Used only by match_builtin_function_types. */
|
||||
|
||||
static GTY(()) tree last_fileptr_type;
|
||||
static GTY(()) tree last_structptr_types[6];
|
||||
|
||||
/* Subroutine of compare_decls. Allow harmless mismatches in return
|
||||
and argument types provided that the type modes match. Set *STRICT
|
||||
|
@ -1660,13 +1660,18 @@ match_builtin_function_types (tree newtype, tree oldtype,
|
|||
if (TYPE_MODE (oldrettype) != TYPE_MODE (newrettype))
|
||||
return NULL_TREE;
|
||||
|
||||
if (!comptypes (oldrettype, newrettype))
|
||||
if (!comptypes (TYPE_MAIN_VARIANT (oldrettype),
|
||||
TYPE_MAIN_VARIANT (newrettype)))
|
||||
*strict = oldrettype;
|
||||
|
||||
tree oldargs = TYPE_ARG_TYPES (oldtype);
|
||||
tree newargs = TYPE_ARG_TYPES (newtype);
|
||||
tree tryargs = newargs;
|
||||
|
||||
gcc_checking_assert ((sizeof (last_structptr_types)
|
||||
/ sizeof (last_structptr_types[0]))
|
||||
== (sizeof (builtin_structptr_types)
|
||||
/ sizeof (builtin_structptr_types[0])));
|
||||
for (unsigned i = 1; oldargs || newargs; ++i)
|
||||
{
|
||||
if (!oldargs
|
||||
|
@ -1675,8 +1680,8 @@ match_builtin_function_types (tree newtype, tree oldtype,
|
|||
|| !TREE_VALUE (newargs))
|
||||
return NULL_TREE;
|
||||
|
||||
tree oldtype = TREE_VALUE (oldargs);
|
||||
tree newtype = TREE_VALUE (newargs);
|
||||
tree oldtype = TYPE_MAIN_VARIANT (TREE_VALUE (oldargs));
|
||||
tree newtype = TYPE_MAIN_VARIANT (TREE_VALUE (newargs));
|
||||
|
||||
/* Fail for types with incompatible modes/sizes. */
|
||||
if (TYPE_MODE (TREE_VALUE (oldargs))
|
||||
|
@ -1684,28 +1689,39 @@ match_builtin_function_types (tree newtype, tree oldtype,
|
|||
return NULL_TREE;
|
||||
|
||||
/* Fail for function and object pointer mismatches. */
|
||||
if (FUNCTION_POINTER_TYPE_P (oldtype) != FUNCTION_POINTER_TYPE_P (newtype)
|
||||
if ((FUNCTION_POINTER_TYPE_P (oldtype)
|
||||
!= FUNCTION_POINTER_TYPE_P (newtype))
|
||||
|| POINTER_TYPE_P (oldtype) != POINTER_TYPE_P (newtype))
|
||||
return NULL_TREE;
|
||||
|
||||
if (oldtype == fileptr_type_node)
|
||||
{
|
||||
/* Store the first FILE* argument type (whatever it is), and
|
||||
expect any subsequent declarations of file I/O built-ins
|
||||
to refer to it rather than to fileptr_type_node which is
|
||||
just void*. */
|
||||
if (last_fileptr_type)
|
||||
{
|
||||
if (!comptypes (last_fileptr_type, newtype))
|
||||
{
|
||||
*argno = i;
|
||||
*strict = last_fileptr_type;
|
||||
}
|
||||
}
|
||||
else
|
||||
last_fileptr_type = newtype;
|
||||
}
|
||||
else if (!*strict && !comptypes (oldtype, newtype))
|
||||
unsigned j = (sizeof (builtin_structptr_types)
|
||||
/ sizeof (builtin_structptr_types[0]));
|
||||
if (POINTER_TYPE_P (oldtype))
|
||||
for (j = 0; j < (sizeof (builtin_structptr_types)
|
||||
/ sizeof (builtin_structptr_types[0])); ++j)
|
||||
{
|
||||
if (TREE_VALUE (oldargs) != builtin_structptr_types[j].node)
|
||||
continue;
|
||||
/* Store the first FILE* etc. argument type (whatever it is), and
|
||||
expect any subsequent declarations of file I/O etc. built-ins
|
||||
to refer to it rather than to fileptr_type_node etc. which is
|
||||
just void* (or const void*). */
|
||||
if (last_structptr_types[j])
|
||||
{
|
||||
if (!comptypes (last_structptr_types[j], newtype))
|
||||
{
|
||||
*argno = i;
|
||||
*strict = last_structptr_types[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
last_structptr_types[j] = newtype;
|
||||
break;
|
||||
}
|
||||
if (j == (sizeof (builtin_structptr_types)
|
||||
/ sizeof (builtin_structptr_types[0]))
|
||||
&& !*strict
|
||||
&& !comptypes (oldtype, newtype))
|
||||
{
|
||||
*argno = i;
|
||||
*strict = oldtype;
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
2019-01-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/86125
|
||||
* gcc.dg/Wbuiltin-declaration-mismatch-7.c: Guard testcase for
|
||||
lp64, ilp32 and llp64 only.
|
||||
(fputs): Use unsigned long long instead of size_t for return type.
|
||||
(vfprintf, vfscanf): Accept arbitrary target specific type for
|
||||
va_list.
|
||||
|
||||
2019-01-28 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/88358 - name wrongly treated as type.
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/* PR c/86125 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wbuiltin-declaration-mismatch -Wextra -Wno-ignored-qualifiers" } */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
struct FILE;
|
||||
struct tm;
|
||||
struct fenv_t;
|
||||
struct fexcept_t;
|
||||
typedef struct FILE FILE;
|
||||
typedef struct fenv_t fenv_t;
|
||||
typedef struct fexcept_t fexcept_t;
|
||||
typedef const int cint;
|
||||
size_t strftime (char *__restrict, const size_t, const char *__restrict, /* { dg-bogus "mismatch in argument 1 type of built-in function" } */
|
||||
const struct tm *__restrict) __attribute__((nothrow));
|
||||
int fprintf (struct FILE *, const char *const, ...); /* { dg-bogus "mismatch in argument 2 type of built-in function" } */
|
||||
cint putc (int, struct FILE *); /* { dg-bogus "mismatch in return type of built-in function" } */
|
||||
cint fegetenv (fenv_t *); /* { dg-bogus "mismatch in argument 1 type of built-in function" } */
|
||||
cint fesetenv (const fenv_t *); /* { dg-bogus "mismatch in return type of built-in function" } */
|
||||
int fegetexceptflag (fexcept_t *, const int); /* { dg-bogus "mismatch in argument 1 type of built-in function" } */
|
||||
int fesetexceptflag (const fexcept_t *, const int); /* { dg-bogus "mismatch in argument 1 type of built-in function" } */
|
|
@ -2,7 +2,7 @@
|
|||
return type
|
||||
Verify that a declaration of vfprintf() with withe the wrong last
|
||||
argument triggers -Wbuiltin-declaration-mismatch even without -Wextra.
|
||||
{ dg-do compile }
|
||||
{ dg-do compile { target { { lp64 || ilp32 } || llp64 } } }
|
||||
{ dg-options "-Wbuiltin-declaration-mismatch" } */
|
||||
|
||||
struct StdioFile;
|
||||
|
@ -13,14 +13,14 @@ struct StdioFile;
|
|||
|
||||
int fprintf (struct StdioFile*, const char*); /* { dg-warning "conflicting types for built-in function .fprintf.; expected .int\\\(\[a-z_\]+ \\\*, const char \\\*, \.\.\.\\\)." } */
|
||||
|
||||
int vfprintf (struct StdioFile*, const char*, ...); /* { dg-warning "conflicting types for built-in function .vfprintf.; expected .int\\\(\[a-z_\]+ \\\*, const char \\\*, \[a-z_\]+ \\\*\\\)." } */
|
||||
int vfprintf (struct StdioFile*, const char*, ...); /* { dg-warning "conflicting types for built-in function .vfprintf.; expected .int\\\(\[a-z_\]+ \\\*, const char \\\*, \[^\n\r,\\\)\]+\\\)." } */
|
||||
|
||||
int fputc (char, struct StdioFile*); /* { dg-warning "conflicting types for built-in function .fputc.; expected .int\\\(int, void \\\*\\\)." } */
|
||||
|
||||
size_t fputs (const char*, struct StdioFile*); /* { dg-warning "conflicting types for built-in function .fputs.; expected .int\\\(const char \\\*, \[a-z_\]+ \\\*\\\)." } */
|
||||
unsigned long long fputs (const char*, struct StdioFile*); /* { dg-warning "conflicting types for built-in function .fputs.; expected .int\\\(const char \\\*, \[a-z_\]+ \\\*\\\)." } */
|
||||
|
||||
int fscanf (struct StdioFile*, const char*, size_t, ...); /* { dg-warning "conflicting types for built-in function .fscanf.; expected .int\\\(\[a-z_\]+ \\\*, const char \\\*, \.\.\.\\\)." } */
|
||||
|
||||
int vfscanf (struct StdioFile*, const char*, ...); /* { dg-warning "conflicting types for built-in function .vfscanf.; expected .int\\\(\[a-z_\]+ \\\*, const char \\\*, \[a-z_\]+ \\\*\\\)." } */
|
||||
int vfscanf (struct StdioFile*, const char*, ...); /* { dg-warning "conflicting types for built-in function .vfscanf.; expected .int\\\(\[a-z_\]+ \\\*, const char \\\*, \[^\n\r,\\\)\]+\\\)." } */
|
||||
|
||||
size_t fwrite (const void*, size_t, size_t, struct StdioFile); /* { dg-warning "conflicting types for built-in function .fwrite.; expected .\(long \)?unsigned int\\\(const void \\\*, \(long \)?unsigned int, *\(long \)?unsigned int, *\[a-z_\]+ \\\*\\\)." } */
|
||||
|
|
Loading…
Reference in New Issue