From 8e0a600bdd9dee1b4eb8f3e5ce840e76fdabf133 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 1 Jun 2005 12:23:17 +0200 Subject: [PATCH] re PR c/21536 (C99 array of variable length use causes segmentation fault) PR c/21536 PR c/20760 * gimplify.c (gimplify_decl_expr): Call gimplify_type_sizes on variable sizes types if a decl is a pointer to a VLA. (gimplify_type_sizes): Handle POINTER_TYPE and REFERENCE_TYPE. Call gimplify_type_sizes on aggregate fields. Prevent infinite recursion. * gcc.dg/20050527-1.c: New test. From-SVN: r100443 --- gcc/ChangeLog | 8 +++++ gcc/gimplify.c | 50 ++++++++++++++-------------- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/20050527-1.c | 55 +++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/20050527-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01a685a22a1..2cc59298371 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2005-06-01 Jakub Jelinek + PR c/21536 + PR c/20760 + * gimplify.c (gimplify_decl_expr): Call gimplify_type_sizes + on variable sizes types if a decl is a pointer to a VLA. + (gimplify_type_sizes): Handle POINTER_TYPE and REFERENCE_TYPE. + Call gimplify_type_sizes on aggregate fields. Prevent infinite + recursion. + * fold-const.c (fold_ternary): Optimize BIT_FIELD_REF of VECTOR_CST. * config/i386/xmmintrin.h (_mm_setzero_ps, _mm_set_ss, _mm_set1_ps, diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 02da99b5672..853ff9db57b 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -983,10 +983,12 @@ gimplify_decl_expr (tree *stmt_p) if (TREE_TYPE (decl) == error_mark_node) return GS_ERROR; - else if (TREE_CODE (decl) == TYPE_DECL) + if ((TREE_CODE (decl) == TYPE_DECL + || TREE_CODE (decl) == VAR_DECL) + && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl))) gimplify_type_sizes (TREE_TYPE (decl), stmt_p); - else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) + if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) { tree init = DECL_INITIAL (decl); @@ -997,12 +999,6 @@ gimplify_decl_expr (tree *stmt_p) of the emitted code: see mx_register_decls(). */ tree t, args, addr, ptr_type; - /* ??? We really shouldn't need to gimplify the type of the variable - since it already should have been done. But leave this here - for now to avoid disrupting too many things at once. */ - if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl))) - gimplify_type_sizes (TREE_TYPE (decl), stmt_p); - gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p); gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p); @@ -4409,21 +4405,21 @@ gimplify_type_sizes (tree type, tree *list_p) { tree field, t; - /* Note that we do not check for TYPE_SIZES_GIMPLIFIED already set because - that's not supposed to happen on types where gimplification does anything. - We should assert that it isn't set, but we can indeed be called multiple - times on pointers. Unfortunately, this includes fat pointers which we - can't easily test for. We could pass TYPE down to gimplify_one_sizepos - and test there, but it doesn't seem worth it. */ + if (type == NULL) + return; /* We first do the main variant, then copy into any other variants. */ type = TYPE_MAIN_VARIANT (type); + /* Avoid infinite recursion. */ + if (TYPE_SIZES_GIMPLIFIED (type) + || type == error_mark_node) + return; + + TYPE_SIZES_GIMPLIFIED (type) = 1; + switch (TREE_CODE (type)) { - case ERROR_MARK: - return; - case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: @@ -4436,17 +4432,13 @@ gimplify_type_sizes (tree type, tree *list_p) { TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type); TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type); - TYPE_SIZES_GIMPLIFIED (t) = 1; } break; case ARRAY_TYPE: /* These types may not have declarations, so handle them here. */ - if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (type))) - gimplify_type_sizes (TREE_TYPE (type), list_p); - - if (!TYPE_SIZES_GIMPLIFIED (TYPE_DOMAIN (type))) - gimplify_type_sizes (TYPE_DOMAIN (type), list_p); + gimplify_type_sizes (TREE_TYPE (type), list_p); + gimplify_type_sizes (TYPE_DOMAIN (type), list_p); break; case RECORD_TYPE: @@ -4454,7 +4446,15 @@ gimplify_type_sizes (tree type, tree *list_p) case QUAL_UNION_TYPE: for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) - gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p); + { + gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p); + gimplify_type_sizes (TREE_TYPE (field), list_p); + } + break; + + case POINTER_TYPE: + case REFERENCE_TYPE: + gimplify_type_sizes (TREE_TYPE (type), list_p); break; default: @@ -4470,8 +4470,6 @@ gimplify_type_sizes (tree type, tree *list_p) TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type); TYPE_SIZES_GIMPLIFIED (t) = 1; } - - TYPE_SIZES_GIMPLIFIED (type) = 1; } /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d002a612750..716eae7cfd2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2005-06-01 Jakub Jelinek + PR c/21536 + PR c/20760 + * gcc.dg/20050527-1.c: New test. + * gcc.dg/i386-sse-12.c: New test. PR fortran/21729 diff --git a/gcc/testsuite/gcc.dg/20050527-1.c b/gcc/testsuite/gcc.dg/20050527-1.c new file mode 100644 index 00000000000..1b32324471f --- /dev/null +++ b/gcc/testsuite/gcc.dg/20050527-1.c @@ -0,0 +1,55 @@ +/* PR c/21536 */ +/* { dg-do run } */ +/* { dg-options "-O2 -Wuninitialized" } */ + +typedef __SIZE_TYPE__ size_t; +extern void *malloc (size_t); +extern void free (void *); + +void * +foo (int x, int y) +{ + void *d = malloc (x * y * sizeof (double)); + double (*e)[x][y] = d; + x += 10; + y += 10; + if (x > 18) + (*e)[x - 12][y - 12] = 0.0; + else + (*e)[x - 11][y - 11] = 1.0; + return d; +} + +void * +bar (int x, int y) +{ + void *d = malloc (x * y * sizeof (double)); + struct S + { + double (*e)[x][y]; + double (*f)[x][y]; + } s; + s.e = d; + s.f = d; + x += 10; + y += 10; + if (x > 18) + (*s.e)[x - 12][y - 12] = 0.0; + else + (*s.e)[x - 11][y - 11] = 1.0; + if (x > 16) + (*s.f)[x - 13][y - 13] = 0.0; + else + (*s.f)[x - 14][y - 14] = 1.0; + return d; +} + +int +main () +{ + void *d1 = foo (10, 10); + void *d2 = bar (10, 10); + free (d1); + free (d2); + return 0; +} -- 2.30.2