aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2004-04-12 21:25:55 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2004-04-12 17:25:55 -0400
commit1c9766da11d71cb57f8962a2eb88833c1ca966f5 (patch)
treefc6c6b14412060a9d6d90d3f45c768a4648b7f4b /gcc/tree.c
parent040e098a5de9115501bd76ce0ea7adc9a0eded21 (diff)
downloadgcc-1c9766da11d71cb57f8962a2eb88833c1ca966f5.zip
gcc-1c9766da11d71cb57f8962a2eb88833c1ca966f5.tar.gz
gcc-1c9766da11d71cb57f8962a2eb88833c1ca966f5.tar.bz2
c-decl.c (finish_decl): Make a decl_stmt for a variable-sized TYPE_DECL.
* c-decl.c (finish_decl): Make a decl_stmt for a variable-sized TYPE_DECL. * c-semantics.c (genrtl_decl_stmt): Handle TYPE_DECL. * stmt.c (expand_decl): Remove redundant expansion of TYPE_DOMAIN. * stor-layout.c (variable_size): Don't check for MINUS_EXPR. Use skip_simple_arithmetic to find SAVE_EXPR. (force_type_save_exprs, force_type_save_exprs_1): New functions. * tree-inline.c (remap_type, case POINTER_TYPE, case REFERENCE_TYPE): Properly chain multiple pointers. (copy_tree_r): Copy a TYPE_DECL. * tree.c (variably_modified_type_p): Add some missing tests and make some other minor changes. * tree.h (force_type_save_exprs): New declaration. * gcc.c-torture/execute/20040411-1.c: New test. From-SVN: r80629
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index d4dd3fe..0b301e2 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -4629,38 +4629,62 @@ variably_modified_type_p (tree type)
case POINTER_TYPE:
case REFERENCE_TYPE:
case ARRAY_TYPE:
- /* If TYPE is a pointer or reference, it is variably modified if
- the type pointed to is variably modified. Similarly for arrays;
- note that VLAs are handled by the TYPE_SIZE check above. */
- return variably_modified_type_p (TREE_TYPE (type));
+ case SET_TYPE:
+ case VECTOR_TYPE:
+ if (variably_modified_type_p (TREE_TYPE (type)))
+ return true;
+ break;
case FUNCTION_TYPE:
case METHOD_TYPE:
/* If TYPE is a function type, it is variably modified if any of the
parameters or the return type are variably modified. */
- {
- tree parm;
+ if (variably_modified_type_p (TREE_TYPE (type)))
+ return true;
- if (variably_modified_type_p (TREE_TYPE (type)))
+ for (t = TYPE_ARG_TYPES (type);
+ t && t != void_list_node;
+ t = TREE_CHAIN (t))
+ if (variably_modified_type_p (TREE_VALUE (t)))
return true;
- for (parm = TYPE_ARG_TYPES (type);
- parm && parm != void_list_node;
- parm = TREE_CHAIN (parm))
- if (variably_modified_type_p (TREE_VALUE (parm)))
- return true;
- }
break;
case INTEGER_TYPE:
+ case REAL_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case CHAR_TYPE:
/* Scalar types are variably modified if their end points
aren't constant. */
t = TYPE_MIN_VALUE (type);
if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)
return true;
+
t = TYPE_MAX_VALUE (type);
if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)
return true;
- return false;
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ /* We can't see if any of the field are variably-modified by the
+ definition we normally use, since that would produce infinite
+ recursion via pointers. */
+ /* This is variably modified if some field's type is. */
+ for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
+ if (TREE_CODE (t) == FIELD_DECL)
+ {
+ tree t1 = DECL_FIELD_OFFSET (t);
+
+ if (t1 && t1 != error_mark_node && TREE_CODE (t1) != INTEGER_CST)
+ return true;
+
+ t1 = DECL_SIZE (t);
+ if (t1 && t1 != error_mark_node && TREE_CODE (t1) != INTEGER_CST)
+ return true;
+ }
+ break;
default:
break;