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&action=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.

Reply via email to