+2011-11-06 Joseph Myers <joseph@codesourcery.com>
+
+ * 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.
+
2011-11-06 Joern Rennecke <joern.rennecke@embecosm.com>
Eric Botcazou <ebotcazou@adacore.com>
$(srcdir)/ginclude/varargs.h \
$(srcdir)/ginclude/stdfix.h \
$(srcdir)/ginclude/stdnoreturn.h \
+ $(srcdir)/ginclude/stdalign.h \
$(EXTRA_HEADERS)
USER_H_INC_NEXT_PRE = @user_headers_inc_next_pre@
warned = 1;
pending_xref_error ();
}
+ else if (declspecs->typespec_kind != ctsk_tagdef
+ && declspecs->typespec_kind != ctsk_tagfirstref
+ && declspecs->alignas_p)
+ {
+ if (warned != 1)
+ pedwarn (input_location, 0,
+ "empty declaration with %<_Alignas%> "
+ "does not redeclare tag");
+ warned = 1;
+ pending_xref_error ();
+ }
else
{
pending_invalid_xref = 0;
warned = 2;
}
+ if (!warned && !in_system_header && declspecs->alignas_p)
+ {
+ warning (0, "useless %<_Alignas%> in empty declaration");
+ warned = 2;
+ }
+
if (warned != 1)
{
if (!found_tag)
tree expr_dummy;
bool expr_const_operands_dummy;
enum c_declarator_kind first_non_attr_kind;
+ unsigned int alignas_align = 0;
if (TREE_CODE (type) == ERROR_MARK)
return error_mark_node;
if (bitfield)
check_bitfield_type_and_width (&type, width, name);
+ /* Reject invalid uses of _Alignas. */
+ if (declspecs->alignas_p)
+ {
+ if (storage_class == csc_typedef)
+ error_at (loc, "alignment specified for typedef %qE", name);
+ else if (storage_class == csc_register)
+ error_at (loc, "alignment specified for %<register%> object %qE",
+ name);
+ else if (decl_context == PARM)
+ {
+ if (name)
+ error_at (loc, "alignment specified for parameter %qE", name);
+ else
+ error_at (loc, "alignment specified for unnamed parameter");
+ }
+ else if (bitfield)
+ {
+ if (name)
+ error_at (loc, "alignment specified for bit-field %qE", name);
+ else
+ error_at (loc, "alignment specified for unnamed bit-field");
+ }
+ else if (TREE_CODE (type) == FUNCTION_TYPE)
+ error_at (loc, "alignment specified for function %qE", name);
+ else if (declspecs->align_log != -1)
+ {
+ alignas_align = 1U << declspecs->align_log;
+ if (alignas_align < TYPE_ALIGN_UNIT (type))
+ {
+ if (name)
+ error_at (loc, "%<_Alignas%> specifiers cannot reduce "
+ "alignment of %qE", name);
+ else
+ error_at (loc, "%<_Alignas%> specifiers cannot reduce "
+ "alignment of unnamed field");
+ alignas_align = 0;
+ }
+ }
+ }
+
/* Did array size calculations overflow? */
if (TREE_CODE (type) == ARRAY_TYPE
/* Record constancy and volatility. */
c_apply_type_quals_to_decl (type_quals, decl);
+ /* Apply _Alignas specifiers. */
+ if (alignas_align)
+ {
+ DECL_ALIGN (decl) = alignas_align * BITS_PER_UNIT;
+ DECL_USER_ALIGN (decl) = 1;
+ }
+
/* If a type has volatile components, it should be stored in memory.
Otherwise, the fact that those components are volatile
will be ignored, and would even crash the compiler.
ret->expr = 0;
ret->decl_attr = 0;
ret->attrs = 0;
+ ret->align_log = -1;
ret->typespec_word = cts_none;
ret->storage_class = csc_none;
ret->expr_const_operands = true;
ret->volatile_p = false;
ret->restrict_p = false;
ret->saturating_p = false;
+ ret->alignas_p = false;
ret->address_space = ADDR_SPACE_GENERIC;
return ret;
}
return specs;
}
+/* Add an _Alignas specifier (expression ALIGN, or type whose
+ alignment is ALIGN) to the declaration specifiers SPECS, returning
+ SPECS. */
+struct c_declspecs *
+declspecs_add_alignas (struct c_declspecs *specs, tree align)
+{
+ int align_log;
+ specs->alignas_p = true;
+ if (align == error_mark_node)
+ return specs;
+ align_log = check_user_alignment (align, true);
+ if (align_log > specs->align_log)
+ specs->align_log = align_log;
+ return specs;
+}
+
/* Combine "long", "short", "signed", "unsigned" and "_Complex" type
specifiers with any other type specifier to determine the resulting
type. This is where ISO C checks on complex types are made, since
+2011-11-06 Joseph Myers <joseph@codesourcery.com>
+
+ * 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.
+
2011-11-06 Andrew MacLeod <amacleod@redhat.com>
Richard Henderson <rth@redhat.com>
*/
const struct c_common_resword c_common_reswords[] =
{
+ { "_Alignas", RID_ALIGNAS, D_CONLY },
+ { "_Alignof", RID_ALIGNOF, D_CONLY },
{ "_Bool", RID_BOOL, D_CONLY },
{ "_Complex", RID_COMPLEX, 0 },
{ "_Imaginary", RID_IMAGINARY, D_CONLY },
value = size_one_node;
}
else
- value = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
+ {
+ if (complain)
+ {
+ if (c_dialect_cxx ())
+ pedwarn (loc, OPT_pedantic, "ISO C++ does not permit "
+ "%<alignof%> applied to a function type");
+ else
+ pedwarn (loc, OPT_pedantic, "ISO C does not permit "
+ "%<_Alignof%> applied to a function type");
+ }
+ value = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
+ }
}
else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
{
return NULL_TREE;
}
+/* Check whether ALIGN is a valid user-specified alignment. If so,
+ return its base-2 log; if not, output an error and return -1. If
+ ALLOW_ZERO then 0 is valid and should result in a return of -1 with
+ no error. */
+int
+check_user_alignment (const_tree align, bool allow_zero)
+{
+ int i;
+
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (align))
+ || TREE_CODE (align) != INTEGER_CST)
+ {
+ error ("requested alignment is not an integer constant");
+ return -1;
+ }
+ else if (allow_zero && integer_zerop (align))
+ return -1;
+ else if ((i = tree_log2 (align)) == -1)
+ {
+ error ("requested alignment is not a power of 2");
+ return -1;
+ }
+ else if (i >= HOST_BITS_PER_INT - BITS_PER_UNIT_LOG)
+ {
+ error ("requested alignment is too large");
+ return -1;
+ }
+ return i;
+}
+
/* Handle a "aligned" attribute; arguments as in
struct attribute_spec.handler. */
else if (TYPE_P (*node))
type = node, is_type = 1;
- if (TREE_CODE (align_expr) != INTEGER_CST)
- {
- error ("requested alignment is not a constant");
- *no_add_attrs = true;
- }
- else if ((i = tree_log2 (align_expr)) == -1)
- {
- error ("requested alignment is not a power of 2");
- *no_add_attrs = true;
- }
- else if (i >= HOST_BITS_PER_INT - BITS_PER_UNIT_LOG)
- {
- error ("requested alignment is too large");
- *no_add_attrs = true;
- }
+ if ((i = check_user_alignment (align_expr, false)) == -1)
+ *no_add_attrs = true;
else if (is_type)
{
if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
RID_FRACT, RID_ACCUM,
+ /* C1X */
+ RID_ALIGNAS,
+
/* This means to warn that this is a C++ keyword, and then treat it
as a normal identifier. */
RID_CXX_COMPAT_WARN,
extern const char *fname_as_string (int);
extern tree fname_decl (location_t, unsigned, tree);
+extern int check_user_alignment (const_tree, bool);
extern void check_function_arguments (const_tree, int, tree *);
extern void check_function_arguments_recurse (void (*)
(void *, tree,
case RID_FRACT:
case RID_ACCUM:
case RID_SAT:
+ case RID_ALIGNAS:
return true;
default:
return false;
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,
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:
{
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
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;
}
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
__alignof__ ( type-name )
&& identifier
+ (C1X permits _Alignof with type names only.)
+
unary-operator: one of
__extension__ __real__ __imag__
{
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++;
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;
NULL; attributes (possibly from multiple lists) will be passed
separately. */
tree attrs;
+ /* The base-2 log of the greatest alignment required by an _Alignas
+ specifier, in bytes, or -1 if no such specifiers with nonzero
+ alignment. */
+ int align_log;
/* The storage class specifier, or csc_none if none. */
enum c_storage_class storage_class;
/* Any type specifier keyword used such as "int", not reflecting
BOOL_BITFIELD restrict_p : 1;
/* Whether "_Sat" was specified. */
BOOL_BITFIELD saturating_p : 1;
+ /* Whether any alignment specifier (even with zero alignment) was
+ specified. */
+ BOOL_BITFIELD alignas_p : 1;
/* The address space that the declaration belongs to. */
addr_space_t address_space;
};
extern struct c_declspecs *declspecs_add_attrs (struct c_declspecs *, tree);
extern struct c_declspecs *declspecs_add_addrspace (struct c_declspecs *,
addr_space_t);
+extern struct c_declspecs *declspecs_add_alignas (struct c_declspecs *, tree);
extern struct c_declspecs *finish_declspecs (struct c_declspecs *);
/* in c-objc-common.c */
--- /dev/null
+/* Copyright (C) 2011 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* ISO C1X: 7.15 Alignment <stdalign.h>. */
+
+#ifndef _STDALIGN_H
+#define _STDALIGN_H
+
+#ifndef __cplusplus
+
+#define alignas _Alignas
+#define alignof _Alignof
+
+#define __alignas_is_defined 1
+#define __alignof_is_defined 1
+
+#endif
+
+#endif /* stdalign.h */
-/* Copyright (C) 1989, 1997, 1998, 1999, 2000, 2002, 2004, 2009
+/* Copyright (C) 1989, 1997, 1998, 1999, 2000, 2002, 2004, 2009, 2011
Free Software Foundation, Inc.
This file is part of GCC.
/* Offset of member MEMBER in a struct of type TYPE. */
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+#if (defined (__STDC_VERSION__) && __STDC_VERSION__ > 199901L) \
+ || (defined(__cplusplus) && __cplusplus >= 201103L)
+#ifndef _GCC_MAX_ALIGN_T
+#define _GCC_MAX_ALIGN_T
+/* Type whose alignment is supported in every context and is at least
+ as great as that of any standard type not using alignment
+ specifiers. */
+typedef struct {
+ long long __max_align_ll __attribute__((__aligned__(__alignof__(long long))));
+ long double __max_align_ld __attribute__((__aligned__(__alignof__(long double))));
+} max_align_t;
+#endif
+#endif /* C1X or C++11. */
+
#endif /* _STDDEF_H was defined this time */
#endif /* !_STDDEF_H && !_STDDEF_H_ && !_ANSI_STDDEF_H && !__STDDEF_H__
+2011-11-06 Joseph Myers <joseph@codesourcery.com>
+
+ * 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.
+
2011-11-06 Andrew MacLeod <amacleod@redhat.com>
Richard Henderson <rth@redhat.com>
Aldy Hernandez <aldyh@redhat.com>
--- /dev/null
+// { dg-do compile }
+// { dg-options "-std=c++0x -pedantic" }
+int main(void)
+{
+ alignof(void (void)); // { dg-warning "function type" }
+}
--- /dev/null
+/* Test C1X alignment support. Test valid code. */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+#include <stddef.h>
+
+_Alignas (_Alignof (max_align_t)) char c;
+extern _Alignas (max_align_t) char c;
+extern char c;
+
+extern _Alignas (max_align_t) short s;
+_Alignas (max_align_t) short s;
+
+_Alignas (int) int i;
+extern int i;
+
+_Alignas (max_align_t) long l;
+
+_Alignas (max_align_t) long long ll;
+
+_Alignas (max_align_t) float f;
+
+_Alignas (max_align_t) double d;
+
+_Alignas (max_align_t) _Complex long double cld;
+
+_Alignas (0) _Alignas (int) _Alignas (char) char ca[10];
+
+_Alignas ((int) _Alignof (max_align_t) + 0) int x;
+
+enum e { E = _Alignof (max_align_t) };
+_Alignas (E) int y;
+
+void
+func (void)
+{
+ _Alignas (max_align_t) long long auto_ll;
+}
+
+/* Valid, but useless. */
+_Alignas (0) struct s; /* { dg-warning "useless" } */
--- /dev/null
+/* Test C1X alignment support. Test valid code using stdalign.h. */
+/* { dg-do run } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+#include <stdalign.h>
+#include <stddef.h>
+
+extern int strcmp (const char *, const char *);
+
+extern void exit (int);
+extern void abort (void);
+
+alignas (alignof (max_align_t)) char c;
+extern alignas (max_align_t) char c;
+extern char c;
+
+extern alignas (max_align_t) short s;
+alignas (max_align_t) short s;
+
+alignas (int) int i;
+extern int i;
+
+alignas (max_align_t) long l;
+
+alignas (max_align_t) long long ll;
+
+alignas (max_align_t) float f;
+
+alignas (max_align_t) double d;
+
+alignas (max_align_t) _Complex long double cld;
+
+alignas (0) alignas (int) alignas (char) char ca[10];
+
+alignas ((int) alignof (max_align_t) + 0) int x;
+
+enum e { E = alignof (max_align_t) };
+alignas (E) int y;
+
+void
+func (void)
+{
+ alignas (max_align_t) long long auto_ll;
+}
+
+/* Valid, but useless. */
+alignas (0) struct s; /* { dg-warning "useless" } */
+
+#ifndef alignas
+#error "alignas not defined"
+#endif
+
+#ifndef alignof
+#error "alignof not defined"
+#endif
+
+#ifndef __alignas_is_defined
+#error "__alignas_is_defined not defined"
+#endif
+
+#if __alignas_is_defined != 1
+#error "__alignas_is_defined not 1"
+#endif
+
+#ifndef __alignof_is_defined
+#error "__alignof_is_defined not defined"
+#endif
+
+#if __alignof_is_defined != 1
+#error "__alignof_is_defined not 1"
+#endif
+
+#define str(x) #x
+#define xstr(x) str(x)
+
+const char *s1 = xstr(alignas);
+const char *s2 = xstr(alignof);
+const char *s3 = xstr(__alignas_is_defined);
+const char *s4 = xstr(__alignof_is_defined);
+
+int
+main (void)
+{
+ if (strcmp (s1, "_Alignas") != 0)
+ abort ();
+ if (strcmp (s2, "_Alignof") != 0)
+ abort ();
+ if (strcmp (s3, "1") != 0)
+ abort ();
+ if (strcmp (s4, "1") != 0)
+ abort ();
+}
--- /dev/null
+/* Test C1X alignment support. Test invalid code. */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+int a = _Alignof (void (void)); /* { dg-error "function" } */
+struct s;
+int b = _Alignof (struct s); /* { dg-error "incomplete" } */
+int c = _Alignof (void); /* { dg-error "void" } */
+int d = _Alignof (a); /* { dg-error "expression" } */
+
+_Alignas (void (void)) char e; /* { dg-error "function" } */
+_Alignas (struct s) char f; /* { dg-error "incomplete" } */
+_Alignas (void) char g; /* { dg-error "void" } */
+
+_Alignas (-__INT_MAX__-1) char h; /* { dg-error "too large|power of 2" } */
+_Alignas (-__INT_MAX__) char h2; /* { dg-error "too large|power of 2" } */
+_Alignas ((-__INT_MAX__-1)/2) char h3; /* { dg-error "too large|power of 2" } */
+_Alignas ((-__INT_MAX__-1)/4) char h4; /* { dg-error "too large|power of 2" } */
+_Alignas ((-__INT_MAX__-1)/8) char h5; /* { dg-error "too large|power of 2" } */
+_Alignas (-__LONG_LONG_MAX__-1) char i; /* { dg-error "too large|power of 2" } */
+_Alignas (-(__LONG_LONG_MAX__-1)/2) char i2; /* { dg-error "too large|power of 2" } */
+_Alignas (-(__LONG_LONG_MAX__-1)/4) char i3; /* { dg-error "too large|power of 2" } */
+_Alignas (-(__LONG_LONG_MAX__-1)/8) char i4; /* { dg-error "too large|power of 2" } */
+_Alignas (-(__LONG_LONG_MAX__-1)/16) char i5; /* { dg-error "too large|power of 2" } */
+_Alignas (-1) char j; /* { dg-error "power of 2" } */
+_Alignas (3) char k; /* { dg-error "power of 2" } */
+
+_Alignas ((void *) 1) char k; /* { dg-error "integer constant" } */
+int x;
+_Alignas (x) char l; /* { dg-error "integer constant" } */
+
+_Alignas (0) struct s; /* { dg-error "does not redeclare tag" } */
+
+_Alignas (0) typedef int T; /* { dg-error "alignment specified for typedef" } */
+void func (_Alignas (0) int); /* { dg-error "alignment specified for unnamed parameter" } */
+void f2 (_Alignas (0) int parm2) {} /* { dg-error "alignment specified for parameter" } */
+void
+f3 (void)
+{
+ register _Alignas (0) int reg; /* { dg-error "register" } */
+}
+_Alignas (0) void f4 (void); /* { dg-error "alignment specified for function" } */
--- /dev/null
+/* Test C1X alignment support. Test reducing alignment (assumes there
+ are at least some alignment constraints). */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+#include <stddef.h>
+
+_Alignas (_Alignof (char)) max_align_t x; /* { dg-error "reduce alignment" } */
--- /dev/null
+/* Test _Alignof and _Alignas not in C90. */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
+
+int a = _Alignof (int); /* { dg-error "ISO C90 does not support '_Alignof'" } */
+_Alignas (int) int b; /* { dg-error "ISO C90 does not support '_Alignas'" } */
--- /dev/null
+/* Test _Alignof and _Alignas not in C99. */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+int a = _Alignof (int); /* { dg-error "ISO C99 does not support '_Alignof'" } */
+_Alignas (int) int b; /* { dg-error "ISO C99 does not support '_Alignas'" } */
E5 = __imag__ 0,
/* __alignof__ always constant. */
E6 = __alignof__ (int[n]), /* { dg-error "ISO C90 forbids variable length array" } */
- E7 = __alignof__ (a),
+ E7 = __alignof__ (a), /* { dg-error "__alignof__ \\(expression\\)" } */
/* __extension__ ignored for constant expression purposes. */
E8 = __extension__ (1 ? 0 : i++), /* { dg-error "constant expression" } */
E9 = __extension__ 0,
E5 = __imag__ 0,
/* __alignof__ always constant. */
E6 = __alignof__ (int[n]), /* { dg-error "ISO C90 forbids variable length array" } */
- E7 = __alignof__ (a),
+ E7 = __alignof__ (a), /* { dg-error "__alignof__ \\(expression\\)" } */
/* __extension__ ignored for constant expression purposes. */
E8 = __extension__ (1 ? 0 : i++), /* { dg-error "constant expression" } */
E9 = __extension__ 0,
E5 = __imag__ 0,
/* __alignof__ always constant. */
E6 = __alignof__ (int[n]),
- E7 = __alignof__ (a),
+ E7 = __alignof__ (a), /* { dg-error "__alignof__ \\(expression\\)" } */
/* __extension__ ignored for constant expression purposes. */
E8 = __extension__ (1 ? 0 : i++), /* { dg-error "constant expression" } */
E9 = __extension__ 0,
/* __alignof__, OK. */
static int f0(void);
-void g0(void) { __alignof__(f0()); }
+void g0(void) { __alignof__(f0()); } /* { dg-error "__alignof__ \\(expression\\)" } */
/* __typeof__ not variably modified, OK. */
static int f1(void);