https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127016

            Bug ID: 127016
           Summary: [13/14/15/16/17 Regression] Rejects valid assignment
                    from {} to aggregate with array member NSDMI
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sebastianmiles20 at gmail dot com
  Target Milestone: ---

The following is accepted by Clang and rejected by GCC since 12.1 (t.C, no
headers):

  struct A { A() {} };
  struct E { A a; };
  struct S { E arr[2]{}; };
  void f (S *p) { *p = {}; }

  $ LC_ALL=C g++ -std=c++14 -fdiagnostics-plain-output -c t.C
  t.C: In function 'void f(S*)':
  t.C:4:23: error: no match for 'operator=' in '* p = <brace-enclosed
initializer list>()' (operand types are 'S' and '<brace-enclosed initializer
list>')
  t.C:4:23: note: there are 2 candidates
  t.C:3:8: note: candidate 1: 'constexpr S& S::operator=(const S&)'
  t.C:3:8: note: no known conversion for argument 1 from '<brace-enclosed
initializer list>' to 'const S&'
  t.C:3:8: note: candidate 2: 'constexpr S& S::operator=(S&&)'
  t.C:3:8: note: no known conversion for argument 1 from '<brace-enclosed
initializer list>' to 'S&&'

S is an aggregate, so copy-list-initializing the parameter of the implicit
copy assignment operator from {} should aggregate-initialize a temporary S
using the NSDMI of arr. `S s{};' and `S s = {};' are accepted, and so is the
assignment if arr is not an array or if A has no user-provided constructor.

can_convert_array (gcc/cp/call.cc) only accepts a CONSTRUCTOR, or a string
literal, as a valid way to aggregate initialize an array.  When the element
type needs a loop to initialize, the digested NSDMI of an array member is a
VEC_INIT_EXPR instead, so we return false and discard both implicit
assignment operators as non-viable. This representation came in with
r12-6326-ge948436ea (PR92385). Looking through to VEC_INIT_EXPR_INIT fixes
it; I will post a patch.

$ g++ -v
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,m2,cobol,algol68,lto
--prefix=/usr --with-bugurl=https://bugzilla.redhat.com/ --enable-shared
--enable-threads=posix --enable-checking=release --enable-multilib
--with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions
--enable-gnu-unique-object --enable-linker-build-id
--with-gcc-major-version-only --enable-libstdcxx-backtrace
--with-linker-hash-style=gnu --enable-plugin --enable-initfini-array
--enable-offload-targets=nvptx-none,amdgcn-amdhsa --enable-offload-defaulted
--without-cuda-driver --enable-gnu-indirect-function --enable-cet
--with-tune=generic --with-tls=gnu2 --with-arch_32=i686
--build=x86_64-redhat-linux
Thread model: posix
gcc version 16.2.1 20260819 (Red Hat 16.2.1-2) (GCC)
  • [Bug c++/127016] New: [13/1... sebastianmiles20 at gmail dot com via Gcc-bugs

Reply via email to