diff options
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index bb7d881ba80..9e34e3e683d 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -283,6 +283,7 @@ static tree c_make_fname_decl PARAMS ((tree, int)); static void c_expand_body PARAMS ((tree, int, int)); static void warn_if_shadowing PARAMS ((tree, tree)); static bool flexible_array_type_p PARAMS ((tree)); +static tree set_save_expr_context PARAMS ((tree *, int *, void *)); /* States indicating how grokdeclarator() should handle declspecs marked with __attribute__((deprecated)). An object declared as @@ -1138,6 +1139,13 @@ duplicate_decls (newdecl, olddecl, different_binding_level) } } error_with_decl (olddecl, "previous declaration of `%s'"); + + /* This is safer because the initializer might contain references + to variables that were declared between olddecl and newdecl. This + will make the initializer invalid for olddecl in case it gets + assigned to olddecl below. */ + if (TREE_CODE (newdecl) == VAR_DECL) + DECL_INITIAL (newdecl) = 0; } /* TLS cannot follow non-TLS declaration. */ else if (TREE_CODE (olddecl) == VAR_DECL && TREE_CODE (newdecl) == VAR_DECL @@ -4065,7 +4073,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) } if (size_varies) - itype = variable_size (itype); + { + /* We must be able to distinguish the + SAVE_EXPR_CONTEXT for the variably-sized type + so that we can set it correctly in + set_save_expr_context. The convention is + that all SAVE_EXPRs that need to be reset + have NULL_TREE for their SAVE_EXPR_CONTEXT. */ + tree cfd = current_function_decl; + if (decl_context == PARM) + current_function_decl = NULL_TREE; + itype = variable_size (itype); + if (decl_context == PARM) + current_function_decl = cfd; + } itype = build_index_type (itype); } } @@ -4544,6 +4565,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) needed, and let dwarf2 know that the function is inlinable. */ else if (flag_inline_trees == 2 && initialized) { + if (!DECL_INLINE (decl)) + DID_INLINE_FUNC (decl) = 1; DECL_INLINE (decl) = 1; DECL_DECLARED_INLINE_P (decl) = 0; } @@ -5217,18 +5240,6 @@ finish_struct (t, fieldlist, attributes) } } - else if (TREE_TYPE (x) != error_mark_node) - { - unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT - : TYPE_ALIGN (TREE_TYPE (x))); - - /* Non-bit-fields are aligned for their type, except packed - fields which require only BITS_PER_UNIT alignment. */ - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align); - if (! DECL_PACKED (x)) - DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x)); - } - DECL_INITIAL (x) = 0; /* Detect flexible array member in an invalid context. */ @@ -6417,6 +6428,26 @@ c_expand_deferred_function (fndecl) } } +/* Called to move the SAVE_EXPRs for parameter declarations in a + nested function into the nested function. DATA is really the + nested FUNCTION_DECL. */ + +static tree +set_save_expr_context (tp, walk_subtrees, data) + tree *tp; + int *walk_subtrees; + void *data; +{ + if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp)) + SAVE_EXPR_CONTEXT (*tp) = (tree) data; + /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause + circularity. */ + else if (DECL_P (*tp)) + *walk_subtrees = 0; + + return NULL_TREE; +} + /* Generate the RTL for the body of FNDECL. If NESTED_P is nonzero, then we are already in the process of generating RTL for another function. If can_defer_p is zero, we won't attempt to defer the @@ -6488,6 +6519,15 @@ c_expand_body (fndecl, nested_p, can_defer_p) /* Set up parameters and prepare for return, for the function. */ expand_function_start (fndecl, 0); + /* If the function has a variably modified type, there may be + SAVE_EXPRs in the parameter types. Their context must be set to + refer to this function; they cannot be expanded in the containing + function. */ + if (decl_function_context (fndecl) + && variably_modified_type_p (TREE_TYPE (fndecl))) + walk_tree (&TREE_TYPE (fndecl), set_save_expr_context, fndecl, + NULL); + /* If this function is `main', emit a call to `__main' to run global initializers, etc. */ if (DECL_NAME (fndecl) |