diff options
author | Sandra Loosemore <sandra@codesourcery.com> | 2019-12-01 22:52:15 -0500 |
---|---|---|
committer | Sandra Loosemore <sandra@gcc.gnu.org> | 2019-12-01 22:52:15 -0500 |
commit | 4569f8b3652ae1e5ca353c24148b50c786b36c8b (patch) | |
tree | f22f9ae555d8f38b980718893ef0bc8f71976ea5 /gcc/tree.c | |
parent | e549dd44b5ff0547004a640554ebe55f1ce2936b (diff) | |
download | gcc-4569f8b3652ae1e5ca353c24148b50c786b36c8b.zip gcc-4569f8b3652ae1e5ca353c24148b50c786b36c8b.tar.gz gcc-4569f8b3652ae1e5ca353c24148b50c786b36c8b.tar.bz2 |
Fix bugs relating to flexibly-sized objects in nios2 backend.
2019-12-01 Sandra Loosemore <sandra@codesourcery.com>
Fix bugs relating to flexibly-sized objects in nios2 backend.
PR target/92499
gcc/c/
* c-decl.c (flexible_array_type_p): Move to common code.
gcc/
* config/nios2/nios2.c (nios2_in_small_data_p): Do not consider
objects of flexible types to be small if they have internal linkage
or are declared extern.
* config/nios2/nios2.h (ASM_OUTPUT_ALIGNED_LOCAL): Replace with...
(ASM_OUTPUT_ALIGNED_DECL_LOCAL): ...this. Use targetm.in_small_data_p
instead of the size of the object initializer.
* tree.c (flexible_array_type_p): Move from C front end, and
generalize to handle fields in non-C structures.
* tree.h (flexible_array_type_p): Declare.
gcc/testsuite/
* gcc.target/nios2/pr92499-1.c: New.
* gcc.target/nios2/pr92499-2.c: New.
* gcc.target/nios2/pr92499-3.c: New.
From-SVN: r278891
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 35 |
1 files changed, 35 insertions, 0 deletions
@@ -15003,6 +15003,41 @@ default_is_empty_record (const_tree type) return default_is_empty_type (TYPE_MAIN_VARIANT (type)); } +/* Determine whether TYPE is a structure with a flexible array member, + or a union containing such a structure (possibly recursively). */ + +bool +flexible_array_type_p (const_tree type) +{ + tree x, last; + switch (TREE_CODE (type)) + { + case RECORD_TYPE: + last = NULL_TREE; + for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x)) + if (TREE_CODE (x) == FIELD_DECL) + last = x; + if (last == NULL_TREE) + return false; + if (TREE_CODE (TREE_TYPE (last)) == ARRAY_TYPE + && TYPE_SIZE (TREE_TYPE (last)) == NULL_TREE + && TYPE_DOMAIN (TREE_TYPE (last)) != NULL_TREE + && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (last))) == NULL_TREE) + return true; + return false; + case UNION_TYPE: + for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x)) + { + if (TREE_CODE (x) == FIELD_DECL + && flexible_array_type_p (TREE_TYPE (x))) + return true; + } + return false; + default: + return false; + } +} + /* Like int_size_in_bytes, but handle empty records specially. */ HOST_WIDE_INT |