aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-parser.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2011-11-06 23:51:19 +0000
committerJoseph Myers <jsm28@gcc.gnu.org>2011-11-06 23:51:19 +0000
commitd19fa6b5f1372429e56c2d4f8d384ed388a22d21 (patch)
tree665bdd624cc911e728a962281f278e5fbf2aefce /gcc/c-parser.c
parent55d2e499d693df45f3065f8bf9f654fd816ae0fb (diff)
downloadgcc-d19fa6b5f1372429e56c2d4f8d384ed388a22d21.zip
gcc-d19fa6b5f1372429e56c2d4f8d384ed388a22d21.tar.gz
gcc-d19fa6b5f1372429e56c2d4f8d384ed388a22d21.tar.bz2
c-decl.c (shadow_tag_warned, [...]): Handle _Alignas specifiers.
* c-decl.c (shadow_tag_warned, grokdeclarator): Handle _Alignas specifiers. (build_null_declspecs): Initialize align_log and alignas_p fields. (declspecs_add_alignas): New. * c-parser.c (c_token_starts_declspecs): Handle RID_ALIGNAS. (c_parser_declspecs): Handle _Alignas specifiers. (c_parser_alignas_specifier): New. (c_parser_alignof_expression): Diagnose alignof use for non-C1X. Diagnose _Alignof (expression). * c-tree.h (struct c_declspecs): Add align_log and alignas_p fields. (declspecs_add_alignas): Declare. * ginclude/stddef.h (max_align_t): Define for C1X and C++11. * ginclude/stdalign.h: New. * Makefile.in (USER_H): Add stdalign.h. c-family: * c-common.c (c_common_reswords): Add _Alignas and _Alignof. (c_sizeof_or_alignof_type): Diagnose alignof applied to a function type. (check_user_alignment): New. Split out of handle_aligned_attribute. Disallow integer constants with noninteger types. Conditionally allow zero. (handle_aligned_attribute): Use check_user_alignment. * c-common.h (RID_ALIGNAS, check_user_alignment): New. testsuite: * g++.dg/cpp0x/alignof3.C, gcc.dg/c1x-align-1.c, gcc.dg/c1x-align-2.c, gcc.dg/c1x-align-3.c, gcc.dg/c1x-align-4.c, gcc.dg/c90-align-1.c, gcc.dg/c99-align-1.c: New tests. * gcc.dg/gnu89-const-expr-1.c, gcc.dg/gnu90-const-expr-1.c, gcc.dg/gnu99-const-expr-1.c, gcc.dg/gnu99-static-1.c: Update expected diagnostics. From-SVN: r181048
Diffstat (limited to 'gcc/c-parser.c')
-rw-r--r--gcc/c-parser.c68
1 files changed, 67 insertions, 1 deletions
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 8db203a..58bcb02 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -650,6 +650,7 @@ c_token_starts_declspecs (c_token *token)
case RID_FRACT:
case RID_ACCUM:
case RID_SAT:
+ case RID_ALIGNAS:
return true;
default:
return false;
@@ -1120,6 +1121,7 @@ static struct c_typespec c_parser_enum_specifier (c_parser *);
static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
static tree c_parser_struct_declaration (c_parser *);
static struct c_typespec c_parser_typeof_specifier (c_parser *);
+static tree c_parser_alignas_specifier (c_parser *);
static struct c_declarator *c_parser_declarator (c_parser *, bool, c_dtr_syn,
bool *);
static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
@@ -1890,9 +1892,11 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
type-specifier declaration-specifiers[opt]
type-qualifier declaration-specifiers[opt]
function-specifier declaration-specifiers[opt]
+ alignment-specifier declaration-specifiers[opt]
Function specifiers (inline) are from C99, and are currently
- handled as storage class specifiers, as is __thread.
+ handled as storage class specifiers, as is __thread. Alignment
+ specifiers are from C1X.
C90 6.5.1, C99 6.7.1:
storage-class-specifier:
@@ -1991,6 +1995,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
{
struct c_typespec t;
tree attrs;
+ tree align;
location_t loc = c_parser_peek_token (parser)->location;
/* If we cannot accept a type, exit if the next token must start
@@ -2169,6 +2174,10 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
attrs = c_parser_attributes (parser);
declspecs_add_attrs (specs, attrs);
break;
+ case RID_ALIGNAS:
+ align = c_parser_alignas_specifier (parser);
+ declspecs_add_alignas (specs, align);
+ break;
default:
goto out;
}
@@ -2751,6 +2760,45 @@ c_parser_typeof_specifier (c_parser *parser)
return ret;
}
+/* Parse an alignment-specifier.
+
+ C1X 6.7.5:
+
+ alignment-specifier:
+ _Alignas ( type-name )
+ _Alignas ( constant-expression )
+*/
+
+static tree
+c_parser_alignas_specifier (c_parser * parser)
+{
+ tree ret = error_mark_node;
+ location_t loc = c_parser_peek_token (parser)->location;
+ gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
+ c_parser_consume_token (parser);
+ if (!flag_isoc1x)
+ {
+ if (flag_isoc99)
+ pedwarn (loc, OPT_pedantic,
+ "ISO C99 does not support %<_Alignas%>");
+ else
+ pedwarn (loc, OPT_pedantic,
+ "ISO C90 does not support %<_Alignas%>");
+ }
+ if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ return ret;
+ if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
+ {
+ struct c_type_name *type = c_parser_type_name (parser);
+ if (type != NULL)
+ ret = c_alignof (loc, groktypename (type, NULL, NULL));
+ }
+ else
+ ret = c_parser_expr_no_commas (parser, NULL).value;
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+ return ret;
+}
+
/* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
6.5.5, C99 6.7.5, 6.7.6). If TYPE_SEEN_P then a typedef name may
be redeclared; otherwise it may not. KIND indicates which kind of
@@ -5759,6 +5807,8 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
__alignof__ ( type-name )
&& identifier
+ (C1X permits _Alignof with type names only.)
+
unary-operator: one of
__extension__ __real__ __imag__
@@ -5942,7 +5992,21 @@ c_parser_alignof_expression (c_parser *parser)
{
struct c_expr expr;
location_t loc = c_parser_peek_token (parser)->location;
+ tree alignof_spelling = c_parser_peek_token (parser)->value;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
+ /* A diagnostic is not required for the use of this identifier in
+ the implementation namespace; only diagnose it for the C1X
+ spelling because of existing code using the other spellings. */
+ if (!flag_isoc1x
+ && strcmp (IDENTIFIER_POINTER (alignof_spelling), "_Alignof") == 0)
+ {
+ if (flag_isoc99)
+ pedwarn (loc, OPT_pedantic, "ISO C99 does not support %qE",
+ alignof_spelling);
+ else
+ pedwarn (loc, OPT_pedantic, "ISO C90 does not support %qE",
+ alignof_spelling);
+ }
c_parser_consume_token (parser);
c_inhibit_evaluation_warnings++;
in_alignof++;
@@ -5991,6 +6055,8 @@ c_parser_alignof_expression (c_parser *parser)
mark_exp_read (expr.value);
c_inhibit_evaluation_warnings--;
in_alignof--;
+ pedwarn (loc, OPT_pedantic, "ISO C does not allow %<%E (expression)%>",
+ alignof_spelling);
ret.value = c_alignof_expr (loc, expr.value);
ret.original_code = ERROR_MARK;
ret.original_type = NULL;