https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70972
Bug ID: 70972 Summary: [6/7 Regression] Inheriting constructors taking parameters by value should move them, not copy Product: gcc Version: 6.1.0 Status: UNCONFIRMED Keywords: rejects-valid, wrong-code Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: rs2740 at gmail dot com Target Milestone: --- The following code, accepted by GCC 5.3, fails to compile in GCC 6.1 and 7: struct moveonly { moveonly(moveonly&&) = default; moveonly() = default; }; struct A { A(moveonly) {} }; struct B : A { using A::A; }; B b(moveonly{}); with a bogus error: + g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp main.cpp: In constructor 'B::B(moveonly)': main.cpp:10:14: error: use of deleted function 'constexpr moveonly::moveonly(const moveonly&)' using A::A; ^ main.cpp:1:8: note: 'constexpr moveonly::moveonly(const moveonly&)' is implicitly declared as deleted because 'moveonly' declares a move constructor or move assignment operator struct moveonly { ^~~~~~~~ main.cpp: At global scope: main.cpp:13:15: note: synthesized method 'B::B(moveonly)' first required here B b(moveonly{}); Per N4140 [class.inhctor]/8, an implicitly defined inheriting constructor should cast a passed-by-value parameter to an rvalue before forwarding it to the base class constructor: > Each expression in the expression-list [of the mem-initializer for the base > class] is of the form static_cast<T&&>(p), where p is the name of the > corresponding constructor parameter and T is the declared type of p. (The code above remains valid under the new inheriting constructor semantics in P0136R1.) However, GCC 6.1 looks for a copy constructor instead, and would call them instead of move: struct abort_on_copy{ abort_on_copy(abort_on_copy&&) = default; abort_on_copy(const abort_on_copy&) { __builtin_abort(); } abort_on_copy() = default; }; struct A { A(abort_on_copy) {} }; struct B : A { using A::A; }; int main() { B b(abort_on_copy{}); // aborts }