From: Jakub Jelinek Date: Wed, 5 Sep 2007 23:25:07 +0000 (+0200) Subject: decl.c (duplicate_decls): Set TREE_NOTHROW on __builtin_XX decl if a prototype for... X-Git-Tag: releases/gcc-4.3.0~2847 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=62bedd31edd62e473fceb5c75b838e4c4f5079fe;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bd9d1e7a40f0..07663ed10d35 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 5971bb873df9..311925a196d7 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 b0e24c0a34f9..41ca76ddc648 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 000000000000..1f56d1a833dd --- /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 000000000000..b106516da683 --- /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 000000000000..be1629ea5f85 --- /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" } } */