http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53025
Bug #: 53025 Summary: [C++11] noexcept operator depends on copy-elision Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: daniel.krueg...@googlemail.com gcc 4.8.0 20120318 (experimental) in C++11 mode rejects the following code: //----- struct A { A() noexcept {} A(const A&) noexcept(false) {} }; void a(A) noexcept {} static_assert(!noexcept(a(A{})), ""); // Error //----- According to [expr.call] p4 parameter construction happens in the caller space, therefore the copy-initialization need to respect the noexcept(false) of the copy constructor (The same problem for a type with a corresponding move-constructor). There seems to be evidence that the outcome of the test above depends on compiler optimization (copy-elision): a) If we change the program slightly to the following form: //----- template<class T> T&& declval() noexcept; struct A { A() noexcept {} A(const A&) noexcept(false) {} }; void a(A) noexcept {} static_assert(!noexcept(a(declval<A>())), ""); // OK //----- The code is accepted, presumably because 12.8 p31 b3 does no longer hold. b) An even more convincing argument is that when adding the compiler argument --no-elide-constructors the original code becomes accepted as well, thus the outcome indeed depends on copy-elision taking place or not. The semantics of the noexcept operator (5.3.7) are described by "potentially evaluated functions calls" and 3.2 p3 says in a note that "A constructor selected to copy or move an object of class type is odr-used even if the call is actually elided by the implementation", so this observable behaviour seems to be non-conforming.