]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
decl.c (duplicate_decls): Set TREE_NOTHROW on __builtin_XX decl if a prototype for...
authorJakub Jelinek <jakub@redhat.com>
Wed, 5 Sep 2007 23:25:07 +0000 (01:25 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 5 Sep 2007 23:25:07 +0000 (01:25 +0200)
* decl.c (duplicate_decls): Set TREE_NOTHROW on __builtin_XX
decl if a prototype for XX is provided with throw().

* g++.dg/eh/builtin1.C: New test.
* g++.dg/eh/builtin2.C: New test.
* g++.dg/eh/builtin3.C: New test.

From-SVN: r128159

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/eh/builtin1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/eh/builtin2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/eh/builtin3.C [new file with mode: 0644]

index bd9d1e7a40f0a4925af6514bb03422f6ac9d7fc2..07663ed10d3531e2bb6da75c969069c9084f6071 100644 (file)
@@ -1,3 +1,8 @@
+2007-09-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * decl.c (duplicate_decls): Set TREE_NOTHROW on __builtin_XX
+       decl if a prototype for XX is provided with throw().
+
 2007-09-05  Paolo Carlini  <pcarlini@suse.de>
 
        PR c++/30302
index 5971bb873df9cde5a9085e7dbb8ce1a8e90e21fa..311925a196d7525057f516577b9f621718f451a2 100644 (file)
@@ -1280,6 +1280,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type;
        }
 
+      /* If a function is explicitly declared "throw ()", propagate that to
+        the corresponding builtin.  */
+      if (DECL_BUILT_IN_CLASS (olddecl) == BUILT_IN_NORMAL
+         && DECL_ANTICIPATED (olddecl)
+         && TREE_NOTHROW (newdecl)
+         && !TREE_NOTHROW (olddecl)
+         && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != NULL_TREE
+         && built_in_decls [DECL_FUNCTION_CODE (olddecl)] != olddecl
+         && types_match)
+       TREE_NOTHROW (built_in_decls [DECL_FUNCTION_CODE (olddecl)]) = 1;
+
       /* Whether or not the builtin can throw exceptions has no
         bearing on this declarator.  */
       TREE_NOTHROW (olddecl) = 0;
index b0e24c0a34f90f07506e04bcebdf513104507daf..41ca76ddc6485f730393cd488bd5c5ea2ca769e8 100644 (file)
@@ -1,3 +1,9 @@
+2007-09-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * g++.dg/eh/builtin1.C: New test.
+       * g++.dg/eh/builtin2.C: New test.
+       * g++.dg/eh/builtin3.C: New test.
+
 2007-09-05  Janis Johnson  <janis187@us.ibm.com>
 
        * gcc.target/powerpc/dfp-dd.c: New test.
diff --git a/gcc/testsuite/g++.dg/eh/builtin1.C b/gcc/testsuite/g++.dg/eh/builtin1.C
new file mode 100644 (file)
index 0000000..1f56d1a
--- /dev/null
@@ -0,0 +1,26 @@
+// Verify that if explicit prototype for builtin is present without throw(),
+// both the normal builtin and __builtin_* variant are expected to be
+// able to throw exceptions.
+// { dg-do compile }
+// { dg-options "-fdump-tree-eh" }
+
+extern "C" int printf (const char *, ...);
+
+struct A { A (); ~A (); int i; };
+
+int
+foo ()
+{
+  A a;
+  printf ("foo %d\n", a.i);
+}
+
+int
+bar ()
+{
+  A a;
+  __builtin_printf ("foo %d\n", a.i);
+}
+
+/* { dg-final { scan-tree-dump-times "resx 1" 2 "eh" } } */
+/* { dg-final { cleanup-tree-dump "eh" } } */
diff --git a/gcc/testsuite/g++.dg/eh/builtin2.C b/gcc/testsuite/g++.dg/eh/builtin2.C
new file mode 100644 (file)
index 0000000..b106516
--- /dev/null
@@ -0,0 +1,25 @@
+// Verify that if explicit prototype for builtin is present with throw(),
+// neither the normal builtin nor __builtin_* variant can throw exceptions.
+// { dg-do compile }
+// { dg-options "-fdump-tree-eh" }
+
+extern "C" int printf (const char *, ...) throw();
+
+struct A { A (); ~A (); int i; };
+
+int
+foo ()
+{
+  A a;
+  printf ("foo %d\n", a.i);
+}
+
+int
+bar ()
+{
+  A a;
+  __builtin_printf ("foo %d\n", a.i);
+}
+
+/* { dg-final { scan-tree-dump-times "resx 1" 0 "eh" } } */
+/* { dg-final { cleanup-tree-dump "eh" } } */
diff --git a/gcc/testsuite/g++.dg/eh/builtin3.C b/gcc/testsuite/g++.dg/eh/builtin3.C
new file mode 100644 (file)
index 0000000..be1629e
--- /dev/null
@@ -0,0 +1,16 @@
+// Without explicit prototype, we need to assume the builtin can
+// throw for builtins that at least on one platform can throw.
+// { dg-do compile }
+// { dg-options "-fdump-tree-eh" }
+
+struct A { A (); ~A (); int i; };
+
+int
+bar ()
+{
+  A a;
+  __builtin_printf ("foo %d\n", a.i);
+}
+
+/* { dg-final { scan-tree-dump-times "resx 1" 1 "eh" } } */
+/* { dg-final { cleanup-tree-dump "eh" } } */