Commit dc5027f4 by Joseph Myers Committed by Joseph Myers

c-decl.c (diagnose_mismatched_decls): Give error for duplicate typedefs with…

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
parent 8f9e812d
2010-05-23 Joseph Myers <joseph@codesourcery.com>
* 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.
2010-05-23 Steven Bosscher <steven@gcc.gnu.org>
* regs.h: Do not include obstack.h, basic-block.h.
......
......@@ -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
......
......@@ -506,6 +506,7 @@ extern tree c_objc_common_truthvalue_conversion (location_t, tree);
extern tree require_complete_type (tree);
extern int same_translation_unit_p (const_tree, const_tree);
extern int comptypes (tree, tree);
extern int comptypes_check_different_types (tree, tree, bool *);
extern bool c_vla_type_p (const_tree);
extern bool c_mark_addressable (tree);
extern void c_incomplete_type_error (const_tree, const_tree);
......
2010-05-23 Joseph Myers <joseph@codesourcery.com>
* 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.
2010-05-23 H.J. Lu <hongjiu.lu@intel.com>
* gcc.c-target/pr43869.c: Move "dg-do run" before lp64.
......
/* Test typedef redeclaration in C1X. */
/* { dg-do compile } */
/* { dg-options "-std=c1x -pedantic-errors" } */
/* C1X permits typedefs to be redeclared to the same type, but not to
different-but-compatible types. */
#include <limits.h>
typedef int TI;
typedef int TI2;
typedef TI2 TI;
typedef TI TI2;
enum e { E1 = 0, E2 = INT_MAX, E3 = -1 };
typedef enum e TE;
typedef enum e TE; /* { dg-message "previous declaration" } */
typedef int TE; /* { dg-error "with different type" } */
struct s;
typedef struct s TS;
struct s { int i; };
typedef struct s TS;
typedef int IA[];
typedef TI2 IA[]; /* { dg-message "previous declaration" } */
typedef int A2[2];
typedef TI A2[2]; /* { dg-message "previous declaration" } */
typedef IA A2; /* { dg-error "with different type" } */
typedef int A3[3];
typedef A3 IA; /* { dg-error "with different type" } */
typedef void F(int);
typedef void F(TI); /* { dg-message "previous declaration" } */
typedef void F(enum e); /* { dg-error "with different type" } */
typedef int G(void);
typedef TI G(void); /* { dg-message "previous declaration" } */
typedef enum e G(void); /* { dg-error "with different type" } */
typedef int *P;
typedef TI *P; /* { dg-message "previous declaration" } */
typedef enum e *P; /* { dg-error "with different type" } */
typedef void F2();
typedef void F2(); /* { dg-message "previous declaration" } */
typedef void F2(int); /* { dg-error "with different type" } */
void
f (void)
{
int a = 1;
int b = 2;
typedef void FN(int (*p)[a]);
typedef void FN(int (*p)[b]);
typedef void FN(int (*p)[*]); /* { dg-message "previous declaration" } */
typedef void FN(int (*p)[1]); /* { dg-error "with different type" } */
typedef void FN2(int (*p)[a]);
typedef void FN2(int (*p)[b]);
typedef void FN2(int (*p)[*]); /* { dg-message "previous declaration" } */
typedef void FN2(int (*p)[]); /* { dg-error "with different type" } */
typedef int AV[a]; /* { dg-message "previous declaration" } */
typedef int AV[b-1]; /* { dg-warning "may be a constraint violation at runtime" } */
typedef int AAa[a];
typedef int AAb[b-1];
typedef AAa *VF(void); /* { dg-message "previous declaration" } */
typedef AAb *VF(void); /* { dg-warning "may be a constraint violation at runtime" } */
}
/* Test typedef redeclaration in C1X. Side effects from duplicate
declarations still apply. */
/* { dg-do run } */
/* { dg-options "-std=c1x -pedantic-errors" } */
extern void exit (int);
extern void abort (void);
int
main (void)
{
int a = 1, b = 1;
typedef int T[++a]; /* { dg-message "previous declaration" } */
typedef int T[++b]; /* { dg-warning "may be a constraint violation at runtime" } */
if (a != 2 || b != 2)
abort ();
exit (0);
}
/* Test typedef redeclaration not permitted in C90. */
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
typedef int TI; /* { dg-message "previous declaration" } */
typedef int TI; /* { dg-error "redefinition of typedef" } */
/* Test typedef redeclaration not permitted in C99. */
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
typedef int TI; /* { dg-message "previous declaration" } */
typedef int TI; /* { dg-error "redefinition of typedef" } */
/* Test diagnostics for duplicate typedefs. Basic diagnostics. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "" } */
/* { dg-options "-std=gnu89 -pedantic-errors" } */
typedef int I; /* { dg-message "note: previous declaration of 'I' was here" } */
typedef int I; /* { dg-error "redefinition of typedef 'I'" } */
......
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