This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix common_pointer_type for fn pointers where one has __attribute__((const)) and one does not (PR tree-optimization/32139)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 31 May 2007 07:57:39 -0400
- Subject: [PATCH] Fix common_pointer_type for fn pointers where one has __attribute__((const)) and one does not (PR tree-optimization/32139)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On FUNCTION_TYPE TREE_READONLY means the fn has __attribute__((const))
and that should be merged IMHO conservatively, TREE_READONLY on the
common fntype onlyl if both functions are __attribute__((const)),
otherwise we can optimize out some invocations even when they have
side-effects.
On gcc-4_1-branch this fixes an ICE, on 4.3 I don't have a testcase
that would be miscompiled, but the problem is IMHO still there.
2007-05-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/32139
* c-typeck.c (common_pointer_type): Set TREE_READONLY
on the merged pointed to FUNCTION_TYPE only if both
pointed_to_1 and pointed_to_2 are TREE_READONLY.
* gcc.c-torture/execute/20070531-1.c: New test.
--- gcc/c-typeck.c.jj 2007-04-25 10:13:52.000000000 +0200
+++ gcc/c-typeck.c 2007-05-31 13:38:04.000000000 +0200
@@ -499,6 +499,7 @@ common_pointer_type (tree t1, tree t2)
tree pointed_to_1, mv1;
tree pointed_to_2, mv2;
tree target;
+ int type_quals;
/* Save time if the two types are the same. */
@@ -526,10 +527,18 @@ common_pointer_type (tree t1, tree t2)
if (TREE_CODE (mv2) != ARRAY_TYPE)
mv2 = TYPE_MAIN_VARIANT (pointed_to_2);
target = composite_type (mv1, mv2);
- t1 = build_pointer_type (c_build_qualified_type
- (target,
- TYPE_QUALS (pointed_to_1) |
- TYPE_QUALS (pointed_to_2)));
+ type_quals = TYPE_QUALS (pointed_to_1) | TYPE_QUALS (pointed_to_2);
+ if (TREE_CODE (pointed_to_1) == FUNCTION_TYPE)
+ {
+ /* TREE_READONLY on FUNCTION_TYPE should be logically ANDed,
+ not ORed, as if one function is __attribute__((const))
+ and the other is not, the common type must be conservatively
+ not __attribute__((const)). */
+ type_quals &= ~TYPE_QUAL_CONST;
+ if (TREE_READONLY (pointed_to_1) && TREE_READONLY (pointed_to_2))
+ type_quals |= TYPE_QUAL_CONST;
+ }
+ t1 = build_pointer_type (c_build_qualified_type (target, type_quals));
return build_type_attribute_variant (t1, attributes);
}
--- gcc/testsuite/gcc.c-torture/execute/20070531-1.c.jj 2007-05-31 13:47:22.000000000 +0200
+++ gcc/testsuite/gcc.c-torture/execute/20070531-1.c 2007-05-31 13:43:26.000000000 +0200
@@ -0,0 +1,11 @@
+/* PR tree-optimization/32139 */
+int foo (void);
+int bar (void) __attribute__ ((const));
+
+int
+test (int x)
+{
+ int a = (x == 10000 ? foo : bar) ();
+ int b = (x == 10000 ? foo : bar) ();
+ return a + b;
+}
Jakub