From: Jakub Jelinek Date: Mon, 28 Jan 2019 23:21:10 +0000 (+0100) Subject: re PR c/86125 (missing -Wbuiltin-declaration-mismatch on a mismatched return type) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6a335b9669b174c14a7811e967d199f2418e5f61;p=gcc.git 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 --- diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index f955449ec1c..3c55209ef34 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2019-01-29 Jakub Jelinek + + 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 * c-warn.c (check_address_or_pointer_of_packed_member): Handle the case diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 2a5a8e7defb..d3b5879a2b2 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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); diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index cb89cd881e5..e6bff9c064b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,16 @@ +2019-01-29 Jakub Jelinek + + 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 PR c/86125 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index b60f1557e9e..593b34e0047 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7af76a148c8..2e97ef3ae46 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2019-01-29 Jakub Jelinek + + 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 PR c++/88358 - name wrongly treated as type. diff --git a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-11.c b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-11.c new file mode 100644 index 00000000000..0c62c61faf3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-11.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-7.c b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-7.c index 77a4bfff4d3..7f6644edb58 100644 --- a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-7.c +++ b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-7.c @@ -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_\]+ \\\*\\\)." } */