diff options
author | Richard Henderson <rth@redhat.com> | 2005-08-08 14:38:24 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-08-08 14:38:24 -0700 |
commit | a9c5ddf90c294e351661f3b487315b8602f2851c (patch) | |
tree | 025597e589fb555cd81a2643920c6a05aac62efc /gcc | |
parent | 224694090c01069cec258efe72c5115b7ef2a879 (diff) | |
download | gcc-a9c5ddf90c294e351661f3b487315b8602f2851c.zip gcc-a9c5ddf90c294e351661f3b487315b8602f2851c.tar.gz gcc-a9c5ddf90c294e351661f3b487315b8602f2851c.tar.bz2 |
re PR middle-end/22439 (ICE with char VLA and __SIZE_TYPE__ argument (so no cast))
PR 22439
* gimplify.c (gimplify_one_sizepos): Preserve the original type.
From-SVN: r102879
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/gimplify.c | 34 |
2 files changed, 35 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 492631d..b01aa11 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2005-08-08 Richard Henderson <rth@redhat.com> + + PR 22439 + * gimplify.c (gimplify_one_sizepos): Preserve the original type. + 2005-08-08 Bob Wilson <bob.wilson@acm.org> * expr.c (write_complex_part): Return after handling MEM. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 16a6aae..d207e7c 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -4610,18 +4610,44 @@ gimplify_type_sizes (tree type, tree *list_p) void gimplify_one_sizepos (tree *expr_p, tree *stmt_p) { + tree type, expr = *expr_p; + /* We don't do anything if the value isn't there, is constant, or contains A PLACEHOLDER_EXPR. We also don't want to do anything if it's already a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier will want to replace it with a new variable, but that will cause problems if this type is from outside the function. It's OK to have that here. */ - if (*expr_p == NULL_TREE || TREE_CONSTANT (*expr_p) - || TREE_CODE (*expr_p) == VAR_DECL - || CONTAINS_PLACEHOLDER_P (*expr_p)) + if (expr == NULL_TREE || TREE_CONSTANT (expr) + || TREE_CODE (expr) == VAR_DECL + || CONTAINS_PLACEHOLDER_P (expr)) return; - *expr_p = unshare_expr (*expr_p); + type = TREE_TYPE (expr); + *expr_p = unshare_expr (expr); + gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue); + expr = *expr_p; + + /* Verify that we've an exact type match with the original expression. + In particular, we do not wish to drop a "sizetype" in favour of a + type of similar dimensions. We don't want to pollute the generic + type-stripping code with this knowledge because it doesn't matter + for the bulk of GENERIC/GIMPLE. It only matters that TYPE_SIZE_UNIT + and friends retain their "sizetype-ness". */ + if (TREE_TYPE (expr) != type && TYPE_IS_SIZETYPE (type)) + { + tree tmp; + + *expr_p = create_tmp_var (type, NULL); + tmp = build1 (NOP_EXPR, type, expr); + tmp = build2 (MODIFY_EXPR, type, *expr_p, expr); + if (EXPR_HAS_LOCATION (expr)) + SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr)); + else + SET_EXPR_LOCATION (tmp, input_location); + + gimplify_and_add (tmp, stmt_p); + } } #ifdef ENABLE_CHECKING |