summaryrefslogtreecommitdiff
path: root/gcc/c-family/c-common.c
diff options
context:
space:
mode:
authorMartin Uecker <uecker@gcc.gnu.org>2021-11-17 14:20:59 +0100
committerMartin Uecker <muecker@gwdg.de>2021-11-17 14:29:50 +0100
commit4e6bf0b9dd5585df1a1472d6a93b9fff72fe2524 (patch)
treedfc6be0b46a1b565c69dd1ddfd094b834465e9f1 /gcc/c-family/c-common.c
parent077425c890927eefacb765ab5236060de9859e82 (diff)
downloadgcc-4e6bf0b9dd5585df1a1472d6a93b9fff72fe2524.tar.gz
Fix ICE when mixing VLAs and statement expressions [PR91038]
When returning VM-types from statement expressions, this can lead to an ICE when declarations from the statement expression are referred to later. Most of these issues can be addressed by gimplifying the base expression earlier in gimplify_compound_lval. Another issue is fixed by wrapping the pointer expression in pointer_int_sum. This fixes PR91038 and some of the test cases from PR29970 (structs with VLA members need further work). gcc/ PR c/91038 PR c/29970 * gimplify.c (gimplify_var_or_parm_decl): Update comment. (gimplify_compound_lval): Gimplify base expression first. (gimplify_target_expr): Add comment. gcc/c-family/ PR c/91038 PR c/29970 * c-common.c (pointer_int_sum): Make sure pointer expressions are evaluated first when the size expression depends on for variably-modified types. gcc/testsuite/ PR c/91038 PR c/29970 * gcc.dg/vla-stexp-3.c: New test. * gcc.dg/vla-stexp-4.c: New test. * gcc.dg/vla-stexp-5.c: New test. * gcc.dg/vla-stexp-6.c: New test. * gcc.dg/vla-stexp-7.c: New test. * gcc.dg/vla-stexp-8.c: New test. * gcc.dg/vla-stexp-9.c: New test.
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r--gcc/c-family/c-common.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 90e8ec87b6b..ca7d69c4f76 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -3306,7 +3306,19 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
TREE_TYPE (result_type)))
size_exp = integer_one_node;
else
- size_exp = size_in_bytes_loc (loc, TREE_TYPE (result_type));
+ {
+ size_exp = size_in_bytes_loc (loc, TREE_TYPE (result_type));
+ /* Wrap the pointer expression in a SAVE_EXPR to make sure it
+ is evaluated first when the size expression may depend
+ on it for VM types. */
+ if (TREE_SIDE_EFFECTS (size_exp)
+ && TREE_SIDE_EFFECTS (ptrop)
+ && variably_modified_type_p (TREE_TYPE (ptrop), NULL))
+ {
+ ptrop = save_expr (ptrop);
+ size_exp = build2 (COMPOUND_EXPR, TREE_TYPE (intop), ptrop, size_exp);
+ }
+ }
/* We are manipulating pointer values, so we don't need to warn
about relying on undefined signed overflow. We disable the