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
This commit is contained in:
Jakub Jelinek 2007-09-06 01:25:07 +02:00 committed by Jakub Jelinek
parent b1e3f20e51
commit 62bedd31ed
6 changed files with 89 additions and 0 deletions

View 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

View 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;

View 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.

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */