From: Paolo Carlini Date: Mon, 21 Jul 2008 16:18:38 +0000 (+0000) Subject: re PR c++/36871 (__has_nothrow_copy(T) false for T with a template ctor) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=279086c39066177adac8f9589683429e01c325a3;p=gcc.git re PR c++/36871 (__has_nothrow_copy(T) false for T with a template ctor) /cp 2008-07-21 Paolo Carlini PR c++/36871 PR c++/36872 * semantics.c (classtype_has_nothrow_assign_or_copy_p): Only check copy constructors and copy assignment operators proper. /testsuite 2008-07-21 Paolo Carlini PR c++/36871 PR c++/36872 * g++.dg/ext/has_nothrow_copy.C: Rename to... * g++.dg/ext/has_nothrow_copy-1.C: ... this. * g++.dg/ext/has_nothrow_copy-2.C: New. * g++.dg/ext/has_nothrow_copy-3.C: Likewise. * g++.dg/ext/has_nothrow_copy-4.C: Likewise. * g++.dg/ext/has_nothrow_copy-5.C: Likewise. * g++.dg/ext/has_nothrow_copy-6.C: Likewise. * g++.dg/ext/has_nothrow_copy-7.C: Likewise. From-SVN: r138034 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4e3bb4cd898..4f9e10c709d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2008-07-21 Paolo Carlini + + PR c++/36871 + PR c++/36872 + * semantics.c (classtype_has_nothrow_assign_or_copy_p): Only check + copy constructors and copy assignment operators proper. + 2008-07-21 Rafael Avila de Espindola * parser.c (cp_token): Remove in_system_header. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 3b91ddb0f90..ffa6493ced4 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4677,8 +4677,20 @@ classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p) return false; for (; fns; fns = OVL_NEXT (fns)) - if (!TYPE_NOTHROW_P (TREE_TYPE (OVL_CURRENT (fns)))) - return false; + { + tree fn = OVL_CURRENT (fns); + + if (assign_p) + { + if (copy_fn_p (fn) == 0) + continue; + } + else if (copy_fn_p (fn) <= 0) + continue; + + if (!TYPE_NOTHROW_P (TREE_TYPE (fn))) + return false; + } return true; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d02787b284a..3f15e389096 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2008-07-21 Paolo Carlini + + PR c++/36871 + PR c++/36872 + * g++.dg/ext/has_nothrow_copy.C: Rename to... + * g++.dg/ext/has_nothrow_copy-1.C: ... this. + * g++.dg/ext/has_nothrow_copy-2.C: New. + * g++.dg/ext/has_nothrow_copy-3.C: Likewise. + * g++.dg/ext/has_nothrow_copy-4.C: Likewise. + * g++.dg/ext/has_nothrow_copy-5.C: Likewise. + * g++.dg/ext/has_nothrow_copy-6.C: Likewise. + * g++.dg/ext/has_nothrow_copy-7.C: Likewise. + 2008-07-21 Thomas Koenig PR libfortran/36773 diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C new file mode 100644 index 00000000000..e8507cf582c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C @@ -0,0 +1,140 @@ +// { dg-do "run" } +#include + +struct A +{ + double a; + double b; +}; + +struct B +{ + A a; +}; + +struct C +: public A { }; + +struct D +{ + D(const D&) throw() { } +}; + +struct E +{ + E(const E&) throw(int) { } +}; + +struct E1 +{ + E1(const E1&) throw(int) { throw int(); } +}; + +struct F +{ + F() throw() { } +}; + +struct G +{ + G() throw(int) { throw int(); } +}; + +struct H +{ + H(H&) throw(int) { } +}; + +struct H1 +{ + H1(H1&) throw(int) { throw int(); } +}; + +struct I +{ + I(I&) throw(int) { } + I(const I&) throw() { } +}; + +struct I1 +{ + I1(I1&) throw(int) { throw int(); } + I1(const I1&) throw() { } +}; + +struct J +{ + J(J&) throw() { } + J(const J&) throw() { } + J(volatile J&) throw() { } + J(const volatile J&) throw() { } +}; + +template + bool + f() + { return __has_nothrow_copy(T); } + +template + class My + { + public: + bool + f() + { return !!__has_nothrow_copy(T); } + }; + +template + class My2 + { + public: + static const bool trait = __has_nothrow_copy(T); + }; + +template + const bool My2::trait; + +template + struct My3_help + { static const bool trait = b; }; + +template + const bool My3_help::trait; + +template + class My3 + { + public: + bool + f() + { return My3_help::trait; } + }; + +#define PTEST(T) (__has_nothrow_copy(T) && f() \ + && My().f() && My2::trait && My3().f()) + +#define NTEST(T) (!__has_nothrow_copy(T) && !f() \ + && !My().f() && !My2::trait && !My3().f()) + +int main() +{ + assert (PTEST (int)); + assert (NTEST (int (int))); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (B)); + assert (PTEST (C)); + assert (NTEST (C[])); + assert (PTEST (D)); + assert (NTEST (E)); + assert (NTEST (E1)); + assert (PTEST (F)); + assert (PTEST (G)); + assert (NTEST (H)); + assert (NTEST (H1)); + assert (NTEST (I)); + assert (NTEST (I1)); + assert (PTEST (J)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C new file mode 100644 index 00000000000..276b11d574c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C @@ -0,0 +1,12 @@ +// PR c++/36871 +// { dg-do "run" } +#include + +struct A { template A (T) throw (int); }; +struct B { B (B&) throw (); template B (T) throw (int); }; + +int main () +{ + assert (__has_nothrow_copy (A)); + assert (__has_nothrow_copy (B)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C new file mode 100644 index 00000000000..2fbcf8c8096 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C @@ -0,0 +1,13 @@ +// PR c++/36871 +// { dg-do "run" } +#include + +struct F { + F (const F&) throw () { } + template F (T) throw () { } +}; + +int main () +{ + assert (__has_nothrow_copy (F)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C new file mode 100644 index 00000000000..4bd7475ea7c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C @@ -0,0 +1,13 @@ +// PR c++/36872 +// { dg-do "run" } +#include + +struct S { + S (const S&) throw (); + S (...) throw (int); +}; + +int main () +{ + assert (__has_nothrow_copy (S)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C new file mode 100644 index 00000000000..051675c4d00 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C @@ -0,0 +1,13 @@ +// PR c++/36872 +// { dg-do "run" } +#include + +struct S { + S (const S&) throw (); + S (int) throw (int); +}; + +int main () +{ + assert (__has_nothrow_copy (S)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C new file mode 100644 index 00000000000..4330edd2941 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C @@ -0,0 +1,12 @@ +// { dg-do "run" } +#include + +struct S { + S (S&) throw (); + S (const S&, int) throw (int); +}; + +int main () +{ + assert (__has_nothrow_copy (S)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C new file mode 100644 index 00000000000..a85224c3abc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C @@ -0,0 +1,13 @@ +// { dg-do "run" } +// { dg-options "-std=c++0x" } +#include + +struct S { + S (const S&) throw (); + S (S&&) throw (int); +}; + +int main () +{ + assert (__has_nothrow_copy (S)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C deleted file mode 100644 index e8507cf582c..00000000000 --- a/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C +++ /dev/null @@ -1,140 +0,0 @@ -// { dg-do "run" } -#include - -struct A -{ - double a; - double b; -}; - -struct B -{ - A a; -}; - -struct C -: public A { }; - -struct D -{ - D(const D&) throw() { } -}; - -struct E -{ - E(const E&) throw(int) { } -}; - -struct E1 -{ - E1(const E1&) throw(int) { throw int(); } -}; - -struct F -{ - F() throw() { } -}; - -struct G -{ - G() throw(int) { throw int(); } -}; - -struct H -{ - H(H&) throw(int) { } -}; - -struct H1 -{ - H1(H1&) throw(int) { throw int(); } -}; - -struct I -{ - I(I&) throw(int) { } - I(const I&) throw() { } -}; - -struct I1 -{ - I1(I1&) throw(int) { throw int(); } - I1(const I1&) throw() { } -}; - -struct J -{ - J(J&) throw() { } - J(const J&) throw() { } - J(volatile J&) throw() { } - J(const volatile J&) throw() { } -}; - -template - bool - f() - { return __has_nothrow_copy(T); } - -template - class My - { - public: - bool - f() - { return !!__has_nothrow_copy(T); } - }; - -template - class My2 - { - public: - static const bool trait = __has_nothrow_copy(T); - }; - -template - const bool My2::trait; - -template - struct My3_help - { static const bool trait = b; }; - -template - const bool My3_help::trait; - -template - class My3 - { - public: - bool - f() - { return My3_help::trait; } - }; - -#define PTEST(T) (__has_nothrow_copy(T) && f() \ - && My().f() && My2::trait && My3().f()) - -#define NTEST(T) (!__has_nothrow_copy(T) && !f() \ - && !My().f() && !My2::trait && !My3().f()) - -int main() -{ - assert (PTEST (int)); - assert (NTEST (int (int))); - assert (NTEST (void)); - assert (PTEST (A)); - assert (PTEST (B)); - assert (PTEST (C)); - assert (NTEST (C[])); - assert (PTEST (D)); - assert (NTEST (E)); - assert (NTEST (E1)); - assert (PTEST (F)); - assert (PTEST (G)); - assert (NTEST (H)); - assert (NTEST (H1)); - assert (NTEST (I)); - assert (NTEST (I1)); - assert (PTEST (J)); - - return 0; -}