diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-09-06 01:25:07 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-09-06 01:25:07 +0200 |
commit | 62bedd31edd62e473fceb5c75b838e4c4f5079fe (patch) | |
tree | 1d6176051116d224efb9036dd9ba002ea90773a4 /gcc | |
parent | b1e3f20e51b93889c8fb8dbb4205170d33dfa9ec (diff) | |
download | gcc-62bedd31edd62e473fceb5c75b838e4c4f5079fe.zip gcc-62bedd31edd62e473fceb5c75b838e4c4f5079fe.tar.gz gcc-62bedd31edd62e473fceb5c75b838e4c4f5079fe.tar.bz2 |
decl.c (duplicate_decls): Set TREE_NOTHROW on __builtin_XX decl if a prototype for XX is provided with...
* 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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/eh/builtin1.C | 26 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/eh/builtin2.C | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/eh/builtin3.C | 16 |
6 files changed, 89 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bd9d1e7..07663ed 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5971bb8..311925a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b0e24c0..41ca76d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..1f56d1a --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/builtin1.C @@ -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 index 0000000..b106516 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/builtin2.C @@ -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 index 0000000..be1629e --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/builtin3.C @@ -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" } } */ |