https://github.com/ClaytonKnittel updated 
https://github.com/llvm/llvm-project/pull/221615

>From a0a916f125993059c3125957801d37f933a58241 Mon Sep 17 00:00:00 2001
From: Clayton Knittel <[email protected]>
Date: Sun, 6 Sep 2026 23:45:05 +0000
Subject: [PATCH] Always emit complete debug info for types which appear as
 members of a standard-layout union.

[[class.mem]](https://timsong-cpp.github.io/cppwp/n3337/class.mem#19)
states:

> "If a standard-layout union contains two or more standard-layout structs that 
> share a common initial sequence, and if the standard-layout union object 
> currently contains one of these standard-layout structs, it is permitted to 
> inspect the common initial part of any of them. Two standard-layout structs 
> share a common initial sequence if corresponding members have 
> layout-compatible types and either neither member is a bit-field or both are 
> bit-fields with the same width for a sequence of one or more initial members."

This makes it possible to obtain a reference to a type which was never
constructed, which violates the assumption made by constructor homing
that all types that may require debug info must be constructed.

This change takes the conservative approach of always emitting full
debug info for standard-layout types which appear as a member of a
standard-layout union somewhere in the TU. It could be made more
aggressive by only emitting full debug info if there is another type in
the union that shares a "common initial sequence", but that would add
complexity to this exclusion logic and likely isn't worth it.

Signed-off-by: Clayton Knittel <[email protected]>
---
 .../clang/AST/CXXRecordDeclDefinitionBits.def |   3 +
 clang/include/clang/AST/DeclCXX.h             |   9 +
 clang/lib/AST/DeclCXX.cpp                     |  50 ++-
 clang/lib/CodeGen/CGDebugInfo.cpp             |  11 +
 clang/test/DebugInfo/CXX/limited-ctor.cpp     |  20 +-
 clang/unittests/AST/DeclTest.cpp              | 397 ++++++++++++++++++
 6 files changed, 488 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def 
b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
index 97e61aaec7d51..a45a57ecfff20 100644
--- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
+++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
@@ -64,6 +64,9 @@ FIELD(Abstract, 1, NO_MERGE)
 /// language rules (including DRs).
 FIELD(IsStandardLayout, 1, NO_MERGE)
 
+/// True when this class appears as a member of some standard-layout union.
+FIELD(IsStandardLayoutUnionMember, 1, MERGE_OR)
+
 /// True when this class was standard-layout under the C++11
 /// definition.
 ///
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index afe46fae1bceb..c46ab72cb1bc5 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1233,6 +1233,15 @@ class CXXRecordDecl : public RecordDecl {
   /// C++ [class]p7.
   bool isStandardLayout() const { return data().IsStandardLayout; }
 
+  /// Determine whether this class appears as a member of a standard-layout
+  /// union.
+  bool isStandardLayoutUnionMember() const {
+    return data().IsStandardLayoutUnionMember;
+  }
+  void setIsStandardLayoutUnionMember(bool V = true) {
+    data().IsStandardLayoutUnionMember = V;
+  }
+
   /// Determine whether this class was standard-layout per
   /// C++11 [class]p7, specifically using the C++11 rules without any DRs.
   bool isCXX11StandardLayout() const { return data().IsCXX11StandardLayout; }
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index f0da56542ae7e..5f2ffcff0478a 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -76,7 +76,8 @@ void LazyASTUnresolvedSet::getFromExternalSource(ASTContext 
&C) const {
 CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
     : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0),
       Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
-      Abstract(false), IsStandardLayout(true), IsCXX11StandardLayout(true),
+      Abstract(false), IsStandardLayout(true),
+      IsStandardLayoutUnionMember(false), IsCXX11StandardLayout(true),
       HasBasesWithFields(false), HasBasesWithNonStaticDataMembers(false),
       HasPrivateFields(false), HasProtectedFields(false),
       HasPublicFields(false), HasMutableFields(false), 
HasVariantMembers(false),
@@ -2269,6 +2270,50 @@ static bool hasPureVirtualFinalOverrider(
   return false;
 }
 
+static void annotateStandardLayoutUnionMembers(const CXXRecordDecl *RD);
+
+static void annotateStandardLayoutUnionType(QualType QT) {
+  const auto *RT = QT->getAs<RecordType>();
+  if (!RT)
+    return;
+
+  auto *CRD = dyn_cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf());
+  if (!CRD || !CRD->hasDefinition())
+    return;
+
+  // We checked at the root that this is a standard-layout type, which
+  // requires all its members / base types to be standard-layout.
+  assert(CRD->isStandardLayout());
+
+  // If we already annotated this type as part of a standard layout union, we
+  // don't need to do it again.
+  if (CRD->isStandardLayoutUnionMember())
+    return;
+
+  CRD->setIsStandardLayoutUnionMember(true);
+  annotateStandardLayoutUnionMembers(CRD);
+}
+
+// Recursively marks all field and base class types of this union as members of
+// a standard layout union. This is meant to capture all types which may be
+// fungible via inspection of a member of a union.
+static void annotateStandardLayoutUnionMembers(const CXXRecordDecl *RD) {
+  for (const CXXBaseSpecifier &BS : RD->bases()) {
+    annotateStandardLayoutUnionType(BS.getType());
+  }
+  for (const FieldDecl *FD : RD->fields()) {
+    // Invalid declarations are skipped when determining the field layout of
+    // unions. This will of course cause a compiler error, but skip these
+    // fields anyway to avoid triggering the `isStandardLayout()` assertion in
+    // annotateStandardLayoutUnionType.
+    if (FD->isInvalidDecl())
+      continue;
+    annotateStandardLayoutUnionType(FD->getType()
+                                        ->getBaseElementTypeUnsafe()
+                                        ->getCanonicalTypeUnqualified());
+  }
+}
+
 void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
   RecordDecl::completeDefinition();
 
@@ -2321,6 +2366,9 @@ void 
CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
     data().IsStandardLayout = false;
     data().IsCXX11StandardLayout = false;
   }
+
+  if (isUnion() && isStandardLayout())
+    annotateStandardLayoutUnionMembers(this);
 }
 
 bool CXXRecordDecl::mayBeAbstract() const {
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 02864621d60a3..243961e26c516 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3244,6 +3244,17 @@ static bool canUseCtorHoming(const CXXRecordDecl *RD) {
       RD->hasConstexprNonCopyMoveConstructor())
     return false;
 
+  // Skip this optimization if this type is standard-layout and is a member of
+  // some standard-layout union in this translation unit. Per the C++ spec, "it
+  // is permitted to inspect the common initial part of any of" the "common
+  // initial sequence" of distinct types in a standard-layout union. This
+  // exception to strict aliasing enables producing a reference to a type
+  // without ever having constructed that type.
+  //
+  // See: https://timsong-cpp.github.io/cppwp/n3337/class.mem#19
+  if (RD->isStandardLayoutUnionMember())
+    return false;
+
   for (const CXXConstructorDecl *Ctor : RD->ctors()) {
     if (Ctor->isCopyOrMoveConstructor())
       continue;
diff --git a/clang/test/DebugInfo/CXX/limited-ctor.cpp 
b/clang/test/DebugInfo/CXX/limited-ctor.cpp
index e820c0703df4f..3fe1682358af2 100644
--- a/clang/test/DebugInfo/CXX/limited-ctor.cpp
+++ b/clang/test/DebugInfo/CXX/limited-ctor.cpp
@@ -53,7 +53,7 @@ struct DeclaredConstexpr {
 template <class A, class B> struct Aliased {
   A first;
   B second;
-  constexpr Aliased(const A &a, const B &b) : first(a), second(b) {}
+  Aliased(const A &a, const B &b) : first(a), second(b) {}
 };
 union AliasedSlot {
   Aliased<const int, int> value;
@@ -66,6 +66,24 @@ int ReadAliasedSlot() {
   return TestAliasedSlot.value.first;
 }
 
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"ConstexprAliased<int, int>"{{.*}}DIFlagTypePassByValue
+// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"ConstexprAliased<const int, int>"{{.*}}DIFlagTypePassByValue
+template <class A, class B> struct ConstexprAliased {
+  A first;
+  B second;
+  constexpr ConstexprAliased(const A &a, const B &b) : first(a), second(b) {}
+};
+union ConstexprAliasedSlot {
+  ConstexprAliased<const int, int> value;
+  ConstexprAliased<int, int> mutable_value;
+  ConstexprAliasedSlot() {}
+  ~ConstexprAliasedSlot() {}
+} TestConstexprAliasedSlot;
+int ReadConstexprAliasedSlot() {
+  TestConstexprAliasedSlot.mutable_value = ConstexprAliased<int, int>(1, 2);
+  return TestConstexprAliasedSlot.value.first;
+}
+
 // Defined out-of-line constexpr constructor should emit full debug info.
 // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: 
"OutOfLineConstexpr"{{.*}}DIFlagTypePassByValue
 struct OutOfLineConstexpr {
diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp
index 195b8ab4c4e66..fab4e9f499c9d 100644
--- a/clang/unittests/AST/DeclTest.cpp
+++ b/clang/unittests/AST/DeclTest.cpp
@@ -24,10 +24,12 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Linkage.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Frontend/ASTUnit.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Testing/Annotations/Annotations.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <cassert>
 #include <memory>
@@ -36,6 +38,14 @@
 using namespace clang::ast_matchers;
 using namespace clang::tooling;
 using namespace clang;
+using ::testing::AllOf;
+using ::testing::Not;
+using ::testing::Pointee;
+
+MATCHER(IsStandardLayout, "") { return arg.isStandardLayout(); }
+MATCHER(IsStandardLayoutUnionMember, "") {
+  return arg.isStandardLayoutUnionMember();
+}
 
 TEST(Decl, CleansUpAPValues) {
   MatchFinder Finder;
@@ -1029,3 +1039,390 @@ TEST(Decl, ObjCPropertyDeclNameForDiagnostic) {
                              /*Qualified=*/true);
   EXPECT_EQ(ExtPQualifiedOS.str(), "-[MyClass extensionProp]");
 }
+
+class StandardLayoutUnionMemberTest : public ::testing::Test {
+protected:
+  std::unique_ptr<ASTUnit> AST;
+  ASTContext *Ctx = nullptr;
+
+  void buildAST(StringRef Code, ArrayRef<std::string> Args = {"-std=c++11"}) {
+    AST = tooling::buildASTFromCodeWithArgs(Code, Args);
+    ASSERT_NE(AST, nullptr);
+    Ctx = &AST->getASTContext();
+  }
+
+  const CXXRecordDecl *findRecord(StringRef Name) const {
+    assert(Ctx && "ASTContext not initialized");
+    return selectFirst<CXXRecordDecl>(
+        "d",
+        match(cxxRecordDecl(hasName(Name), isDefinition()).bind("d"), *Ctx));
+  }
+
+  const CXXRecordDecl *findTemplate(StringRef Name,
+                                    StringRef TemplateArg) const {
+    assert(Ctx && "ASTContext not initialized");
+    return selectFirst<CXXRecordDecl>(
+        "d", match(classTemplateSpecializationDecl(
+                       hasName(Name), isDefinition(),
+                       hasTemplateArgument(
+                           0, refersToType(asString(TemplateArg.str()))))
+                       .bind("d"),
+                   *Ctx));
+  }
+
+  // Matches a standard-layout union member.
+  auto IsSLUnionMember() {
+    return Pointee(AllOf(IsStandardLayout(), IsStandardLayoutUnionMember()));
+  }
+
+  // Matches a standard-layout type that is not a member of a standard-layout
+  // union.
+  auto IsStandaloneSL() {
+    return Pointee(
+        AllOf(IsStandardLayout(), Not(IsStandardLayoutUnionMember())));
+  }
+
+  // Matches a non-standard-layout type.
+  auto IsNonSL() {
+    return Pointee(
+        AllOf(Not(IsStandardLayout()), Not(IsStandardLayoutUnionMember())));
+  }
+};
+
+TEST_F(StandardLayoutUnionMemberTest, StandaloneStruct) {
+  buildAST(R"cc(
+    struct StandaloneSL {
+      int x;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("StandaloneSL"), IsStandaloneSL());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, NonStandardLayoutStruct) {
+  buildAST(R"cc(
+    struct NonSL {
+      virtual void foo();
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("NonSL"), IsNonSL());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, StandardLayoutUnion) {
+  buildAST(R"cc(
+    struct SLInUnion {
+      int x;
+    };
+
+    union SLUnion {
+      SLInUnion u;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("SLUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("SLInUnion"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, RecurseFieldTypes) {
+  buildAST(R"cc(
+    struct SLMember {
+      int x;
+    };
+
+    struct SLInUnion {
+      SLMember x;
+    };
+
+    union SLUnion {
+      SLInUnion u;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("SLUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("SLInUnion"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("SLMember"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, TemplatedMember) {
+  buildAST(R"cc(
+    template <typename T>
+    struct TemplatedSL {
+      T x;
+    };
+
+    union TemplatedUnion {
+      TemplatedSL<int> a;
+      TemplatedSL<float> b;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("TemplatedUnion"), IsStandaloneSL());
+  EXPECT_THAT(findTemplate("TemplatedSL", "int"), IsSLUnionMember());
+  EXPECT_THAT(findTemplate("TemplatedSL", "float"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, NonStandardLayoutUnion) {
+  buildAST(R"cc(
+    struct NonSL {
+      virtual void foo();
+    };
+
+    struct SLInNonSLUnion {
+      int x;
+    };
+
+    union NonSLUnion {
+      SLInNonSLUnion s;
+      NonSL n;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("NonSLUnion"), Pointee(Not(IsStandardLayout())));
+  EXPECT_THAT(findRecord("NonSL"), IsNonSL());
+  EXPECT_THAT(findRecord("SLInNonSLUnion"), IsStandaloneSL());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, NestedStruct) {
+  buildAST(R"cc(
+    union NestedUnion {
+      struct NestedSL {
+        int a;
+      } n;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("NestedUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("NestedSL"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, Array) {
+  buildAST(R"cc(
+    struct SLInArray {
+      int x;
+    };
+    struct SLInMultiArray {
+      int y;
+    };
+    union ArrayUnion {
+      SLInArray arr[3];
+      SLInMultiArray multi_arr[2][4];
+      int raw;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("ArrayUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("SLInArray"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("SLInMultiArray"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, CVQualified) {
+  buildAST(R"cc(
+    struct SLConst {
+      int x;
+    };
+    struct SLVolatile {
+      int y;
+    };
+    union CVUnion {
+      const SLConst c;
+      volatile SLVolatile v;
+      int raw;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("CVUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("SLConst"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("SLVolatile"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, GenericUnionTemplate) {
+  buildAST(R"cc(
+    template <typename T>
+    union GenericUnion {
+      T val;
+      int raw;
+    };
+    struct SLInGenericUnion {
+      int x;
+    };
+    GenericUnion<SLInGenericUnion> u;
+  )cc");
+
+  EXPECT_THAT(findRecord("SLInGenericUnion"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, AnonymousUnion) {
+  buildAST(R"cc(
+    struct SLInAnonUnion {
+      int x;
+    };
+    struct EnclosingStruct {
+      union {
+        SLInAnonUnion a;
+        int b;
+      };
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("SLInAnonUnion"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, Inheritance) {
+  buildAST(R"cc(
+    struct EmptyBase {};
+    struct SLDerived : EmptyBase {
+      int x;
+    };
+    union DerivedUnion {
+      SLDerived d;
+      int raw;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("DerivedUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("SLDerived"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("EmptyBase"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, TypedefInheritance) {
+  buildAST(R"cc(
+    typedef struct EmptyBase {} EmptyBaseAlias;
+    struct SLDerived : EmptyBaseAlias {
+      int y;
+    };
+    union DerivedUnion {
+      SLDerived d;
+      int raw;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("DerivedUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("SLDerived"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("EmptyBase"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, MultipleInheritance) {
+  buildAST(R"cc(
+    struct EmptyBase1 {};
+    struct EmptyBase2 {};
+    struct SLDerived : EmptyBase1, EmptyBase2 {
+      int x;
+    };
+    union DerivedUnion {
+      SLDerived d;
+      int raw;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("DerivedUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("SLDerived"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("EmptyBase1"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("EmptyBase2"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, InheritanceNonEmptyBase) {
+  buildAST(R"cc(
+    struct SLBase {
+      int y;
+    };
+    struct EmptyDerived : SLBase {};
+    union DerivedUnion {
+      EmptyDerived d;
+      int raw;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("DerivedUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("EmptyDerived"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("SLBase"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, TypedefInheritanceNonEmptyBase) {
+  buildAST(R"cc(
+    typedef struct SLBase {
+      int y;
+    } SLBaseAlias;
+    struct EmptyDerived : SLBaseAlias {};
+    union DerivedUnion {
+      EmptyDerived d;
+      int raw;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("DerivedUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("EmptyDerived"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("SLBase"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, RecurseInheritance) {
+  buildAST(R"cc(
+    struct SLBaseMember {
+      int x;
+    };
+    struct SLBase {
+      SLBaseMember y;
+    };
+    struct EmptyDerived : SLBase {};
+    union DerivedUnion {
+      EmptyDerived d;
+      int raw;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("DerivedUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("EmptyDerived"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("SLBase"), IsSLUnionMember());
+  EXPECT_THAT(findRecord("SLBaseMember"), IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, AnonymousTypedefStruct) {
+  buildAST(R"cc(
+    typedef struct {
+      int x;
+    } AnonTypedefSL;
+
+    union AnonTypedefUnion {
+      AnonTypedefSL s;
+      int raw;
+    };
+  )cc");
+
+  const auto *TD = selectFirst<TypedefDecl>(
+      "d", match(typedefDecl(hasName("AnonTypedefSL")).bind("d"), *Ctx));
+  ASSERT_NE(TD, nullptr);
+  const auto *AnonRecord = TD->getUnderlyingType()->getAsCXXRecordDecl();
+
+  EXPECT_THAT(findRecord("AnonTypedefUnion"), IsStandaloneSL());
+  EXPECT_THAT(AnonRecord, IsSLUnionMember());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, IgnorePointerMembers) {
+  buildAST(R"cc(
+    struct SLPointerInUnion {
+      int x;
+    };
+
+    union SLUnion {
+      SLPointerInUnion* u;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("SLUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("SLPointerInUnion"), IsStandaloneSL());
+}
+
+TEST_F(StandardLayoutUnionMemberTest, IgnoreReferenceMembers) {
+  buildAST(R"cc(
+    struct SLReferenceInUnion {
+      int x;
+    };
+
+    union SLUnion {
+      SLReferenceInUnion& u;
+    };
+  )cc");
+
+  EXPECT_THAT(findRecord("SLUnion"), IsStandaloneSL());
+  EXPECT_THAT(findRecord("SLReferenceInUnion"), IsStandaloneSL());
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to