diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 20ee05cd6f3..ebc3aad86c9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-05-07 Ian Lance Taylor + + PR middle-end/36013 + * gimplify.c (find_single_pointer_decl_1): Don't look through + indirections. + (find_single_pointer_decl): Adjust comments. + 2008-05-07 Jakub Jelinek PR middle-end/36137 diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 2e8ffef4430..e36d5db93c8 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -391,6 +391,13 @@ find_single_pointer_decl_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, { tree *pdecl = (tree *) data; + /* We are only looking for pointers at the same level as the + original tree; we must not look through any indirections. + Returning anything other than NULL_TREE will cause the caller to + not find a base. */ + if (REFERENCE_CLASS_P (*tp)) + return *tp; + if (DECL_P (*tp) && POINTER_TYPE_P (TREE_TYPE (*tp))) { if (*pdecl) @@ -406,8 +413,9 @@ find_single_pointer_decl_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, return NULL_TREE; } -/* Find the single DECL of pointer type in the tree T and return it. - If there are zero or more than one such DECLs, return NULL. */ +/* Find the single DECL of pointer type in the tree T, used directly + rather than via an indirection, and return it. If there are zero + or more than one such DECLs, return NULL. */ static tree find_single_pointer_decl (tree t) @@ -418,7 +426,8 @@ find_single_pointer_decl (tree t) { /* find_single_pointer_decl_1 returns a nonzero value, causing walk_tree to return a nonzero value, to indicate that it - found more than one pointer DECL. */ + found more than one pointer DECL or that it found an + indirection. */ return NULL_TREE; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a36aa5a3301..b872afd3e19 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2008-05-07 Jakub Jelinek + PR middle-end/36013 + * gcc.c-torture/execute/20080506-2.c: New test. + PR middle-end/36137 * gcc.c-torture/execute/20080506-1.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/20080506-2.c b/gcc/testsuite/gcc.c-torture/execute/20080506-2.c new file mode 100644 index 00000000000..d2fac713bd8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20080506-2.c @@ -0,0 +1,21 @@ +/* PR middle-end/36013 */ + +extern void abort (void); + +void __attribute__((noinline)) +foo (int **__restrict p, int **__restrict q) +{ + *p[0] = 1; + *q[0] = 2; + if (*p[0] != 2) + abort (); +} + +int +main (void) +{ + int a; + int *p1 = &a, *p2 = &a; + foo (&p1, &p2); + return 0; +}