From 62bedd31edd62e473fceb5c75b838e4c4f5079fe Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 6 Sep 2007 01:25:07 +0200 Subject: 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 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/decl.c | 11 +++++++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/eh/builtin1.C | 26 ++++++++++++++++++++++++++ gcc/testsuite/g++.dg/eh/builtin2.C | 25 +++++++++++++++++++++++++ gcc/testsuite/g++.dg/eh/builtin3.C | 16 ++++++++++++++++ 6 files changed, 89 insertions(+) create mode 100644 gcc/testsuite/g++.dg/eh/builtin1.C create mode 100644 gcc/testsuite/g++.dg/eh/builtin2.C create mode 100644 gcc/testsuite/g++.dg/eh/builtin3.C (limited to 'gcc') 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 + + * 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 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 + + * 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 * 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" } } */ -- cgit v1.1