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
This commit is contained in:
parent
dcd25113c6
commit
8e0a600bdd
@ -1,5 +1,13 @@
|
||||
2005-06-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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,
|
||||
|
@ -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,
|
||||
|
@ -1,5 +1,9 @@
|
||||
2005-06-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/21536
|
||||
PR c/20760
|
||||
* gcc.dg/20050527-1.c: New test.
|
||||
|
||||
* gcc.dg/i386-sse-12.c: New test.
|
||||
|
||||
PR fortran/21729
|
||||
|
55
gcc/testsuite/gcc.dg/20050527-1.c
Normal file
55
gcc/testsuite/gcc.dg/20050527-1.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user