aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@adacore.com>2006-10-06 09:12:09 +0000
committerOlivier Hainque <hainque@gcc.gnu.org>2006-10-06 09:12:09 +0000
commit706c4bb76caf0bf9cef5f12d94c9b52d9594e433 (patch)
tree27fdba5cec2529f809c49eb8024849092cb5d4d5 /gcc/c-decl.c
parent4d51dc9ec6c2b5e94031936baca7763d9c3b4f1c (diff)
downloadgcc-706c4bb76caf0bf9cef5f12d94c9b52d9594e433.zip
gcc-706c4bb76caf0bf9cef5f12d94c9b52d9594e433.tar.gz
gcc-706c4bb76caf0bf9cef5f12d94c9b52d9594e433.tar.bz2
gimplify.c (gimplify_type_sizes): Don't recurse on the pointed-to type.
* gimplify.c (gimplify_type_sizes) [POINTER_TYPE, REFERENCE_TYPE]: Don't recurse on the pointed-to type. * c-decl.c (grokdeclarator) [cdk_pointer]: If we are in a NORMAL or DECL context, attach an artificial TYPE_DECL to anonymous pointed-to types with components of variable size. * testsuite/gcc.dg/typename-vla-1.c: New case. * testsuite/gnat.dg/forward_vla.adb: New case. From-SVN: r117493
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index fd20078..6379a1e 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -4471,6 +4471,40 @@ grokdeclarator (const struct c_declarator *declarator,
type = c_build_qualified_type (type, type_quals);
size_varies = 0;
+ /* When the pointed-to type involves components of variable size,
+ care must be taken to ensure that the size evaluation code is
+ emitted early enough to dominate all the possible later uses
+ and late enough for the variables on which it depends to have
+ been assigned.
+
+ This is expected to happen automatically when the pointed-to
+ type has a name/declaration of it's own, but special attention
+ is required if the type is anonymous.
+
+ We handle the NORMAL and FIELD contexts here by attaching an
+ artificial TYPE_DECL to such pointed-to type. This forces the
+ sizes evaluation at a safe point and ensures it is not deferred
+ until e.g. within a deeper conditional context.
+
+ We expect nothing to be needed here for PARM or TYPENAME.
+ Pushing a TYPE_DECL at this point for TYPENAME would actually
+ be incorrect, as we might be in the middle of an expression
+ with side effects on the pointed-to type size "arguments" prior
+ to the pointer declaration point and the fake TYPE_DECL in the
+ enclosing context would force the size evaluation prior to the
+ side effects. */
+
+ if (!TYPE_NAME (type)
+ && (decl_context == NORMAL || decl_context == FIELD)
+ && variably_modified_type_p (type, NULL_TREE))
+ {
+ tree decl = build_decl (TYPE_DECL, NULL_TREE, type);
+ DECL_ARTIFICIAL (decl) = 1;
+ pushdecl (decl);
+ finish_decl (decl, NULL_TREE, NULL_TREE);
+ TYPE_NAME (type) = decl;
+ }
+
type = build_pointer_type (type);
/* Process type qualifiers (such as const or volatile)