aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-decl.c38
-rw-r--r--gcc/testsuite/gcc.dg/redecl-16.c18
3 files changed, 56 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cfdcdc8..f9e5d14 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-05-11 Richard Henderson <rth@redhat.com>
+
+ PR c/21502
+ * c-decl.c (finish_decl): Propagate the completed array type of
+ a global variable into the binding.
+
2005-05-10 Matt Kraai <kraai@ftbfs.org>
* Makefile.in (gtype-desc.o, build/genautomata.o)
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 0ca4500..6c9ab45 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -3275,11 +3275,13 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
/* Get the completed type made by complete_array_type. */
type = TREE_TYPE (decl);
- if (failure == 1)
- error ("%Jinitializer fails to determine size of %qD", decl, decl);
-
- else if (failure == 2)
+ switch (failure)
{
+ case 1:
+ error ("%Jinitializer fails to determine size of %qD", decl, decl);
+ break;
+
+ case 2:
if (do_default)
error ("%Jarray size missing in %qD", decl, decl);
/* If a `static' var's size isn't known,
@@ -3290,9 +3292,33 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
and it will get allocated. */
else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
DECL_EXTERNAL (decl) = 1;
+ break;
+
+ case 3:
+ error ("%Jzero or negative size array %qD", decl, decl);
+ break;
+
+ case 0:
+ /* For global variables, update the copy of the type that
+ exists in the binding. */
+ if (TREE_PUBLIC (decl))
+ {
+ struct c_binding *b_ext = I_SYMBOL_BINDING (DECL_NAME (decl));
+ while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext))
+ b_ext = b_ext->shadowed;
+ if (b_ext)
+ {
+ if (b_ext->type)
+ b_ext->type = composite_type (b_ext->type, type);
+ else
+ b_ext->type = type;
+ }
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
}
- else if (failure == 3)
- error ("%Jzero or negative size array %qD", decl, decl);
if (DECL_INITIAL (decl))
TREE_TYPE (DECL_INITIAL (decl)) = type;
diff --git a/gcc/testsuite/gcc.dg/redecl-16.c b/gcc/testsuite/gcc.dg/redecl-16.c
new file mode 100644
index 0000000..52941cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-16.c
@@ -0,0 +1,18 @@
+/* PR 21502 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+typedef int IA[];
+typedef int IA5[5];
+typedef int IA10[10];
+typedef IA *IAP;
+typedef IA5 *IA5P;
+typedef IA10 *IA10P;
+extern IAP a[];
+void
+f (void)
+{
+ extern IA5P a[];
+}
+IAP a[] = { 0 }; /* { dg-error "previous definition" } */
+extern IA10P a[]; /* { dg-error "conflicting types" } */