aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2007-08-24 15:09:10 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2007-08-24 15:09:10 +0000
commitfa2050d2664411f84dfdfcdcea9c509144ba0b96 (patch)
treee1badd70aec0549a564c0a232d88b4610c7d380a
parenta7d318ea7f7b816250f872bc0cb13b9cd8277cd9 (diff)
downloadgcc-fa2050d2664411f84dfdfcdcea9c509144ba0b96.zip
gcc-fa2050d2664411f84dfdfcdcea9c509144ba0b96.tar.gz
gcc-fa2050d2664411f84dfdfcdcea9c509144ba0b96.tar.bz2
re PR tree-optimization/33166 (ICE in get_indirect_ref_operands, at tree-ssa-operands.c:1698)
2007-08-24 Richard Guenther <rguenther@suse.de> PR middle-end/33166 * tree-ssa.c (useless_type_conversion_p): Split into a recursive and a non-recursive part. (useless_type_conversion_p_1): New function. * tree-ssa-ccp.c (fold_stmt_r): Make sure that the result from maybe_fold_offset_to_reference is trivially convertible to the desired type before doing the simplification. * gcc.c-torture/compile/pr33166.c: New testcase. From-SVN: r127771
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr33166.c10
-rw-r--r--gcc/tree-ssa-ccp.c7
-rw-r--r--gcc/tree-ssa.c82
5 files changed, 77 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 18e9586..02646a7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2007-08-24 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33166
+ * tree-ssa.c (useless_type_conversion_p): Split into a
+ recursive and a non-recursive part.
+ (useless_type_conversion_p_1): New function.
+ * tree-ssa-ccp.c (fold_stmt_r): Make sure that the result
+ from maybe_fold_offset_to_reference is trivially convertible
+ to the desired type before doing the simplification.
+
2007-08-24 Jakub Jelinek <jakub@redhat.com>
* expr.c (store_expr): Optimize initialization of an array
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a27c2ad..54da80e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-08-24 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33166
+ * gcc.c-torture/compile/pr33166.c: New testcase.
+
2007-08-24 Tobias Burnus <burnus@net-b.de>
PR fortran/33139
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr33166.c b/gcc/testsuite/gcc.c-torture/compile/pr33166.c
new file mode 100644
index 0000000..a48c529
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr33166.c
@@ -0,0 +1,10 @@
+static void ConvertAddr (char *saddr, void **addr)
+{
+ *addr = (void *) &saddr;
+}
+void DefineSelf (char *addr)
+{
+ ConvertAddr (addr, (void **) &addr);
+ if (addr[0] == 127 && addr[3] == 1)
+ ;
+}
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index e6dfcd8..e0829f5 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2060,7 +2060,12 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
(TREE_OPERAND (expr, 0),
integer_zero_node,
TREE_TYPE (TREE_TYPE (expr)))))
- t = build_fold_addr_expr_with_type (t, TREE_TYPE (expr));
+ {
+ tree ptr_type = build_pointer_type (TREE_TYPE (t));
+ if (!useless_type_conversion_p (TREE_TYPE (expr), ptr_type))
+ return NULL_TREE;
+ t = build_fold_addr_expr_with_type (t, ptr_type);
+ }
break;
/* ??? Could handle more ARRAY_REFs here, as a variant of INDIRECT_REF.
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index e088549..633e446 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -885,32 +885,10 @@ delete_tree_ssa (void)
cfun->gimple_df = NULL;
}
+/* Helper function for useless_type_conversion_p. */
-/* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a
- useless type conversion, otherwise return false.
-
- This function implicitly defines the middle-end type system. With
- the notion of 'a < b' meaning that useless_type_conversion_p (a, b)
- holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds,
- the following invariants shall be fulfilled:
-
- 1) useless_type_conversion_p is transitive.
- If a < b and b < c then a < c.
-
- 2) useless_type_conversion_p is not symmetric.
- From a < b does not follow a > b.
-
- 3) Types define the available set of operations applicable to values.
- A type conversion is useless if the operations for the target type
- is a subset of the operations for the source type. For example
- casts to void* are useless, casts from void* are not (void* can't
- be dereferenced or offsetted, but copied, hence its set of operations
- is a strict subset of that of all other data pointer types). Casts
- to const T* are useless (can't be written to), casts from const T*
- to T* are not. */
-
-bool
-useless_type_conversion_p (tree outer_type, tree inner_type)
+static bool
+useless_type_conversion_p_1 (tree outer_type, tree inner_type)
{
/* Qualifiers on value types do not matter. */
inner_type = TYPE_MAIN_VARIANT (inner_type);
@@ -964,11 +942,6 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
else if (POINTER_TYPE_P (inner_type)
&& POINTER_TYPE_P (outer_type))
{
- /* If the outer type is (void *), then the conversion is not
- necessary. */
- if (TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
- return true;
-
/* Don't lose casts between pointers to volatile and non-volatile
qualified types. Doing so would result in changing the semantics
of later accesses. */
@@ -1002,22 +975,22 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
to types are effectively the same. We can strip qualifiers
on pointed-to types for further comparison, which is done in
the callee. */
- return useless_type_conversion_p (TREE_TYPE (outer_type),
- TREE_TYPE (inner_type));
+ return useless_type_conversion_p_1 (TREE_TYPE (outer_type),
+ TREE_TYPE (inner_type));
}
/* Recurse for complex types. */
else if (TREE_CODE (inner_type) == COMPLEX_TYPE
&& TREE_CODE (outer_type) == COMPLEX_TYPE)
- return useless_type_conversion_p (TREE_TYPE (outer_type),
- TREE_TYPE (inner_type));
+ return useless_type_conversion_p_1 (TREE_TYPE (outer_type),
+ TREE_TYPE (inner_type));
/* Recurse for vector types with the same number of subparts. */
else if (TREE_CODE (inner_type) == VECTOR_TYPE
&& TREE_CODE (outer_type) == VECTOR_TYPE
&& TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
- return useless_type_conversion_p (TREE_TYPE (outer_type),
- TREE_TYPE (inner_type));
+ return useless_type_conversion_p_1 (TREE_TYPE (outer_type),
+ TREE_TYPE (inner_type));
/* For aggregates we may need to fall back to structural equality
checks. */
@@ -1037,6 +1010,43 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
return false;
}
+/* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a
+ useless type conversion, otherwise return false.
+
+ This function implicitly defines the middle-end type system. With
+ the notion of 'a < b' meaning that useless_type_conversion_p (a, b)
+ holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds,
+ the following invariants shall be fulfilled:
+
+ 1) useless_type_conversion_p is transitive.
+ If a < b and b < c then a < c.
+
+ 2) useless_type_conversion_p is not symmetric.
+ From a < b does not follow a > b.
+
+ 3) Types define the available set of operations applicable to values.
+ A type conversion is useless if the operations for the target type
+ is a subset of the operations for the source type. For example
+ casts to void* are useless, casts from void* are not (void* can't
+ be dereferenced or offsetted, but copied, hence its set of operations
+ is a strict subset of that of all other data pointer types). Casts
+ to const T* are useless (can't be written to), casts from const T*
+ to T* are not. */
+
+bool
+useless_type_conversion_p (tree outer_type, tree inner_type)
+{
+ /* If the outer type is (void *), then the conversion is not
+ necessary. We have to make sure to not apply this while
+ recursing though. */
+ if (POINTER_TYPE_P (inner_type)
+ && POINTER_TYPE_P (outer_type)
+ && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
+ return true;
+
+ return useless_type_conversion_p_1 (outer_type, inner_type);
+}
+
/* Return true if a conversion from either type of TYPE1 and TYPE2
to the other is not required. Otherwise return false. */