This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix common_pointer_type for fn pointers where one has __attribute__((const)) and one does not (PR tree-optimization/32139)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]