summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/c-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/c-common.c')
-rw-r--r--contrib/gcc/c-common.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/contrib/gcc/c-common.c b/contrib/gcc/c-common.c
index b650a48..fa89614 100644
--- a/contrib/gcc/c-common.c
+++ b/contrib/gcc/c-common.c
@@ -2995,16 +2995,16 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
}
/* Implement the __alignof keyword: Return the minimum required
- alignment of EXPR, measured in bytes. For VAR_DECL's and
- FIELD_DECL's return DECL_ALIGN (which can be set from an
- "aligned" __attribute__ specification). */
+ alignment of EXPR, measured in bytes. For VAR_DECLs,
+ FUNCTION_DECLs and FIELD_DECLs return DECL_ALIGN (which can be set
+ from an "aligned" __attribute__ specification). */
tree
c_alignof_expr (tree expr)
{
tree t;
- if (TREE_CODE (expr) == VAR_DECL)
+ if (VAR_OR_FUNCTION_DECL_P (expr))
t = size_int (DECL_ALIGN_UNIT (expr));
else if (TREE_CODE (expr) == COMPONENT_REF
@@ -4809,12 +4809,24 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
TYPE_ALIGN (*type) = (1 << i) * BITS_PER_UNIT;
TYPE_USER_ALIGN (*type) = 1;
}
- else if (TREE_CODE (decl) != VAR_DECL
+ else if (! VAR_OR_FUNCTION_DECL_P (decl)
&& TREE_CODE (decl) != FIELD_DECL)
{
error ("alignment may not be specified for %q+D", decl);
*no_add_attrs = true;
}
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_ALIGN (decl) > (1 << i) * BITS_PER_UNIT)
+ {
+ if (DECL_USER_ALIGN (decl))
+ error ("alignment for %q+D was previously specified as %d "
+ "and may not be decreased", decl,
+ DECL_ALIGN (decl) / BITS_PER_UNIT);
+ else
+ error ("alignment for %q+D must be at least %d", decl,
+ DECL_ALIGN (decl) / BITS_PER_UNIT);
+ *no_add_attrs = true;
+ }
else
{
DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT;
OpenPOWER on IntegriCloud