diff options
author | Joseph Myers <jsm@polyomino.org.uk> | 2002-08-17 15:48:28 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2002-08-17 15:48:28 +0100 |
commit | 2984fe64968ad7140e84f8137c877c9e6d25136a (patch) | |
tree | 89955359e44fa2311d348937a438303874397fd2 /gcc/c-decl.c | |
parent | fded6d781c8e005bc195fc047a7e480073871c35 (diff) | |
download | gcc-2984fe64968ad7140e84f8137c877c9e6d25136a.zip gcc-2984fe64968ad7140e84f8137c877c9e6d25136a.tar.gz gcc-2984fe64968ad7140e84f8137c877c9e6d25136a.tar.bz2 |
c-decl.c (flexible_array_type_p): New function.
* c-decl.c (flexible_array_type_p): New function.
(grokdeclarator, finish_struct): Use it.
* doc/extend.texi: Document constraints on use of structures with
flexible array members.
testsuite:
* gcc.dg/c90-flex-array-1.c, gcc.dg/c99-flex-array-3.c,
gcc.dg/c99-flex-array-4.c: New tests.
From-SVN: r56411
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 7a926cf..d61d955 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -282,6 +282,7 @@ static void layout_array_type PARAMS ((tree)); 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)); /* States indicating how grokdeclarator() should handle declspecs marked with __attribute__((deprecated)). An object declared as @@ -3357,6 +3358,40 @@ complete_array_type (type, initial_value, do_default) return value; } +/* Determine whether TYPE is a structure with a flexible array member, + or a union containing such a structure (possibly recursively). */ + +static bool +flexible_array_type_p (type) + tree type; +{ + tree x; + switch (TREE_CODE (type)) + { + case RECORD_TYPE: + x = TYPE_FIELDS (type); + if (x == NULL_TREE) + return false; + while (TREE_CHAIN (x) != NULL_TREE) + x = TREE_CHAIN (x); + if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE + && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE + && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE + && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE) + return true; + return false; + case UNION_TYPE: + for (x = TYPE_FIELDS (type); x != NULL_TREE; x = TREE_CHAIN (x)) + { + if (flexible_array_type_p (TREE_TYPE (x))) + return true; + } + return false; + default: + return false; + } +} + /* Given declspecs and a declarator, determine the name and type of the object declared and construct a ..._DECL node for it. @@ -3953,6 +3988,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) type = error_mark_node; } + if (pedantic && flexible_array_type_p (type)) + pedwarn ("invalid use of structure with flexible array member"); + if (size == error_mark_node) type = error_mark_node; @@ -5216,6 +5254,11 @@ finish_struct (t, fieldlist, attributes) else if (! saw_named_field) error_with_decl (x, "flexible array member in otherwise empty struct"); } + + if (pedantic && TREE_CODE (t) == RECORD_TYPE + && flexible_array_type_p (TREE_TYPE (x))) + pedwarn_with_decl (x, "invalid use of structure with flexible array member"); + if (DECL_NAME (x)) saw_named_field = 1; } |