https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83937
Bug ID: 83937
Summary: [REGRESSION] C++17 binds braced init of a type T to
default arg of a ctor instead of using T's own default
ctor
Product: gcc
Version: 7.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: raphaelsc at scylladb dot com
Target Milestone: ---
Created attachment 43181
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43181=edit
default_ctor_regression_for_default_value_ctor_argument
Unlike C++14, C++17 isn't using default ctor of a type T when it's braced
initialized, i.e. {}, and used as argument for a ctor of a type that has a
default argument for the same type T.
The following code
struct S
{
S(int i = 42);
};
void f()
{
S( {} );
}
produces this assembly to g++ --std=c++14
lea rax, [rbp-1]
mov esi, 0
mov rdi, rax
call S::S(int)
and this one for g++ --std=c++17
lea rax, [rbp-1]
mov esi, 42
mov rdi, rax
call S::S(int)
that also works for any user-defined type, such as
struct T
{
T(int i = 10);
};
struct S
{
S(T i = T(42));
};
void f()
{
S( {} );
}
S's ctor is called with 42 instead of 10 for C++17.
but C++14 judges it ambiguous and doesn't even compile it.
Note that if I change S( {} ) to S( T{} ), it works as expected.
The code attached which resembles the first code shown produces the following
output:
$ g++ --std=c++17 ub.cc -o ub; ./ub
42
$ g++ --std=c++14 ub.cc -o ub; ./ub
0
Please find code for output above attached.