This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR c/29129 (C99 [*] array declarators errors)


This patch fixes PR c/29129, a regression from the implementation of
C99 [*] array declarators (VLA of unknown size in function prototype)
that was suspended while waiting for issues with the standard to be
resolved (DR#341).

The original intent was agreed by the committee to have been that [*]
could be used as part of the abstract declarator for an unnamed
parameter, but not when merely lexically inside the function prototype
(as in casts or sizeof).  The committee did not however like the
wording I proposed to bring this into effect, and the final agreed
wording instead gives scopes to all type names, meaning that the case
of [*] merely lexically inside a function prototype is in fact valid.

As the relevant requirements are in a Semantics section not
Constraints, there is certainly no requirement for them to be
diagnosed, whatever the exact rules are meant to be on what is or is
not valid.  I took the approach of giving a warning, not an error, for
the questionable cases of type names other than unnamed parameters
using [*], similar to the warning given for structure tags with
function prototype scope, and made sure the type was properly treated
as a VLA type in this case.  This warning replaces a previous error
specific to sizeof (that was not effective in general because it only
checked the outermost declarator representing the first stage of type
derivation, not all the declarators in the nested sequence).

Bootstrapped with no regressions on i686-pc-linux-gnu.  Applied to
mainline.  I won't backport this to 4.3 branch because of the risk
associated with adding new warnings for previously missing cases on a
release branch.

2009-02-03  Joseph Myers  <joseph@codesourcery.com>

	PR c/29129
	* c-decl.c (grokdeclarator): Mark [*] arrays in field declarators
	as having variable size.  Do not give an error for unnamed
	parameters with [*] declarators.  Give a warning for type names
	with [*] declarators and mark them as variable size.
	* c-parser.c (c_parser_sizeof_expression): Do not give an error
	for sizeof applied to [*] type names.

testsuite:
2009-02-03  Joseph Myers  <joseph@codesourcery.com>

	PR c/29129
	* c90-arraydecl-1.c: Do not expect error for [*] in abstract
	declarator.
	* vla-6.c: Likewise.  Expect warning not error for [*] lexically
	inside function prototype but not part of parameter declarator.
	* vla-11.c: New test.

Index: c-decl.c
===================================================================
--- c-decl.c	(revision 143890)
+++ c-decl.c	(working copy)
@@ -4389,7 +4389,14 @@
 	      }
 	    else if (decl_context == FIELD)
 	      {
-		if (pedantic && !flag_isoc99 && !in_system_header)
+		if (array_parm_vla_unspec_p)
+		  /* Field names can in fact have function prototype
+		     scope so [*] is disallowed here through making
+		     the field variably modified, not through being
+		     something other than a declaration with function
+		     prototype scope.  */
+		  size_varies = 1;
+		else if (pedantic && !flag_isoc99 && !in_system_header)
 		  pedwarn (input_location, OPT_pedantic,
 			   "ISO C90 does not support flexible array members");
 
@@ -4401,12 +4408,6 @@
 	      {
 		if (array_parm_vla_unspec_p)
 		  {
-		    if (! orig_name)
-		      {
-			/* C99 6.7.5.2p4 */
-			error ("%<[*]%> not allowed in other than a declaration");
-		      }
-
 		    itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
 		    size_varies = 1;
 		  }
@@ -4415,12 +4416,14 @@
 	      {
 		if (array_parm_vla_unspec_p)
 		  {
-		    /* The error is printed elsewhere.  We use this to
-		       avoid messing up with incomplete array types of
-		       the same type, that would otherwise be modified
-		       below.  */
+		    /* C99 6.7.5.2p4 */
+		    warning (0, "%<[*]%> not in a declaration");
+		    /* We use this to avoid messing up with incomplete
+		       array types of the same type, that would
+		       otherwise be modified below.  */
 		    itype = build_range_type (sizetype, size_zero_node,
 					      NULL_TREE);
+		    size_varies = 1;
 		  }
 	      }
 
Index: c-parser.c
===================================================================
--- c-parser.c	(revision 143890)
+++ c-parser.c	(working copy)
@@ -4949,13 +4949,6 @@
       /* sizeof ( type-name ).  */
       skip_evaluation--;
       in_sizeof--;
-      if (type_name->declarator->kind == cdk_array
-	  && type_name->declarator->u.array.vla_unspec_p)
-	{
-	  /* C99 6.7.5.2p4 */
-	  error_at (expr_loc,
-		    "%<[*]%> not allowed in other than a declaration");
-	}
       return c_expr_sizeof_type (type_name);
     }
   else
Index: testsuite/gcc.dg/c90-arraydecl-1.c
===================================================================
--- testsuite/gcc.dg/c90-arraydecl-1.c	(revision 143890)
+++ testsuite/gcc.dg/c90-arraydecl-1.c	(working copy)
@@ -10,8 +10,8 @@
 
 void foo0 (int a, int b[*]); /* { dg-error "ISO C90" "\[*\] not in C90" } */
 void foo1 (int, int [*]); /* { dg-error "ISO C90" "\[*\] not in C90" } */
-/* { dg-error "allowed" "\'\[*\]\' not allowed in other than a declaration" { target *-*-* } 12 } */
 
+
 /* Use of static and type qualifiers (not allowed with abstract declarators)
    is a C99 feature.  */
 
Index: testsuite/gcc.dg/vla-11.c
===================================================================
--- testsuite/gcc.dg/vla-11.c	(revision 0)
+++ testsuite/gcc.dg/vla-11.c	(revision 0)
@@ -0,0 +1,13 @@
+/* Further tests of [*] being rejected other that in declarations, as
+   per the consensus in DR#341 that the second example there should be
+   invalid (but warnings because the final wording appears to allow
+   these cases).  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+void foo11a(int x[sizeof(int *(*)[*])]);	/* { dg-warning "not in a declaration" } */
+void foo11b(__SIZE_TYPE__ x, int y[(__SIZE_TYPE__)(int (*)[*])x]);	/* { dg-warning "not in a declaration" } */
+void foo11c(struct s { int (*x)[*]; } *y);	/* { dg-error "a member of a structure or union cannot have a variably modified type" "variably modified" } */
+/* { dg-warning "'struct s' declared inside parameter list" "struct decl" { target *-*-* } 11 } */
+/* { dg-warning "its scope is only this definition or declaration" "struct scope" { target *-*-* } 11 } */
Index: testsuite/gcc.dg/vla-6.c
===================================================================
--- testsuite/gcc.dg/vla-6.c	(revision 143890)
+++ testsuite/gcc.dg/vla-6.c	(working copy)
@@ -7,9 +7,12 @@
 void foo4(int o[*][4]) { }	/* { dg-error "not allowed in other than function prototype scope" } */
 void foo5(int o[4][*]) { }	/* { dg-error "not allowed in other than function prototype scope" } */
 
-/* [*] can't be used in a type that's not a declaration */
-void foo11(int x[sizeof(int (*)[*])]);	/* { dg-error "not allowed in other than a declaration" } */
-void foo12(int [*]);		/* { dg-error "not allowed in other than a declaration" } */
+/* [*] can't be used in a type that's not a declaration (maybe, the
+   final wording for DR#341 would allow it although the first
+   discussed intent would not).  */
+void foo11(int x[sizeof(int (*)[*])]);	/* { dg-warning "not in a declaration" } */
+/* This case is allowed per DR#341.  */
+void foo12(int [*]);
 
 extern int n;
 int B[100];

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]