[all-commits] [llvm/llvm-project] d60c3d: [clang] Skip stores in init for fields that are em...

Martin Storsjö via All-commits all-commits at lists.llvm.org
Tue Aug 15 01:08:18 PDT 2023

  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: d60c3d08e78dfbb4b180776b83e910d810e1f36a
  Author: Martin Storsjö <martin at martin.st>
  Date:   2023-08-15 (Tue, 15 Aug 2023)

  Changed paths:
    M clang/lib/CodeGen/CGCall.cpp
    A clang/test/CodeGenCXX/ctor-empty-nounique.cpp

  Log Message:
  [clang] Skip stores in init for fields that are empty structs

An empty struct is handled as a struct with a dummy i8, on all targets.

Most targets treat an empty struct return value as essentially
void - but some don't. (Currently, at least x86_64-windows-* and
powerpc64le-* don't treat it as void.)

When intializing a struct with such a no_unique_address member,
make sure we don't write the dummy i8 into the struct where there's
no space allocated for it.

Previously it would clobber the actual valid data of the struct.

Fixes https://github.com/llvm/llvm-project/issues/64253, and
possibly https://github.com/llvm/llvm-project/issues/64077
and https://github.com/llvm/llvm-project/issues/64427 as well.

We should omit the store for any empty record (not only ones
declared with no_unique_address); we can have a situation where a
class doesn't have the no_unique_address attribute, but is embedded
in an outer struct with the no_unique_address attribute - like this:

    struct S {};
    S f();
    struct S2 : public S { S2();};
    S2::S2() : S(f()) {}
    struct S3 { int x; [[no_unique_address]] S2 y; S3(); };
    S3::S3() : x(1), y() {}

Here, the problematic store (which this patch omits) is in
the constructor of S2. In the case of S3, S2 has no valid storage
and aliases x - thus the constructor of S2 should omit the dummy

Differential Revision: https://reviews.llvm.org/D157332

More information about the All-commits mailing list