aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/c-decl.c55
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/redecl-11.c9
-rw-r--r--gcc/testsuite/gcc.dg/redecl-12.c9
-rw-r--r--gcc/testsuite/gcc.dg/redecl-13.c9
-rw-r--r--gcc/testsuite/gcc.dg/redecl-14.c22
-rw-r--r--gcc/testsuite/gcc.dg/redecl-15.c14
8 files changed, 131 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 82d7ba0..ffdd2bb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index e7ac0d3..0ca4500 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 55605df..7dd2e19 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/redecl-11.c b/gcc/testsuite/gcc.dg/redecl-11.c
new file mode 100644
index 0000000..a0554d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-11.c
@@ -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'" } */
diff --git a/gcc/testsuite/gcc.dg/redecl-12.c b/gcc/testsuite/gcc.dg/redecl-12.c
new file mode 100644
index 0000000..cb1501d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-12.c
@@ -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'" } */
diff --git a/gcc/testsuite/gcc.dg/redecl-13.c b/gcc/testsuite/gcc.dg/redecl-13.c
new file mode 100644
index 0000000..54be4db
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-13.c
@@ -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'" } */
diff --git a/gcc/testsuite/gcc.dg/redecl-14.c b/gcc/testsuite/gcc.dg/redecl-14.c
new file mode 100644
index 0000000..ed19610
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-14.c
@@ -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'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/redecl-15.c b/gcc/testsuite/gcc.dg/redecl-15.c
new file mode 100644
index 0000000..c4ac76c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-15.c
@@ -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'" } */
+ }
+}