diff options
author | Martin Sebor <msebor@redhat.com> | 2019-01-24 21:06:01 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2019-01-24 14:06:01 -0700 |
commit | d8b5a1a00d4f88aa82c9119095e2b4993444f6ee (patch) | |
tree | e7c8ef5adbfbf022494077b361707815ca26de7d /gcc/c | |
parent | b0e0e88526c47e05346469db24d4111b5f43be54 (diff) | |
download | gcc-d8b5a1a00d4f88aa82c9119095e2b4993444f6ee.zip gcc-d8b5a1a00d4f88aa82c9119095e2b4993444f6ee.tar.gz gcc-d8b5a1a00d4f88aa82c9119095e2b4993444f6ee.tar.bz2 |
PR c/86125 - missing -Wbuiltin-declaration-mismatch on a mismatched return type
PR c/86125 - missing -Wbuiltin-declaration-mismatch on a mismatched return type
PR middle-end/86308 - ICE in verify_gimple calling index() with an invalid declaration
PR c/86125 - missing -Wbuiltin-declaration-mismatch on a mismatched return type
PR c/88886 - [9 Regression] ice in get_constant, at c-family/c-format.c:292
gcc/c/ChangeLog:
PR c/86125
PR c/88886
PR middle-end/86308
* c-decl.c (match_builtin_function_types): Add arguments.
(diagnose_mismatched_decls): Diagnose mismatched declarations
of built-ins more strictly.
gcc/testsuite/ChangeLog:
PR c/86125
PR c/88886
PR middle-end/86308
* gcc.dg/Wbuiltin-declaration-mismatch-6.c: New test.
* gcc.dg/Wbuiltin-declaration-mismatch-7.c: New test.
* gcc.dg/Wbuiltin-declaration-mismatch-8.c: New test.
* gcc.dg/Wbuiltin-declaration-mismatch-9.c: New test.
* gcc.dg/Wbuiltin-declaration-mismatch-10.c: New test.
* gcc.dg/builtins-69.c: New test.
* gcc.dg/Wint-conversion-2.c: Add expected warning.
* gcc.c-torture/execute/eeprof-1.c: Adjust function signatures.
From-SVN: r268251
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 120 |
2 files changed, 106 insertions, 23 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 32c77f9..cb89cd8 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,12 @@ +2019-01-24 Martin Sebor <msebor@redhat.com> + + PR c/86125 + PR c/88886 + PR middle-end/86308 + * c-decl.c (match_builtin_function_types): Add arguments. + (diagnose_mismatched_decls): Diagnose mismatched declarations + of built-ins more strictly. + 2019-01-24 Jakub Jelinek <jakub@redhat.com> PR c++/88976 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 57049f8..b60f155 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -1631,43 +1631,91 @@ c_bind (location_t loc, tree decl, bool is_global) bind (DECL_NAME (decl), decl, scope, false, nested, loc); } + +/* 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). + Used only by match_builtin_function_types. */ + +static GTY(()) tree last_fileptr_type; + /* Subroutine of compare_decls. Allow harmless mismatches in return - and argument types provided that the type modes match. This function - return a unified type given a suitable match, and 0 otherwise. */ + and argument types provided that the type modes match. Set *STRICT + and *ARGNO to the expected argument type and number in case of + an argument type mismatch or null and zero otherwise. Return + a unified type given a suitable match, and 0 otherwise. */ static tree -match_builtin_function_types (tree newtype, tree oldtype) +match_builtin_function_types (tree newtype, tree oldtype, + tree *strict, unsigned *argno) { - tree newrettype, oldrettype; - tree newargs, oldargs; - tree trytype, tryargs; - /* Accept the return type of the new declaration if same modes. */ - oldrettype = TREE_TYPE (oldtype); - newrettype = TREE_TYPE (newtype); + tree oldrettype = TREE_TYPE (oldtype); + tree newrettype = TREE_TYPE (newtype); + + *argno = 0; + *strict = NULL_TREE; if (TYPE_MODE (oldrettype) != TYPE_MODE (newrettype)) return NULL_TREE; - oldargs = TYPE_ARG_TYPES (oldtype); - newargs = TYPE_ARG_TYPES (newtype); - tryargs = newargs; + if (!comptypes (oldrettype, newrettype)) + *strict = oldrettype; - while (oldargs || newargs) + tree oldargs = TYPE_ARG_TYPES (oldtype); + tree newargs = TYPE_ARG_TYPES (newtype); + tree tryargs = newargs; + + for (unsigned i = 1; oldargs || newargs; ++i) { if (!oldargs || !newargs || !TREE_VALUE (oldargs) - || !TREE_VALUE (newargs) - || TYPE_MODE (TREE_VALUE (oldargs)) - != TYPE_MODE (TREE_VALUE (newargs))) + || !TREE_VALUE (newargs)) return NULL_TREE; + tree oldtype = TREE_VALUE (oldargs); + tree newtype = TREE_VALUE (newargs); + + /* Fail for types with incompatible modes/sizes. */ + if (TYPE_MODE (TREE_VALUE (oldargs)) + != TYPE_MODE (TREE_VALUE (newargs))) + return NULL_TREE; + + /* Fail for function and object pointer mismatches. */ + 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)) + { + *argno = i; + *strict = oldtype; + } + oldargs = TREE_CHAIN (oldargs); newargs = TREE_CHAIN (newargs); } - trytype = build_function_type (newrettype, tryargs); + tree trytype = build_function_type (newrettype, tryargs); /* Allow declaration to change transaction_safe attribute. */ tree oldattrs = TYPE_ATTRIBUTES (oldtype); @@ -1881,14 +1929,26 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (TREE_CODE (olddecl) == FUNCTION_DECL && fndecl_built_in_p (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl)) { - /* Accept harmless mismatch in function types. - This is for the ffs and fprintf builtins. */ - tree trytype = match_builtin_function_types (newtype, oldtype); + /* Accept "harmless" mismatches in function types such + as missing qualifiers or pointer vs same size integer + mismatches. This is for the ffs and fprintf builtins. + However, with -Wextra in effect, diagnose return and + argument types that are incompatible according to + language rules. */ + tree mismatch_expect; + unsigned mismatch_argno; + + tree trytype = match_builtin_function_types (newtype, oldtype, + &mismatch_expect, + &mismatch_argno); if (trytype && comptypes (newtype, trytype)) *oldtypep = oldtype = trytype; else { + /* 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. */ const char *header = header_for_builtin_fn (DECL_FUNCTION_CODE (olddecl)); location_t loc = DECL_SOURCE_LOCATION (newdecl); @@ -1905,11 +1965,25 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, 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. */ return false; } + + if (mismatch_expect && extra_warnings) + { + /* If types match only loosely, print a warning but accept + the redeclaration. */ + location_t newloc = DECL_SOURCE_LOCATION (newdecl); + if (mismatch_argno) + warning_at (newloc, OPT_Wbuiltin_declaration_mismatch, + "mismatch in argument %u type of built-in " + "function %qD; expected %qT", + mismatch_argno, newdecl, mismatch_expect); + else + warning_at (newloc, OPT_Wbuiltin_declaration_mismatch, + "mismatch in return type of built-in " + "function %qD; expected %qT", + newdecl, mismatch_expect); + } } else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_IS_BUILTIN (olddecl)) |