diff mbox

[C] Warn for _Alignas in an array declarator (PR c/58267)

Message ID 20131016113405.GC10967@redhat.com
State New
Headers show

Commit Message

Marek Polacek Oct. 16, 2013, 11:34 a.m. UTC
This PR is about _Alignas in contexts like
char x[_Alignas (int) 20];
C grammar does not allow _Alignas to be in an array declarator, yet we
don't issue any warning or an error.  This patch implements a pedwarn
for this.  I'm however highly unsure whether we want pedwarn, error, or
normal warning for this - currently we just DTRT and ignore the
_Alignas altogether.

Regtested/bootstrapped on x86_64-linux, ok for trunk?

2013-10-16  Marek Polacek  <polacek@redhat.com>

	PR c/58267
c/
	* c-parser.c (c_parser_direct_declarator_inner): Record whether
	_Alignas has been seen.
	* c-decl.c (build_array_declarator): Add alignas_p parameter.  Warn
	if _Alignas occurs in an array declarator.
	* c-tree.h (build_array_declarator): Adjust declaration.
testsuite/
	* gcc.dg/c1x-align-5.c: New test.


	Marek

Comments

Joseph Myers Oct. 16, 2013, 12:28 p.m. UTC | #1
On Wed, 16 Oct 2013, Marek Polacek wrote:

> This PR is about _Alignas in contexts like
> char x[_Alignas (int) 20];
> C grammar does not allow _Alignas to be in an array declarator, yet we
> don't issue any warning or an error.  This patch implements a pedwarn
> for this.  I'm however highly unsure whether we want pedwarn, error, or
> normal warning for this - currently we just DTRT and ignore the
> _Alignas altogether.

I think this should be an error.

I see this as a problem with how the parsing of array declarators uses 
c_parser_declspecs to parse a sequence of qualifiers and attributes, with 
scspec_ok=false and typespec_ok=false to ensure those kinds of specifiers 
can't occur in the list, but without any measure to exclude alignment 
specifiers.  That is, I think c_parser_declspecs should gain an argument 
specifying whether alignment specifiers are OK, and the relevant calls 
from c_parser_direct_declarator_inner would pass false for that argument, 
and uses of alignment specifiers here would result in parse errors.

(Incidentally, the comments in c-parser.c that are supposed to give the 
grammar accepted are missing the syntax of array-declarator.)

> --- gcc/testsuite/gcc.dg/c1x-align-5.c.mp	2013-10-16 11:11:16.432690963 +0200
> +++ gcc/testsuite/gcc.dg/c1x-align-5.c	2013-10-16 11:15:09.269514593 +0200
> @@ -0,0 +1,17 @@
> +/* Test C1X alignment support.  Test invalid code.  */
> +/* { dg-do compile } */
> +/* { dg-options "-std=c1x -pedantic-errors" } */
> +
> +static int
> +foo (int a[_Alignas (0) 10])	/* { dg-error "meaningless in array declarator" } */
> +{
> +  return a[0];
> +}
> +
> +int
> +main ()
> +{
> +  int a[_Alignas (int) 10];	/* { dg-error "meaningless in array declarator" } */
> +  foo (a);
> +  return 0;
> +}

I think this should also be tested after "static" (given that there are 
two separate calls to c_parser_declspecs involved), as well as in an 
abstract declarator.
diff mbox

Patch

--- gcc/c/c-tree.h.mp	2013-10-15 19:36:09.548670833 +0200
+++ gcc/c/c-tree.h	2013-10-15 19:36:25.003727398 +0200
@@ -480,8 +480,8 @@  extern void c_init_decl_processing (void
 extern void c_print_identifier (FILE *, tree, int);
 extern int quals_from_declspecs (const struct c_declspecs *);
 extern struct c_declarator *build_array_declarator (location_t, tree,
-    						    struct c_declspecs *,
-						    bool, bool);
+						    struct c_declspecs *,
+						    bool, bool, bool);
 extern tree build_enumerator (location_t, location_t, struct c_enum_contents *,
 			      tree, tree);
 extern tree check_for_loop_decls (location_t, bool);
--- gcc/c/c-parser.c.mp	2013-10-15 19:33:47.706150200 +0200
+++ gcc/c/c-parser.c	2013-10-15 19:35:57.557627164 +0200
@@ -3096,8 +3096,10 @@  c_parser_direct_declarator_inner (c_pars
       struct c_declspecs *quals_attrs = build_null_declspecs ();
       bool static_seen;
       bool star_seen;
+      bool alignas_seen;
       tree dimen;
       c_parser_consume_token (parser);
+      alignas_seen = c_parser_next_token_is_keyword (parser, RID_ALIGNAS);
       c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id);
       static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
       if (static_seen)
@@ -3169,7 +3171,8 @@  c_parser_direct_declarator_inner (c_pars
       if (dimen)
 	mark_exp_read (dimen);
       declarator = build_array_declarator (brace_loc, dimen, quals_attrs,
-					   static_seen, star_seen);
+					   static_seen, star_seen,
+					   alignas_seen);
       if (declarator == NULL)
 	return NULL;
       inner = set_array_declarator_inner (declarator, inner);
--- gcc/c/c-decl.c.mp	2013-10-15 19:35:30.172525717 +0200
+++ gcc/c/c-decl.c	2013-10-16 11:05:06.046383071 +0200
@@ -3866,7 +3866,7 @@  quals_from_declspecs (const struct c_dec
 struct c_declarator *
 build_array_declarator (location_t loc,
 			tree expr, struct c_declspecs *quals, bool static_p,
-			bool vla_unspec_p)
+			bool vla_unspec_p, bool alignas_p)
 {
   struct c_declarator *declarator = XOBNEW (&parser_obstack,
 					    struct c_declarator);
@@ -3908,6 +3908,9 @@  build_array_declarator (location_t loc,
 	}
       current_scope->had_vla_unspec = true;
     }
+  if (alignas_p)
+    pedwarn (loc, OPT_Wpedantic, "%<_Alignas%> meaningless in array "
+	     "declarator");
   return declarator;
 }
 
--- gcc/testsuite/gcc.dg/c1x-align-5.c.mp	2013-10-16 11:11:16.432690963 +0200
+++ gcc/testsuite/gcc.dg/c1x-align-5.c	2013-10-16 11:15:09.269514593 +0200
@@ -0,0 +1,17 @@ 
+/* Test C1X alignment support.  Test invalid code.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+static int
+foo (int a[_Alignas (0) 10])	/* { dg-error "meaningless in array declarator" } */
+{
+  return a[0];
+}
+
+int
+main ()
+{
+  int a[_Alignas (int) 10];	/* { dg-error "meaningless in array declarator" } */
+  foo (a);
+  return 0;
+}