Commit d19fa6b5 by Joseph Myers Committed by Joseph Myers

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
parent 55d2e499
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>
......@@ -376,6 +376,7 @@ USER_H = $(srcdir)/ginclude/float.h \
$(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@
......
......@@ -3707,6 +3707,17 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
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;
......@@ -3782,6 +3793,12 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
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)
......@@ -4894,6 +4911,7 @@ grokdeclarator (const struct c_declarator *declarator,
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;
......@@ -5737,6 +5755,46 @@ grokdeclarator (const struct c_declarator *declarator,
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
......@@ -6117,6 +6175,13 @@ grokdeclarator (const struct c_declarator *declarator,
/* 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.
......@@ -8709,6 +8774,7 @@ build_null_declspecs (void)
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;
......@@ -8732,6 +8798,7 @@ build_null_declspecs (void)
ret->volatile_p = false;
ret->restrict_p = false;
ret->saturating_p = false;
ret->alignas_p = false;
ret->address_space = ADDR_SPACE_GENERIC;
return ret;
}
......@@ -9522,6 +9589,22 @@ declspecs_add_attrs (struct c_declspecs *specs, tree attrs)
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>
......
......@@ -404,6 +404,8 @@ static int resort_field_decl_cmp (const void *, const void *);
*/
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 },
......@@ -4332,7 +4334,18 @@ c_sizeof_or_alignof_type (location_t loc,
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)
{
......@@ -6670,6 +6683,36 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args,
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. */
......@@ -6693,21 +6736,8 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
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))
......
......@@ -106,6 +106,9 @@ enum rid
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,
......@@ -724,6 +727,7 @@ extern void finish_fname_decls (void);
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,
......
......@@ -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;
......
......@@ -238,6 +238,10 @@ struct c_declspecs {
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
......@@ -294,6 +298,9 @@ struct c_declspecs {
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;
};
......@@ -510,6 +517,7 @@ extern struct c_declspecs *declspecs_add_scspec (struct c_declspecs *, tree);
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 */
......
/* 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.
......@@ -412,6 +412,20 @@ typedef __WINT_TYPE__ wint_t;
/* 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>
......
// { dg-do compile }
// { dg-options "-std=c++0x -pedantic" }
int main(void)
{
alignof(void (void)); // { dg-warning "function type" }
}
/* 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" } */
/* 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 ();
}
/* 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" } */
/* 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" } */
/* 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'" } */
/* 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'" } */
......@@ -23,7 +23,7 @@ f (void)
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,
......
......@@ -23,7 +23,7 @@ f (void)
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,
......
......@@ -23,7 +23,7 @@ f (void)
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,
......
......@@ -11,7 +11,7 @@
/* __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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment