]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/34768 (Wrong code with conditional function invocation)
authorRichard Guenther <rguenther@suse.de>
Wed, 16 Jan 2008 09:44:23 +0000 (09:44 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 16 Jan 2008 09:44:23 +0000 (09:44 +0000)
2008-01-16  Richard Guenther  <rguenther@suse.de>

PR c/34768
* c-typeck.c (common_pointer_type): Do not merge inconsistent
type qualifiers for function types.

* gcc.c-torture/execute/pr34768-1.c: New testcase.
* gcc.c-torture/execute/pr34768-2.c: Likewise.

From-SVN: r131568

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr34768-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr34768-2.c [new file with mode: 0644]

index 90e422ea1302ff847c831eec54b16fa33dce4fe5..dd099a44055cb42156083af351266e34be5e71b6 100644 (file)
@@ -1,3 +1,9 @@
+2008-01-16  Richard Guenther  <rguenther@suse.de>
+
+       PR c/34768
+       * c-typeck.c (common_pointer_type): Do not merge inconsistent
+       type qualifiers for function types.
+
 2008-01-15  Sebastian Pop  <sebastian.pop@amd.com>
 
        * tree-parloops (gen_parallel_loop): Revert my fix.
index 6d94cabdf99e4cdb3079f7bfbbc32f2ddef4a9da..fb2e47f096996e7883cc90dcd5d61c8500fada7c 100644 (file)
@@ -530,6 +530,7 @@ common_pointer_type (tree t1, tree t2)
   tree pointed_to_1, mv1;
   tree pointed_to_2, mv2;
   tree target;
+  unsigned target_quals;
 
   /* Save time if the two types are the same.  */
 
@@ -557,10 +558,15 @@ 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)));
+
+  /* For function types do not merge const qualifiers, but drop them
+     if used inconsistently.  The middle-end uses these to mark const
+     and noreturn functions.  */
+  if (TREE_CODE (pointed_to_1) == FUNCTION_TYPE)
+    target_quals = TYPE_QUALS (pointed_to_1) & TYPE_QUALS (pointed_to_2);
+  else
+    target_quals = TYPE_QUALS (pointed_to_1) | TYPE_QUALS (pointed_to_2);
+  t1 = build_pointer_type (c_build_qualified_type (target, target_quals));
   return build_type_attribute_variant (t1, attributes);
 }
 
index 7a2d834e6417305833e65970497a9c983fb69781..b69ff98543974e324080e2d1552193d4337d40c9 100644 (file)
@@ -1,3 +1,9 @@
+2008-01-16  Richard Guenther  <rguenther@suse.de>
+
+       PR c/34768
+       * gcc.c-torture/execute/pr34768-1.c: New testcase.
+       * gcc.c-torture/execute/pr34768-2.c: Likewise.
+
 2008-01-16  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/34796
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr34768-1.c b/gcc/testsuite/gcc.c-torture/execute/pr34768-1.c
new file mode 100644 (file)
index 0000000..eb16adb
--- /dev/null
@@ -0,0 +1,26 @@
+int x;
+
+void __attribute__((noinline)) foo (void)
+{
+  x = -x;
+}
+void __attribute__((const,noinline)) bar (void)
+{
+}
+
+int __attribute__((noinline))
+test (int c)
+{
+  int tmp = x;
+  (c ? foo : bar) ();
+  return tmp + x;
+}
+
+extern void abort (void);
+int main()
+{
+  x = 1;
+  if (test (1) != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr34768-2.c b/gcc/testsuite/gcc.c-torture/execute/pr34768-2.c
new file mode 100644 (file)
index 0000000..917bf9e
--- /dev/null
@@ -0,0 +1,28 @@
+int x;
+
+int __attribute__((noinline)) foo (void)
+{
+  x = -x;
+  return 0;
+}
+int __attribute__((const,noinline)) bar (void)
+{
+  return 0;
+}
+
+int __attribute__((noinline))
+test (int c)
+{
+  int tmp = x;
+  int res = (c ? foo : bar) ();
+  return tmp + x + res;
+}
+
+extern void abort (void);
+int main()
+{
+  x = 1;
+  if (test (1) != 0)
+    abort ();
+  return 0;
+}