diff options
author | Joseph Myers <joseph@codesourcery.com> | 2010-05-23 21:47:16 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2010-05-23 21:47:16 +0100 |
commit | dc5027f47440baef6b984b029fb5c3e5ee59e5ba (patch) | |
tree | 83fb32a9434ffd3ff6d6985dd79f64b42099c036 /gcc/c-decl.c | |
parent | 8f9e812dacef3cc9eedb9fa17111affa93454287 (diff) | |
download | gcc-dc5027f47440baef6b984b029fb5c3e5ee59e5ba.zip gcc-dc5027f47440baef6b984b029fb5c3e5ee59e5ba.tar.gz gcc-dc5027f47440baef6b984b029fb5c3e5ee59e5ba.tar.bz2 |
c-decl.c (diagnose_mismatched_decls): Give error for duplicate typedefs with different but compatible types.
* c-decl.c (diagnose_mismatched_decls): Give error for duplicate
typedefs with different but compatible types. Allow duplicate
typedefs with the same type except for pedantic non-C1X, but give
warning for variably modified types.
* c-typeck.c (tagged_types_tu_compatible_p,
function_types_compatible_p, type_lists_compatible_p,
comptypes_internal): Add parameter different_types_p; set
*different_types_p for different but compatible types. All
callers changed.
(comptypes_check_different_types): New.
* c-tree.h (comptypes_check_different_types): Declare.
testsuite:
* gcc.dg/c1x-typedef-1.c, gcc.dg/c1x-typedef-2.c,
gcc.dg/c90-typedef-1.c, gcc.dg/c99-typedef-1.c: New tests.
* gcc.dg/decl-8.c: Use -std=gnu89 -pedantic-errors.
From-SVN: r159767
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index af038e1..68b0f8c 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1786,18 +1786,48 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, /* Redeclaration of a type is a constraint violation (6.7.2.3p1), but silently ignore the redeclaration if either is in a system - header. (Conflicting redeclarations were handled above.) */ + header. (Conflicting redeclarations were handled above.) This + is allowed for C1X if the types are the same, not just + compatible. */ if (TREE_CODE (newdecl) == TYPE_DECL) { + bool types_different = false; + int comptypes_result; + + comptypes_result + = comptypes_check_different_types (oldtype, newtype, &types_different); + + if (comptypes_result != 1 || types_different) + { + error ("redefinition of typedef %q+D with different type", newdecl); + locate_old_decl (olddecl); + return false; + } + if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl) || TREE_NO_WARNING (newdecl) || TREE_NO_WARNING (olddecl)) return true; /* Allow OLDDECL to continue in use. */ - error ("redefinition of typedef %q+D", newdecl); - locate_old_decl (olddecl); - return false; + if (pedantic && !flag_isoc1x) + { + pedwarn (input_location, OPT_pedantic, + "redefinition of typedef %q+D", newdecl); + locate_old_decl (olddecl); + } + else if (variably_modified_type_p (newtype, NULL)) + { + /* Whether there is a constraint violation for the types not + being the same cannot be determined at compile time; a + warning that there may be one at runtime is considered + appropriate (WG14 reflector message 11743, 8 May 2009). */ + warning (0, "redefinition of typedef %q+D may be a constraint " + "violation at runtime", newdecl); + locate_old_decl (olddecl); + } + + return true; } /* Function declarations can either be 'static' or 'extern' (no |