re PR c/21342 (some incompatible external declarations not diagnosed)

PR c/21342
	* c-decl.c (pushdecl): When there is a declaration in the current
	scope and the declarations are external linkage, check for
	compatibility with the type in the external scope and update the
	type in the external scope with the composite type information.
	Do not form a composite type of the new type and the visible type
	if they are incompatible.

testsuite:
	* gcc.dg/redecl-11.c, gcc.dg/redecl-12.c, gcc.dg/redecl-13.c,
	gcc.dg/redecl-14.c, gcc.dg/redecl-15.c: New tests.

From-SVN: r99510
This commit is contained in:
Joseph Myers 2005-05-10 13:38:34 +01:00 committed by Joseph Myers
parent 56d6849d89
commit 2798c11f46
8 changed files with 131 additions and 3 deletions

View file

@ -1,3 +1,13 @@
2005-05-10 Joseph S. Myers <joseph@codesourcery.com>
PR c/21342
* c-decl.c (pushdecl): When there is a declaration in the current
scope and the declarations are external linkage, check for
compatibility with the type in the external scope and update the
type in the external scope with the composite type information.
Do not form a composite type of the new type and the visible type
if they are incompatible.
2005-05-10 Nathan Sidwell <nathan@codesourcery.com>
* crtstuff.c: Revert part of 2005-05-08 Change.

View file

@ -2029,11 +2029,52 @@ pushdecl (tree x)
b = I_SYMBOL_BINDING (name);
if (b && B_IN_SCOPE (b, scope))
{
struct c_binding *b_ext, *b_use;
tree type = TREE_TYPE (x);
tree visdecl = b->decl;
tree vistype = TREE_TYPE (visdecl);
if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
&& COMPLETE_TYPE_P (TREE_TYPE (x)))
b->inner_comp = false;
if (duplicate_decls (x, b->decl))
return b->decl;
b_use = b;
b_ext = b;
/* If this is an external linkage declaration, we should check
for compatibility with the type in the external scope before
setting the type at this scope based on the visible
information only. */
if (TREE_PUBLIC (x) && TREE_PUBLIC (visdecl))
{
while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext))
b_ext = b_ext->shadowed;
if (b_ext)
{
b_use = b_ext;
if (b_use->type)
TREE_TYPE (b_use->decl) = b_use->type;
}
}
if (duplicate_decls (x, b_use->decl))
{
if (b_use != b)
{
/* Save the updated type in the external scope and
restore the proper type for this scope. */
tree thistype;
if (comptypes (vistype, type))
thistype = composite_type (vistype, type);
else
thistype = TREE_TYPE (b_use->decl);
b_use->type = TREE_TYPE (b_use->decl);
if (TREE_CODE (b_use->decl) == FUNCTION_DECL
&& DECL_BUILT_IN (b_use->decl))
thistype
= build_type_attribute_variant (thistype,
TYPE_ATTRIBUTES
(b_use->type));
TREE_TYPE (b_use->decl) = thistype;
}
return b_use->decl;
}
else
goto skip_external_and_shadow_checks;
}
@ -2120,7 +2161,15 @@ pushdecl (tree x)
&& duplicate_decls (x, b->decl))
{
tree thistype;
thistype = (vistype ? composite_type (vistype, type) : type);
if (vistype)
{
if (comptypes (vistype, type))
thistype = composite_type (vistype, type);
else
thistype = TREE_TYPE (b->decl);
}
else
thistype = type;
b->type = TREE_TYPE (b->decl);
if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl))
thistype

View file

@ -1,3 +1,9 @@
2005-05-10 Joseph S. Myers <joseph@codesourcery.com>
PR c/21342
* gcc.dg/redecl-11.c, gcc.dg/redecl-12.c, gcc.dg/redecl-13.c,
gcc.dg/redecl-14.c, gcc.dg/redecl-15.c: New tests.
2005-05-10 Ben Elliston <bje@au.ibm.com>
PR debug/16676

View file

@ -0,0 +1,9 @@
/* Some incompatible external linkage declarations were not diagnosed.
Bug 21342. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "" } */
int f(int (*)[]);
void g() { int f(int (*)[2]); } /* { dg-error "error: previous declaration of 'f' was here" } */
int f(int (*)[3]); /* { dg-error "error: conflicting types for 'f'" } */

View file

@ -0,0 +1,9 @@
/* Some incompatible external linkage declarations were not diagnosed.
Bug 21342. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "" } */
extern int a[];
void f(void) { extern int a[]; extern int a[10]; } /* { dg-error "error: previous declaration of 'a' was here" } */
extern int a[5]; /* { dg-error "error: conflicting types for 'a'" } */

View file

@ -0,0 +1,9 @@
/* Some incompatible external linkage declarations were not diagnosed.
Bug 21342. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "" } */
extern int a[];
void f(void) { extern int a[10]; } /* { dg-error "error: previous declaration of 'a' was here" } */
extern int a[5]; /* { dg-error "error: conflicting types for 'a'" } */

View file

@ -0,0 +1,22 @@
/* Some incompatible external linkage declarations were not diagnosed.
Bug 21342. Test type in inner scope is correct. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "" } */
typedef int IA[];
typedef int IA5[5];
typedef IA *IAP;
typedef IA5 *IA5P;
extern IAP a[];
void
f (void)
{
{
extern IA5P a[];
sizeof (*a[0]);
}
extern IAP a[];
extern IAP a[5];
sizeof (*a[0]); /* { dg-error "error: invalid application of 'sizeof' to incomplete type 'IA'" } */
}

View file

@ -0,0 +1,14 @@
/* Test for ICE with redeclaration in inner scope which is accepted
despite incompatible type. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-options "" } */
void
f (void)
{
g(); /* { dg-warning "warning: previous implicit declaration of 'g' was here" } */
{
void g(); /* { dg-warning "warning: conflicting types for 'g'" } */
}
}