diff options
author | Jason Merrill <jason@redhat.com> | 2011-02-15 19:39:27 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-02-15 19:39:27 -0500 |
commit | 503c8e860b28659ab922f8500590d08353c0575c (patch) | |
tree | a6d0a3bb4ee91bd00b282995d12c2c735da5c1f8 | |
parent | aa2bf28660fa52a864fc8e0dacf4d5862c86e2e9 (diff) | |
download | gcc-503c8e860b28659ab922f8500590d08353c0575c.zip gcc-503c8e860b28659ab922f8500590d08353c0575c.tar.gz gcc-503c8e860b28659ab922f8500590d08353c0575c.tar.bz2 |
re PR c++/46807 (internal compiler error: in synthesized_method_walk)
PR c++/46807
* method.c (synthesized_method_walk): Always exit early for
trivial fn in C++98 mode.
From-SVN: r170207
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/method.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/implicit-trivial1.C | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/inherit/implicit-trivial1.C | 23 |
5 files changed, 61 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 61a3e4a..0fdac3c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2011-02-15 Jason Merrill <jason@redhat.com> + + PR c++/46807 + * method.c (synthesized_method_walk): Always exit early for + trivial fn in C++98 mode. + 2011-02-14 Jason Merrill <jason@redhat.com> PR c++/47482 diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 3f0baed..bfe8a06 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1153,13 +1153,15 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, if (trivial_p) *trivial_p = expected_trivial; -#ifndef ENABLE_CHECKING /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base class versions and other properties of the type. But a subobject class can be trivially copyable and yet have overload resolution choose a template constructor for initialization, depending on rvalueness and cv-quals. So we can't exit early for copy/move - methods in C++0x. */ + methods in C++0x. The same considerations apply in C++98/03, but + there the definition of triviality does not consider overload + resolution, so a constructor can be trivial even if it would otherwise + call a non-trivial constructor. */ if (expected_trivial && (!copy_arg_p || cxx_dialect < cxx0x)) { @@ -1167,7 +1169,6 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, *constexpr_p = synthesized_default_constructor_is_constexpr (ctype); return; } -#endif ++cp_unevaluated_operand; ++c_inhibit_evaluation_warnings; @@ -1300,14 +1301,6 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, if (spec_p) *spec_p = merge_exception_specifiers (*spec_p, cleanup_spec); } - -#ifdef ENABLE_CHECKING - /* If we expected this to be trivial but it isn't, then either we're in - C++0x mode and this is a copy/move ctor/op= or there's an error. */ - gcc_assert (!(trivial_p && expected_trivial && !*trivial_p) - || (copy_arg_p && cxx_dialect >= cxx0x) - || errorcount); -#endif } /* DECL is a deleted function. If it's implicitly deleted, explain why and diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d6834fb..2608ce5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-02-15 Jason Merrill <jason@redhat.com> + + * g++.dg/inherit/implicit-trivial1.C: New. + * g++.dg/cpp0x/implicit-trivial1.C: New. + 2011-02-15 H.J. Lu <hongjiu.lu@intel.com> PR middle-end/47725 diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit-trivial1.C b/gcc/testsuite/g++.dg/cpp0x/implicit-trivial1.C new file mode 100644 index 0000000..64084c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/implicit-trivial1.C @@ -0,0 +1,23 @@ +// PR c++/46807 +// { dg-options -std=c++0x } +// In C++98/03, B::B(const B&) is trivial because A::A(const A&) is trivial, +// even though doing overload resolution would mean calling the template +// constructor. In C++0x, we do overload resolution to determine triviality. + +struct A +{ + A() {} +private: + template <class T> A(T&); // { dg-error "private" } +}; + +struct B // { dg-error "implicitly deleted|this context" } +{ + mutable A a; +}; + +int main() +{ + B b; + B b2(b); // { dg-error "deleted" } +} diff --git a/gcc/testsuite/g++.dg/inherit/implicit-trivial1.C b/gcc/testsuite/g++.dg/inherit/implicit-trivial1.C new file mode 100644 index 0000000..e63bd34 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/implicit-trivial1.C @@ -0,0 +1,23 @@ +// PR c++/46807 +// { dg-options -std=c++98 } +// In C++98/03, B::B(const B&) is trivial because A::A(const A&) is trivial, +// even though doing overload resolution would mean calling the template +// constructor. In C++0x, we do overload resolution to determine triviality. + +struct A +{ + A() {} +private: + template <class T> A(T&); +}; + +struct B +{ + mutable A a; +}; + +int main() +{ + B b; + B b2(b); +} |