Skip to content

Conversation

@BStott6
Copy link
Contributor

@BStott6 BStott6 commented Dec 8, 2025

This PR is intending to improve this and potentially enable more optimizations by adding TBAA metadata to the fields of structs returned directly (not via sret pointer) and where the returned struct matches the RecordDecl's struct layout (this is not always true).

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Dec 8, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 8, 2025

@llvm/pr-subscribers-clang

Author: Benjamin Stott (BStott6)

Changes

This PR is intending to improve this and potentially enable more optimizations by adding TBAA metadata to the fields of structs returned directly (not via sret pointer) and where the returned struct matches the RecordDecl's struct layout (this is not always true).


Full diff: https://github.com/llvm/llvm-project/pull/171173.diff

6 Files Affected:

  • (modified) clang/lib/CodeGen/CGCall.cpp (+71-3)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+5-32)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+2-1)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+42)
  • (modified) clang/lib/CodeGen/CodeGenModule.h (+5)
  • (added) clang/test/CodeGen/tbaa-returned-struct.cpp (+37)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index efacb3cc04c01..a35cab83fd286 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -44,12 +44,49 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Transforms/Utils/Local.h"
+#include <algorithm>
 #include <optional>
 using namespace clang;
 using namespace CodeGen;
 
 /***/
 
+namespace {
+/// Creates a table of `FieldDecl` pointers for each `llvm::StructTy` element
+/// no, by working backwards from the `CGRecordLayout`.
+class LLVMToClangFieldLookup {
+public:
+  LLVMToClangFieldLookup(const llvm::StructType *LLVMType,
+                         const RecordDecl *RDecl, const CGRecordLayout &RLayout)
+      : Table(LLVMType->getNumElements(), nullptr) {
+    for (const auto *FDecl : RDecl->fields()) {
+      if (!isa<FieldDecl>(FDecl))
+        continue;
+      if (!RLayout.containsFieldDecl(FDecl))
+        continue;
+
+      unsigned FieldIndex = RLayout.getLLVMFieldNo(FDecl);
+      assert(FieldIndex < Table.size() &&
+             "Field index should not exceed num elements");
+
+      if (!Table[FieldIndex]) {
+        // If several LLVM fields correspond to the same Clang FieldDecl,
+        // arbitrarily pick the first.
+        Table[FieldIndex] = FDecl;
+      }
+    }
+  }
+
+  const FieldDecl *getFieldDeclForFieldNo(unsigned FieldNo) {
+    assert(FieldNo < Table.size());
+    return Table[FieldNo];
+  }
+
+private:
+  SmallVector<const FieldDecl *, 16> Table;
+};
+} // namespace
+
 unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
   switch (CC) {
   default:
@@ -1398,7 +1435,8 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
 
 void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
                                          llvm::TypeSize DstSize,
-                                         bool DstIsVolatile) {
+                                         bool DstIsVolatile,
+                                         std::optional<QualType> QTy) {
   if (!DstSize)
     return;
 
@@ -1426,6 +1464,22 @@ void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
       addInstToCurrentSourceAtom(I, Src);
     } else if (llvm::StructType *STy =
                    dyn_cast<llvm::StructType>(Src->getType())) {
+      // For TBAA metadata, get the record layout
+      std::optional<LLVMToClangFieldLookup> FieldLookupForTBAA;
+      if (QTy && CGM.shouldUseTBAA()) {
+        if (const RecordDecl *RDecl = (*QTy)->getAsRecordDecl()) {
+          const CGRecordLayout &RLayout =
+              CGM.getTypes().getCGRecordLayout(RDecl);
+
+          if (RLayout.getLLVMType()->isLayoutIdentical(STy)) {
+            // There are cases where the returned LLVM struct type does not
+            // match the LLVM type corresponding to the record's layout, so we
+            // can't use it to work out the correct TBAA metadata.
+            FieldLookupForTBAA.emplace(STy, RDecl, RLayout);
+          }
+        }
+      }
+
       // Prefer scalar stores to first-class aggregate stores.
       Dst = Dst.withElementType(SrcTy);
       for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
@@ -1433,6 +1487,21 @@ void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
         llvm::Value *Elt = Builder.CreateExtractValue(Src, i);
         auto *I = Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
         addInstToCurrentSourceAtom(I, Elt);
+
+        if (FieldLookupForTBAA) {
+          // Try to find the field declaration corresponding to this struct
+          // element no.
+          const FieldDecl *FDecl =
+              FieldLookupForTBAA->getFieldDeclForFieldNo(i);
+
+          if (FDecl && FDecl->getType()->isScalarType()) {
+            // FIXME Decide on a way to add TBAA MD for store to an aggregate
+            // type. Currently, TBAA MD requires that the access type is a
+            // scalar.
+            CGM.DecorateInstructionWithTBAA(
+                I, CGM.getTBAAInfoForField(TBAAAccessInfo(), *QTy, FDecl));
+          }
+        }
       }
     } else {
       auto *I =
@@ -6235,9 +6304,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
           CreateCoercedStore(
               CI, StorePtr,
               llvm::TypeSize::getFixed(DestSize - RetAI.getDirectOffset()),
-              DestIsVolatile);
+              DestIsVolatile, RetTy);
         }
-
         return convertTempToRValue(DestPtr, RetTy, SourceLocation());
       }
 
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c8f669b69d991..65200a9a3dec7 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5390,38 +5390,8 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
   // and unions.
   QualType FieldType = field->getType();
   const RecordDecl *rec = field->getParent();
-  AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource();
-  LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource));
-  TBAAAccessInfo FieldTBAAInfo;
-  if (base.getTBAAInfo().isMayAlias() ||
-          rec->hasAttr<MayAliasAttr>() || FieldType->isVectorType()) {
-    FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
-  } else if (rec->isUnion()) {
-    // TODO: Support TBAA for unions.
-    FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
-  } else {
-    // If no base type been assigned for the base access, then try to generate
-    // one for this base lvalue.
-    FieldTBAAInfo = base.getTBAAInfo();
-    if (!FieldTBAAInfo.BaseType) {
-        FieldTBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(base.getType());
-        assert(!FieldTBAAInfo.Offset &&
-               "Nonzero offset for an access with no base type!");
-    }
-
-    // Adjust offset to be relative to the base type.
-    const ASTRecordLayout &Layout =
-        getContext().getASTRecordLayout(field->getParent());
-    unsigned CharWidth = getContext().getCharWidth();
-    if (FieldTBAAInfo.BaseType)
-      FieldTBAAInfo.Offset +=
-          Layout.getFieldOffset(field->getFieldIndex()) / CharWidth;
-
-    // Update the final access type and size.
-    FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType);
-    FieldTBAAInfo.Size =
-        getContext().getTypeSizeInChars(FieldType).getQuantity();
-  }
+  TBAAAccessInfo FieldTBAAInfo =
+      CGM.getTBAAInfoForField(base.getTBAAInfo(), base.getType(), field);
 
   Address addr = base.getAddress();
   if (hasBPFPreserveStaticOffset(rec))
@@ -5472,6 +5442,9 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
       addr = emitPreserveStructAccess(*this, base, addr, field);
   }
 
+  AlignmentSource BaseAlignSource = base.getBaseInfo().getAlignmentSource();
+  LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource));
+
   // If this is a reference field, load the reference right now.
   if (FieldType->isReferenceType()) {
     LValue RefLVal =
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 8c4c1c8c2dc95..b7fbec3152be9 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -5038,7 +5038,8 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// Create a store to \arg DstPtr from \arg Src, truncating the stored value
   /// to at most \arg DstSize bytes.
   void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize,
-                          bool DstIsVolatile);
+                          bool DstIsVolatile,
+                          std::optional<QualType> QTy = std::nullopt);
 
   /// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
   /// make sure it survives garbage collection until this point.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4789c6b26797f..ec421eb91f0c4 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1720,6 +1720,48 @@ CodeGenModule::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
   return TBAA->mergeTBAAInfoForConditionalOperator(DestInfo, SrcInfo);
 }
 
+TBAAAccessInfo CodeGenModule::getTBAAInfoForField(TBAAAccessInfo BaseTBAAInfo,
+                                                  QualType BaseType,
+                                                  const FieldDecl *Field) {
+  // Fields of may-alias structures are may-alias themselves.
+  // FIXME: this should get propagated down through anonymous structs
+  // and unions.
+  const RecordDecl *Rec = Field->getParent();
+  QualType FieldType = Field->getType();
+  TBAAAccessInfo FieldTBAAInfo;
+  if (BaseTBAAInfo.isMayAlias() || Rec->hasAttr<MayAliasAttr>() ||
+      FieldType->isVectorType()) {
+    FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
+  } else if (Rec->isUnion()) {
+    // TODO: Support TBAA for unions.
+    FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
+  } else {
+    // If no base type been assigned for the base access, then try to generate
+    // one for this base lvalue.
+    FieldTBAAInfo = BaseTBAAInfo;
+    if (!FieldTBAAInfo.BaseType) {
+      FieldTBAAInfo.BaseType = getTBAABaseTypeInfo(BaseType);
+      assert(!FieldTBAAInfo.Offset &&
+             "Nonzero offset for an access with no base type!");
+    }
+
+    // Adjust offset to be relative to the base type.
+    const ASTRecordLayout &Layout =
+        getContext().getASTRecordLayout(Field->getParent());
+    unsigned CharWidth = getContext().getCharWidth();
+    if (FieldTBAAInfo.BaseType)
+      FieldTBAAInfo.Offset +=
+          Layout.getFieldOffset(Field->getFieldIndex()) / CharWidth;
+
+    // Update the final access type and size.
+    FieldTBAAInfo.AccessType = getTBAATypeInfo(FieldType);
+    FieldTBAAInfo.Size =
+        getContext().getTypeSizeInChars(FieldType).getQuantity();
+  }
+
+  return FieldTBAAInfo;
+}
+
 void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst,
                                                 TBAAAccessInfo TBAAInfo) {
   if (llvm::MDNode *Tag = getTBAAAccessTagInfo(TBAAInfo))
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index a253bcda2d06c..1dc53c792230a 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -909,6 +909,11 @@ class CodeGenModule : public CodeGenTypeCache {
     return getTBAAAccessInfo(AccessType);
   }
 
+  /// getTBAAInfoForSubobject - Get TBAA information for an access to a field in
+  /// a record.
+  TBAAAccessInfo getTBAAInfoForField(TBAAAccessInfo BaseTBAAInfo,
+                                     QualType BaseType, const FieldDecl *Field);
+
   bool isPaddedAtomicType(QualType type);
   bool isPaddedAtomicType(const AtomicType *type);
 
diff --git a/clang/test/CodeGen/tbaa-returned-struct.cpp b/clang/test/CodeGen/tbaa-returned-struct.cpp
new file mode 100644
index 0000000000000..e276488b63c46
--- /dev/null
+++ b/clang/test/CodeGen/tbaa-returned-struct.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple x86_64-linux-unknown -emit-llvm -o - -O1 -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK
+
+// Checking that we generate TBAA metadata for returned aggregates.
+// Currently, TBAA metadata is only emitted when structs are returned directly and the returned LLVM struct exactly matches the LLVM struct representation of the type.
+// We should update this test when TBAA metadata is added for more cases. Cases which aren't covered include:
+//  - Direct return as scalar (e.g. { int x; int y; } returned as i64)
+//  - Indirect return via sret pointer
+
+struct S1 {
+    // Currently, only structs small enough to be returned directly, but large enough not to be returned as a scalar, will get TBAA metadata.
+    long x;
+    double y;
+};
+
+S1 returns_s1() {
+    return S1 {1, 2};
+}
+
+void receives_s1() {
+    S1 x = returns_s1();
+// CHECK: define dso_local void @_Z11receives_s1v()
+// CHECK: %call = call { i64, double } @_Z10returns_s1v()
+// CHECK-NEXT: %0 = getelementptr inbounds nuw { i64, double }, ptr %x, i32 0, i32 0
+// CHECK-NEXT: %1 = extractvalue { i64, double } %call, 0
+// CHECK-NEXT: store i64 %1, ptr %0, align 8, !tbaa ![[TBAA_LONG_IN_S1:[0-9]+]]
+// CHECK-NEXT: %2 = getelementptr inbounds nuw { i64, double }, ptr %x, i32 0, i32 1
+// CHECK-NEXT: %3 = extractvalue { i64, double } %call, 1
+// CHECK-NEXT: store double %3, ptr %2, align 8, !tbaa ![[TBAA_DOUBLE_IN_S1:[0-9]+]]
+}
+
+// Validate TBAA MD
+// CHECK-DAG: ![[TBAA_CHAR:[0-9]+]] = !{!"omnipotent char",
+// CHECK-DAG: ![[TBAA_LONG:[0-9]+]] = !{!"long", ![[TBAA_CHAR]], i64 0}
+// CHECK-DAG: ![[TBAA_DOUBLE:[0-9]+]] = !{!"double", ![[TBAA_CHAR]], i64 0}
+// CHECK-DAG: ![[TBAA_S1:[0-9]+]] = !{!"_ZTS2S1", ![[TBAA_LONG]], i64 0, ![[TBAA_DOUBLE]], i64 8}
+// CHECK-DAG: ![[TBAA_LONG_IN_S1]] = !{![[TBAA_S1]], ![[TBAA_LONG]], i64 0}
+// CHECK-DAG: ![[TBAA_DOUBLE_IN_S1]] = !{![[TBAA_S1]], ![[TBAA_DOUBLE]], i64 8}

@llvmbot
Copy link
Member

llvmbot commented Dec 8, 2025

@llvm/pr-subscribers-clang-codegen

Author: Benjamin Stott (BStott6)

Changes

This PR is intending to improve this and potentially enable more optimizations by adding TBAA metadata to the fields of structs returned directly (not via sret pointer) and where the returned struct matches the RecordDecl's struct layout (this is not always true).


Full diff: https://github.com/llvm/llvm-project/pull/171173.diff

6 Files Affected:

  • (modified) clang/lib/CodeGen/CGCall.cpp (+71-3)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+5-32)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+2-1)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+42)
  • (modified) clang/lib/CodeGen/CodeGenModule.h (+5)
  • (added) clang/test/CodeGen/tbaa-returned-struct.cpp (+37)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index efacb3cc04c01..a35cab83fd286 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -44,12 +44,49 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Transforms/Utils/Local.h"
+#include <algorithm>
 #include <optional>
 using namespace clang;
 using namespace CodeGen;
 
 /***/
 
+namespace {
+/// Creates a table of `FieldDecl` pointers for each `llvm::StructTy` element
+/// no, by working backwards from the `CGRecordLayout`.
+class LLVMToClangFieldLookup {
+public:
+  LLVMToClangFieldLookup(const llvm::StructType *LLVMType,
+                         const RecordDecl *RDecl, const CGRecordLayout &RLayout)
+      : Table(LLVMType->getNumElements(), nullptr) {
+    for (const auto *FDecl : RDecl->fields()) {
+      if (!isa<FieldDecl>(FDecl))
+        continue;
+      if (!RLayout.containsFieldDecl(FDecl))
+        continue;
+
+      unsigned FieldIndex = RLayout.getLLVMFieldNo(FDecl);
+      assert(FieldIndex < Table.size() &&
+             "Field index should not exceed num elements");
+
+      if (!Table[FieldIndex]) {
+        // If several LLVM fields correspond to the same Clang FieldDecl,
+        // arbitrarily pick the first.
+        Table[FieldIndex] = FDecl;
+      }
+    }
+  }
+
+  const FieldDecl *getFieldDeclForFieldNo(unsigned FieldNo) {
+    assert(FieldNo < Table.size());
+    return Table[FieldNo];
+  }
+
+private:
+  SmallVector<const FieldDecl *, 16> Table;
+};
+} // namespace
+
 unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
   switch (CC) {
   default:
@@ -1398,7 +1435,8 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
 
 void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
                                          llvm::TypeSize DstSize,
-                                         bool DstIsVolatile) {
+                                         bool DstIsVolatile,
+                                         std::optional<QualType> QTy) {
   if (!DstSize)
     return;
 
@@ -1426,6 +1464,22 @@ void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
       addInstToCurrentSourceAtom(I, Src);
     } else if (llvm::StructType *STy =
                    dyn_cast<llvm::StructType>(Src->getType())) {
+      // For TBAA metadata, get the record layout
+      std::optional<LLVMToClangFieldLookup> FieldLookupForTBAA;
+      if (QTy && CGM.shouldUseTBAA()) {
+        if (const RecordDecl *RDecl = (*QTy)->getAsRecordDecl()) {
+          const CGRecordLayout &RLayout =
+              CGM.getTypes().getCGRecordLayout(RDecl);
+
+          if (RLayout.getLLVMType()->isLayoutIdentical(STy)) {
+            // There are cases where the returned LLVM struct type does not
+            // match the LLVM type corresponding to the record's layout, so we
+            // can't use it to work out the correct TBAA metadata.
+            FieldLookupForTBAA.emplace(STy, RDecl, RLayout);
+          }
+        }
+      }
+
       // Prefer scalar stores to first-class aggregate stores.
       Dst = Dst.withElementType(SrcTy);
       for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
@@ -1433,6 +1487,21 @@ void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
         llvm::Value *Elt = Builder.CreateExtractValue(Src, i);
         auto *I = Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
         addInstToCurrentSourceAtom(I, Elt);
+
+        if (FieldLookupForTBAA) {
+          // Try to find the field declaration corresponding to this struct
+          // element no.
+          const FieldDecl *FDecl =
+              FieldLookupForTBAA->getFieldDeclForFieldNo(i);
+
+          if (FDecl && FDecl->getType()->isScalarType()) {
+            // FIXME Decide on a way to add TBAA MD for store to an aggregate
+            // type. Currently, TBAA MD requires that the access type is a
+            // scalar.
+            CGM.DecorateInstructionWithTBAA(
+                I, CGM.getTBAAInfoForField(TBAAAccessInfo(), *QTy, FDecl));
+          }
+        }
       }
     } else {
       auto *I =
@@ -6235,9 +6304,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
           CreateCoercedStore(
               CI, StorePtr,
               llvm::TypeSize::getFixed(DestSize - RetAI.getDirectOffset()),
-              DestIsVolatile);
+              DestIsVolatile, RetTy);
         }
-
         return convertTempToRValue(DestPtr, RetTy, SourceLocation());
       }
 
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c8f669b69d991..65200a9a3dec7 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5390,38 +5390,8 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
   // and unions.
   QualType FieldType = field->getType();
   const RecordDecl *rec = field->getParent();
-  AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource();
-  LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource));
-  TBAAAccessInfo FieldTBAAInfo;
-  if (base.getTBAAInfo().isMayAlias() ||
-          rec->hasAttr<MayAliasAttr>() || FieldType->isVectorType()) {
-    FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
-  } else if (rec->isUnion()) {
-    // TODO: Support TBAA for unions.
-    FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
-  } else {
-    // If no base type been assigned for the base access, then try to generate
-    // one for this base lvalue.
-    FieldTBAAInfo = base.getTBAAInfo();
-    if (!FieldTBAAInfo.BaseType) {
-        FieldTBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(base.getType());
-        assert(!FieldTBAAInfo.Offset &&
-               "Nonzero offset for an access with no base type!");
-    }
-
-    // Adjust offset to be relative to the base type.
-    const ASTRecordLayout &Layout =
-        getContext().getASTRecordLayout(field->getParent());
-    unsigned CharWidth = getContext().getCharWidth();
-    if (FieldTBAAInfo.BaseType)
-      FieldTBAAInfo.Offset +=
-          Layout.getFieldOffset(field->getFieldIndex()) / CharWidth;
-
-    // Update the final access type and size.
-    FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType);
-    FieldTBAAInfo.Size =
-        getContext().getTypeSizeInChars(FieldType).getQuantity();
-  }
+  TBAAAccessInfo FieldTBAAInfo =
+      CGM.getTBAAInfoForField(base.getTBAAInfo(), base.getType(), field);
 
   Address addr = base.getAddress();
   if (hasBPFPreserveStaticOffset(rec))
@@ -5472,6 +5442,9 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
       addr = emitPreserveStructAccess(*this, base, addr, field);
   }
 
+  AlignmentSource BaseAlignSource = base.getBaseInfo().getAlignmentSource();
+  LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource));
+
   // If this is a reference field, load the reference right now.
   if (FieldType->isReferenceType()) {
     LValue RefLVal =
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 8c4c1c8c2dc95..b7fbec3152be9 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -5038,7 +5038,8 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// Create a store to \arg DstPtr from \arg Src, truncating the stored value
   /// to at most \arg DstSize bytes.
   void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize,
-                          bool DstIsVolatile);
+                          bool DstIsVolatile,
+                          std::optional<QualType> QTy = std::nullopt);
 
   /// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
   /// make sure it survives garbage collection until this point.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4789c6b26797f..ec421eb91f0c4 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1720,6 +1720,48 @@ CodeGenModule::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
   return TBAA->mergeTBAAInfoForConditionalOperator(DestInfo, SrcInfo);
 }
 
+TBAAAccessInfo CodeGenModule::getTBAAInfoForField(TBAAAccessInfo BaseTBAAInfo,
+                                                  QualType BaseType,
+                                                  const FieldDecl *Field) {
+  // Fields of may-alias structures are may-alias themselves.
+  // FIXME: this should get propagated down through anonymous structs
+  // and unions.
+  const RecordDecl *Rec = Field->getParent();
+  QualType FieldType = Field->getType();
+  TBAAAccessInfo FieldTBAAInfo;
+  if (BaseTBAAInfo.isMayAlias() || Rec->hasAttr<MayAliasAttr>() ||
+      FieldType->isVectorType()) {
+    FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
+  } else if (Rec->isUnion()) {
+    // TODO: Support TBAA for unions.
+    FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
+  } else {
+    // If no base type been assigned for the base access, then try to generate
+    // one for this base lvalue.
+    FieldTBAAInfo = BaseTBAAInfo;
+    if (!FieldTBAAInfo.BaseType) {
+      FieldTBAAInfo.BaseType = getTBAABaseTypeInfo(BaseType);
+      assert(!FieldTBAAInfo.Offset &&
+             "Nonzero offset for an access with no base type!");
+    }
+
+    // Adjust offset to be relative to the base type.
+    const ASTRecordLayout &Layout =
+        getContext().getASTRecordLayout(Field->getParent());
+    unsigned CharWidth = getContext().getCharWidth();
+    if (FieldTBAAInfo.BaseType)
+      FieldTBAAInfo.Offset +=
+          Layout.getFieldOffset(Field->getFieldIndex()) / CharWidth;
+
+    // Update the final access type and size.
+    FieldTBAAInfo.AccessType = getTBAATypeInfo(FieldType);
+    FieldTBAAInfo.Size =
+        getContext().getTypeSizeInChars(FieldType).getQuantity();
+  }
+
+  return FieldTBAAInfo;
+}
+
 void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst,
                                                 TBAAAccessInfo TBAAInfo) {
   if (llvm::MDNode *Tag = getTBAAAccessTagInfo(TBAAInfo))
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index a253bcda2d06c..1dc53c792230a 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -909,6 +909,11 @@ class CodeGenModule : public CodeGenTypeCache {
     return getTBAAAccessInfo(AccessType);
   }
 
+  /// getTBAAInfoForSubobject - Get TBAA information for an access to a field in
+  /// a record.
+  TBAAAccessInfo getTBAAInfoForField(TBAAAccessInfo BaseTBAAInfo,
+                                     QualType BaseType, const FieldDecl *Field);
+
   bool isPaddedAtomicType(QualType type);
   bool isPaddedAtomicType(const AtomicType *type);
 
diff --git a/clang/test/CodeGen/tbaa-returned-struct.cpp b/clang/test/CodeGen/tbaa-returned-struct.cpp
new file mode 100644
index 0000000000000..e276488b63c46
--- /dev/null
+++ b/clang/test/CodeGen/tbaa-returned-struct.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple x86_64-linux-unknown -emit-llvm -o - -O1 -disable-llvm-passes %s | FileCheck %s --check-prefixes=CHECK
+
+// Checking that we generate TBAA metadata for returned aggregates.
+// Currently, TBAA metadata is only emitted when structs are returned directly and the returned LLVM struct exactly matches the LLVM struct representation of the type.
+// We should update this test when TBAA metadata is added for more cases. Cases which aren't covered include:
+//  - Direct return as scalar (e.g. { int x; int y; } returned as i64)
+//  - Indirect return via sret pointer
+
+struct S1 {
+    // Currently, only structs small enough to be returned directly, but large enough not to be returned as a scalar, will get TBAA metadata.
+    long x;
+    double y;
+};
+
+S1 returns_s1() {
+    return S1 {1, 2};
+}
+
+void receives_s1() {
+    S1 x = returns_s1();
+// CHECK: define dso_local void @_Z11receives_s1v()
+// CHECK: %call = call { i64, double } @_Z10returns_s1v()
+// CHECK-NEXT: %0 = getelementptr inbounds nuw { i64, double }, ptr %x, i32 0, i32 0
+// CHECK-NEXT: %1 = extractvalue { i64, double } %call, 0
+// CHECK-NEXT: store i64 %1, ptr %0, align 8, !tbaa ![[TBAA_LONG_IN_S1:[0-9]+]]
+// CHECK-NEXT: %2 = getelementptr inbounds nuw { i64, double }, ptr %x, i32 0, i32 1
+// CHECK-NEXT: %3 = extractvalue { i64, double } %call, 1
+// CHECK-NEXT: store double %3, ptr %2, align 8, !tbaa ![[TBAA_DOUBLE_IN_S1:[0-9]+]]
+}
+
+// Validate TBAA MD
+// CHECK-DAG: ![[TBAA_CHAR:[0-9]+]] = !{!"omnipotent char",
+// CHECK-DAG: ![[TBAA_LONG:[0-9]+]] = !{!"long", ![[TBAA_CHAR]], i64 0}
+// CHECK-DAG: ![[TBAA_DOUBLE:[0-9]+]] = !{!"double", ![[TBAA_CHAR]], i64 0}
+// CHECK-DAG: ![[TBAA_S1:[0-9]+]] = !{!"_ZTS2S1", ![[TBAA_LONG]], i64 0, ![[TBAA_DOUBLE]], i64 8}
+// CHECK-DAG: ![[TBAA_LONG_IN_S1]] = !{![[TBAA_S1]], ![[TBAA_LONG]], i64 0}
+// CHECK-DAG: ![[TBAA_DOUBLE_IN_S1]] = !{![[TBAA_S1]], ![[TBAA_DOUBLE]], i64 8}

@github-actions
Copy link

github-actions bot commented Dec 8, 2025

🐧 Linux x64 Test Results

  • 84972 tests passed
  • 1150 tests skipped
  • 1 test failed

Failed Tests

(click on a test name to see its output)

lldb-api

lldb-api.tools/lldb-dap/output/TestDAP_output.py
Script:
--
/usr/bin/python3 /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --env LLVM_INCLUDE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include --env LLVM_TOOLS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --libcxx-include-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/c++/v1 --libcxx-include-target-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/x86_64-unknown-linux-gnu/c++/v1 --libcxx-library-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib/x86_64-unknown-linux-gnu --arch x86_64 --build-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex --lldb-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/lldb --compiler /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/clang --dsymutil /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --lldb-obj-root /home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb --lldb-libs-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --cmake-build-type Release /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/tools/lldb-dap/output -p TestDAP_output.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 22.0.0git (https://github.com/llvm/llvm-project revision 55b1de5078481bfd17d17f9fac5c86206fed7ab1)
  clang revision 55b1de5078481bfd17d17f9fac5c86206fed7ab1
  llvm revision 55b1de5078481bfd17d17f9fac5c86206fed7ab1
Skipping the following test categories: msvcstl, dsym, pdb, gmodules, debugserver, objc

--
Command Output (stderr):
--
========= DEBUG ADAPTER PROTOCOL LOGS =========
FAIL: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_output (TestDAP_output.TestDAP_output.test_output)
[18:24:22.733] (stdio) --> {"command":"initialize","type":"request","arguments":{"adapterID":"lldb-native","clientID":"vscode","columnsStartAt1":true,"linesStartAt1":true,"locale":"en-us","pathFormat":"path","supportsRunInTerminalRequest":true,"supportsVariablePaging":true,"supportsVariableType":true,"supportsStartDebuggingRequest":true,"supportsProgressReporting":true,"supportsInvalidatedEvent":true,"supportsMemoryEvent":true,"$__lldb_sourceInitFile":false},"seq":1}
[18:24:22.733] DAP.cpp:1007 (stdio) queued (command=initialize seq=1)
[18:24:22.734] (stdio) <-- {"body":{"$__lldb_version":"lldb version 22.0.0git (https://github.com/llvm/llvm-project revision 55b1de5078481bfd17d17f9fac5c86206fed7ab1)\n  clang revision 55b1de5078481bfd17d17f9fac5c86206fed7ab1\n  llvm revision 55b1de5078481bfd17d17f9fac5c86206fed7ab1","completionTriggerCharacters":["."," ","\t"],"exceptionBreakpointFilters":[{"description":"C++ Catch","filter":"cpp_catch","label":"C++ Catch","supportsCondition":true},{"description":"C++ Throw","filter":"cpp_throw","label":"C++ Throw","supportsCondition":true},{"description":"Objective-C Catch","filter":"objc_catch","label":"Objective-C Catch","supportsCondition":true},{"description":"Objective-C Throw","filter":"objc_throw","label":"Objective-C Throw","supportsCondition":true}],"supportTerminateDebuggee":true,"supportsBreakpointLocationsRequest":true,"supportsCancelRequest":true,"supportsCompletionsRequest":true,"supportsConditionalBreakpoints":true,"supportsConfigurationDoneRequest":true,"supportsDataBreakpointBytes":true,"supportsDataBreakpoints":true,"supportsDelayedStackTraceLoading":true,"supportsDisassembleRequest":true,"supportsEvaluateForHovers":true,"supportsExceptionFilterOptions":true,"supportsExceptionInfoRequest":true,"supportsFunctionBreakpoints":true,"supportsHitConditionalBreakpoints":true,"supportsInstructionBreakpoints":true,"supportsLogPoints":true,"supportsModuleSymbolsRequest":true,"supportsModulesRequest":true,"supportsReadMemoryRequest":true,"supportsSetVariable":true,"supportsSteppingGranularity":true,"supportsValueFormattingOptions":true,"supportsWriteMemoryRequest":true},"command":"initialize","request_seq":1,"seq":1,"success":true,"type":"response"}
[18:24:22.734] (stdio) --> {"command":"launch","type":"request","arguments":{"program":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/tools/lldb-dap/output/TestDAP_output.test_output/a.out","initCommands":["settings clear --all","settings set symbols.enable-external-lookup false","settings set target.inherit-tcc true","settings set target.disable-aslr false","settings set target.detach-on-error false","settings set target.auto-apply-fixits false","settings set plugin.process.gdb-remote.packet-timeout 60","settings set symbols.clang-modules-cache-path \"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api\"","settings set use-color false","settings set show-statusline false"],"exitCommands":["?script print('out\\0\\0', end='\\r\\n', file=sys.stdout)","?script print('err\\0\\0', end='\\r\\n', file=sys.stderr)"],"disableASLR":false,"enableAutoVariableSummaries":false,"enableSyntheticChildDebugging":false,"displayExtendedBacktrace":false},"seq":2}
[18:24:22.734] DAP.cpp:1007 (stdio) queued (command=launch seq=2)
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"Running initCommands:\n"},"event":"output","seq":2,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings clear --all\n"},"event":"output","seq":3,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set symbols.enable-external-lookup false\n"},"event":"output","seq":4,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.inherit-tcc true\n"},"event":"output","seq":5,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.disable-aslr false\n"},"event":"output","seq":6,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.detach-on-error false\n"},"event":"output","seq":7,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.auto-apply-fixits false\n"},"event":"output","seq":8,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set plugin.process.gdb-remote.packet-timeout 60\n"},"event":"output","seq":9,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set symbols.clang-modules-cache-path \"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api\"\n"},"event":"output","seq":10,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set use-color false\n"},"event":"output","seq":11,"type":"event"}
[18:24:22.737] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set show-statusline false\n"},"event":"output","seq":12,"type":"event"}
[18:24:22.773] (stdio) <-- {"command":"launch","request_seq":2,"seq":13,"success":true,"type":"response"}
[18:24:22.773] (stdio) <-- {"event":"initialized","seq":14,"type":"event"}
[18:24:22.773] (stdio) <-- {"body":{"module":{"addressRange":"0x7980bc46f000","id":"520E0587-8220-FB2F-C6D2-8FF46B63B3FD-5D48E763","name":"ld-linux-x86-64.so.2","path":"/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":15,"type":"event"}
[18:24:22.773] (stdio) <-- {"body":{"module":{"addressRange":"0x7fff0afcb000","id":"935E8301-3E94-6C72-593D-620D433BE6E8-4F9BB79F","name":"[vdso]","path":"[vdso]","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":16,"type":"event"}
[18:24:22.773] (stdio) --> {"command":"setBreakpoints","type":"request","arguments":{"source":{"path":"main.c"},"sourceModified":false,"lines":[10],"breakpoints":[{"line":10}]},"seq":3}
[18:24:22.773] (stdio) <-- {"body":{"module":{"addressRange":"0x596481a03000","debugInfoSize":"1.1KB","id":"B688FE77","name":"a.out","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/tools/lldb-dap/output/TestDAP_output.test_output/a.out","symbolFilePath":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/tools/lldb-dap/output/TestDAP_output.test_output/a.out","symbolStatus":"Symbols loaded."},"reason":"new"},"event":"module","seq":17,"type":"event"}
[18:24:22.774] DAP.cpp:1007 (stdio) queued (command=setBreakpoints seq=3)
[18:24:22.776] (stdio) <-- {"body":{"breakpoints":[{"column":3,"id":1,"instructionReference":"0x596481A04189","line":10,"source":{"name":"main.c","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/tools/lldb-dap/output/main.c"},"verified":true}]},"command":"setBreakpoints","request_seq":3,"seq":18,"success":true,"type":"response"}
[18:24:22.776] (stdio) <-- {"body":{"breakpoint":{"column":3,"id":1,"instructionReference":"0x596481A04189","line":10,"verified":true},"reason":"changed"},"event":"breakpoint","seq":19,"type":"event"}
[18:24:22.776] (stdio) --> {"command":"configurationDone","type":"request","arguments":{},"seq":4}
[18:24:22.776] DAP.cpp:1007 (stdio) queued (command=configurationDone seq=4)
[18:24:22.777] (stdio) <-- {"body":{"capabilities":{"supportsModuleSymbolsRequest":true,"supportsRestartRequest":true,"supportsStepInTargetsRequest":true}},"event":"capabilities","seq":20,"type":"event"}
[18:24:22.777] (stdio) <-- {"body":{"isLocalProcess":true,"name":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/tools/lldb-dap/output/TestDAP_output.test_output/a.out","pointerSize":64,"startMethod":"launch","systemProcessId":692050},"event":"process","seq":21,"type":"event"}
[18:24:22.777] (stdio) <-- {"command":"configurationDone","request_seq":4,"seq":22,"success":true,"type":"response"}
[18:24:22.777] (stdio) --> {"command":"threads","type":"request","arguments":{},"seq":5}
[18:24:22.777] DAP.cpp:1007 (stdio) queued (command=threads seq=5)
[18:24:22.779] (stdio) <-- {"body":{"threads":[{"id":692050,"name":"a.out"}]},"command":"threads","request_seq":5,"seq":23,"success":true,"type":"response"}
[18:24:22.802] (stdio) <-- {"body":{"module":{"addressRange":"0x7980bc359000","id":"DE0036AA","name":"libc++.so.1","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libc++.so.1","symbolFilePath":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libc++.so.1","symbolStatus":"Symbols loaded."},"reason":"new"},"event":"module","seq":24,"type":"event"}
[18:24:22.802] (stdio) <-- {"body":{"module":{"addressRange":"0x7980bc1e6000","id":"30724452-88DD-2ABA-348B-F583C65F7050-9AAB8141","name":"libgcc_s.so.1","path":"/lib/x86_64-linux-gnu/libgcc_s.so.1","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":25,"type":"event"}
[18:24:22.802] (stdio) <-- {"body":{"module":{"addressRange":"0x7980bc310000","id":"AE12CE5C","name":"libc++abi.so.1","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libc++abi.so.1","symbolFilePath":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libc++abi.so.1","symbolStatus":"Symbols loaded."},"reason":"new"},"event":"module","seq":26,"type":"event"}
[18:24:22.802] (stdio) <-- {"body":{"module":{"addressRange":"0x7980bc214000","id":"F834D730-8D26-6021-8ED4-F7486A58E28C-8464FE4B","name":"libm.so.6","path":"/lib/x86_64-linux-gnu/libm.so.6","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":27,"type":"event"}
[18:24:22.802] (stdio) <-- {"body":{"module":{"addressRange":"0x7980bbfc7000","id":"D2D793C5-CDFA-B4C2-E083-F41AAF689B69-4B62EACD","name":"libatomic.so.1","path":"/lib/x86_64-linux-gnu/libatomic.so.1","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":28,"type":"event"}
[18:24:22.802] (stdio) <-- {"body":{"module":{"addressRange":"0x7980bbfd2000","id":"274EEC48-8D23-0825-A136-FA9C4D85370F-ED7A0A5E","name":"libc.so.6","path":"/lib/x86_64-linux-gnu/libc.so.6","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":29,"type":"event"}
[18:24:22.802] (stdio) <-- {"body":{"module":{"addressRange":"0x7980bc300000","id":"8D933762","name":"libunwind.so.1","path":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libunwind.so.1","symbolFilePath":"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/x86_64-unknown-linux-gnu/libunwind.so.1","symbolStatus":"Symbols loaded."},"reason":"new"},"event":"module","seq":30,"type":"event"}
[18:24:22.805] (stdio) <-- {"body":{"category":"stdout","output":"abcdefghi\r\n"},"event":"output","seq":31,"type":"event"}
[18:24:22.806] (stdio) <-- {"body":{"allThreadsStopped":true,"description":"breakpoint 1.1","hitBreakpointIds":[1],"preserveFocusHint":false,"reason":"breakpoint","threadCausedFocus":true,"threadId":692050},"event":"stopped","seq":32,"type":"event"}
[18:24:23.058] (stdio) --> {"command":"threads","type":"request","arguments":{},"seq":6}
[18:24:23.058] DAP.cpp:1007 (stdio) queued (command=threads seq=6)
[18:24:23.062] (stdio) <-- {"body":{"threads":[{"id":692050,"name":"a.out"}]},"command":"threads","request_seq":6,"seq":33,"success":true,"type":"response"}
[18:24:23.062] (stdio) --> {"command":"continue","type":"request","arguments":{"threadId":692050},"seq":7}
[18:24:23.062] DAP.cpp:1007 (stdio) queued (command=continue seq=7)
[18:24:23.063] (stdio) <-- {"body":{"allThreadsContinued":true,"threadId":692050},"event":"continued","seq":34,"type":"event"}
[18:24:23.064] (stdio) <-- {"body":{"allThreadsContinued":true},"command":"continue","request_seq":7,"seq":35,"success":true,"type":"response"}
[18:24:23.066] (stdio) <-- {"body":{"category":"stdout","output":"hello world\r\n"},"event":"output","seq":36,"type":"event"}
[18:24:23.066] (stdio) <-- {"body":{"category":"stdout","output":"finally\u0000\u0000"},"event":"output","seq":37,"type":"event"}
[18:24:23.066] (stdio) <-- {"body":{"category":"console","output":"Process 692050 exited with status = 0 (0x00000000) \n"},"event":"output","seq":38,"type":"event"}
[18:24:23.112] (stdio) <-- {"body":{"category":"console","output":"out\u0000\u0000\r\n"},"event":"output","seq":39,"type":"event"}
[18:24:23.113] (stdio) <-- {"body":{"exitCode":0},"event":"exited","seq":40,"type":"event"}
[18:24:23.113] (stdio) --> {"command":"disconnect","type":"request","arguments":{},"seq":8}
[18:24:23.113] DAP.cpp:1007 (stdio) queued (command=disconnect seq=8)
[18:24:23.116] (stdio) <-- {"body":{"$__lldb_statistics":{"commands":"{\"settings clear\":1}","memory":"{\"strings\":{\"bytesTotal\":1056768,\"bytesUnused\":428709,\"bytesUsed\":628059}}","plugins":"{\"abi\":[{\"enabled\":true,\"name\":\"SysV-arm64\"},{\"enabled\":true,\"name\":\"ABIMacOSX_arm64\"},{\"enabled\":true,\"name\":\"SysV-arm\"},{\"enabled\":true,\"name\":\"macosx-arm\"},{\"enabled\":true,\"name\":\"sysv-hexagon\"},{\"enabled\":true,\"name\":\"sysv-loongarch\"},{\"enabled\":true,\"name\":\"sysv-mips\"},{\"enabled\":true,\"name\":\"sysv-mips64\"},{\"enabled\":true,\"name\":\"sysv-msp430\"},{\"enabled\":true,\"name\":\"sysv-ppc\"},{\"enabled\":true,\"name\":\"sysv-ppc64\"},{\"enabled\":true,\"name\":\"sysv-riscv\"},{\"enabled\":true,\"name\":\"sysv-s390x\"},{\"enabled\":true,\"name\":\"abi.macosx-i386\"},{\"enabled\":true,\"name\":\"sysv-i386\"},{\"enabled\":true,\"name\":\"sysv-x86_64\"},{\"enabled\":true,\"name\":\"windows-x86_64\"}],\"architecture\":[{\"enabled\":true,\"name\":\"arm\"},{\"enabled\":true,\"name\":\"mips\"},{\"enabled\":true,\"name\":\"ppc64\"},{\"enabled\":true,\"name\":\"aarch64\"}],\"disassembler\":[{\"enabled\":true,\"name\":\"llvm-mc\"}],\"dynamic-loader\":[{\"enabled\":true,\"name\":\"darwin-kernel\"},{\"enabled\":true,\"name\":\"freebsd-kernel\"},{\"enabled\":true,\"name\":\"macosx-dyld\"},{\"enabled\":true,\"name\":\"macos-dyld\"},{\"enabled\":true,\"name\":\"posix-dyld\"},{\"enabled\":true,\"name\":\"static\"},{\"enabled\":true,\"name\":\"hexagon-dyld\"},{\"enabled\":true,\"name\":\"windows-dyld\"},{\"enabled\":true,\"name\":\"wasm-dyld\"}],\"emulate-instruction\":[{\"enabled\":true,\"name\":\"arm\"},{\"enabled\":true,\"name\":\"arm64\"},{\"enabled\":true,\"name\":\"LoongArch\"},{\"enabled\":true,\"name\":\"mips32\"},{\"enabled\":true,\"name\":\"mips64\"},{\"enabled\":true,\"name\":\"ppc64\"},{\"enabled\":true,\"name\":\"riscv\"}],\"instrumentation-runtime\":[{\"enabled\":true,\"name\":\"AddressSanitizer\"},{\"enabled\":true,\"name\":\"Libsanitizers-ASan\"},{\"enabled\":true,\"name\":\"BoundsSafety\"},{\"enabled\":true,\"name\":\"MainThreadChecker\"},{\"enabled\":true,\"name\":\"ThreadSanitizer\"},{\"enabled\":true,\"name\":\"UndefinedBehaviorSanitizer\"}],\"jit-loader\":[{\"enabled\":true,\"name\":\"gdb\"}],\"language\":[{\"enabled\":true,\"name\":\"cplusplus\"},{\"enabled\":true,\"name\":\"objc\"},{\"enabled\":true,\"name\":\"objcplusplus\"}],\"language-runtime\":[{\"enabled\":true,\"name\":\"itanium\"},{\"enabled\":true,\"name\":\"apple-objc-v2\"},{\"enabled\":true,\"name\":\"apple-objc-v1\"},{\"enabled\":true,\"name\":\"gnustep-objc-libobjc2\"}],\"memory-history\":[{\"enabled\":true,\"name\":\"asan\"}],\"object-container\":[{\"enabled\":true,\"name\":\"bsd-archive\"},{\"enabled\":true,\"name\":\"mach-o\"},{\"enabled\":true,\"name\":\"mach-o-fileset\"}],\"object-file\":[{\"enabled\":true,\"name\":\"breakpad\"},{\"enabled\":true,\"name\":\"COFF\"},{\"enabled\":true,\"name\":\"elf\"},{\"enabled\":true,\"name\":\"JSON\"},{\"enabled\":true,\"name\":\"mach-o\"},{\"enabled\":true,\"name\":\"minidump\"},{\"enabled\":true,\"name\":\"pdb\"},{\"enabled\":true,\"name\":\"pe-coff\"},{\"enabled\":true,\"name\":\"xcoff\"},{\"enabled\":true,\"name\":\"wasm\"}],\"operating-system\":[{\"enabled\":true,\"name\":\"python\"}],\"platform\":[{\"enabled\":true,\"name\":\"remote-AIX\"},{\"enabled\":true,\"name\":\"remote-linux\"},{\"enabled\":true,\"name\":\"remote-android\"},{\"enabled\":true,\"name\":\"remote-freebsd\"},{\"enabled\":true,\"name\":\"remote-gdb-server\"},{\"enabled\":true,\"name\":\"darwin\"},{\"enabled\":true,\"name\":\"remote-ios\"},{\"enabled\":true,\"name\":\"remote-macosx\"},{\"enabled\":true,\"name\":\"host\"},{\"enabled\":true,\"name\":\"remote-netbsd\"},{\"enabled\":true,\"name\":\"remote-openbsd\"},{\"enabled\":true,\"name\":\"qemu-user\"},{\"enabled\":true,\"name\":\"remote-windows\"}],\"process\":[{\"enabled\":true,\"name\":\"ScriptedProcess\"},{\"enabled\":true,\"name\":\"elf-core\"},{\"enabled\":true,\"name\":\"mach-o-core\"},{\"enabled\":true,\"name\":\"minidump\"},{\"enabled\":true,\"name\":\"wasm\"},{\"enabled\":true,\"name\":\"gdb-remote\"}],\"register-type-builder\":[{\"enabled\":true,\"name\":\"register-types-clang\"}],\"repl\":[{\"enabled\":true,\"name\":\"ClangREPL\"}],\"script-interpreter\":[{\"enabled\":true,\"name\":\"script-none\"},{\"enabled\":true,\"name\":\"script-python\"}],\"scripted-interface\":[{\"enabled\":true,\"name\":\"OperatingSystemPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedPlatformPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedProcessPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedStopHookPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedBreakpointPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedThreadPlanPythonInterface\"},{\"enabled\":true,\"name\":\"ScriptedFrameProviderPythonInterface\"}],\"structured-data\":[{\"enabled\":true,\"name\":\"darwin-log\"}],\"symbol-file\":[{\"enabled\":true,\"name\":\"breakpad\"},{\"enabled\":true,\"name\":\"CTF\"},{\"enabled\":true,\"name\":\"dwarf\"},{\"enabled\":true,\"name\":\"dwarf-debugmap\"},{\"enabled\":true,\"name\":\"JSON\"},{\"enabled\":true,\"name\":\"native-pdb\"},{\"enabled\":true,\"name\":\"pdb\"},{\"enabled\":true,\"name\":\"symtab\"}],\"symbol-locator\":[{\"enabled\":true,\"name\":\"debuginfod\"},{\"enabled\":true,\"name\":\"Default\"}],\"symbol-vendor\":[{\"enabled\":true,\"name\":\"ELF\"},{\"enabled\":true,\"name\":\"PE-COFF\"},{\"enabled\":true,\"name\":\"WASM\"}],\"system-runtime\":[{\"enabled\":true,\"name\":\"systemruntime-macosx\"}],\"trace-exporter\":[{\"enabled\":true,\"name\":\"ctf\"}],\"type-system\":[{\"enabled\":true,\"name\":\"clang\"}],\"unwind-assembly\":[{\"enabled\":true,\"name\":\"inst-emulation\"},{\"enabled\":true,\"name\":\"x86\"}]}","targets":"[{\"breakpoints\":[{\"details\":{\"Breakpoint\":{\"BKPTOptions\":{\"AutoContinue\":false,\"ConditionText\":\"\",\"EnabledState\":true,\"IgnoreCount\":0,\"OneShotState\":false},\"BKPTResolver\":{\"Options\":{\"Column\":0,\"Exact\":false,\"FileName\":\"/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/tools/lldb-dap/output/main.c\",\"Inlines\":true,\"LineNumber\":10,\"Offset\":0,\"SkipPrologue\":true},\"Type\":\"FileAndLine\"},\"Hardware\":false,\"Names\":[\"dap\"],\"SearchFilter\":{\"Options\":{},\"Type\":\"Unconstrained\"}}},\"hitCount\":1,\"id\":1,\"internal\":false,\"numLocations\":1,\"numResolvedLocations\":1,\"resolveTime\":0.0013240000000000001},{\"details\":{\"Breakpoint\":{\"BKPTOptions\":{\"AutoContinue\":false,\"ConditionText\":\"\",\"EnabledState\":true,\"IgnoreCount\":0,\"OneShotState\":false},\"BKPTResolver\":{\"Options\":{\"Language\":\"c\",\"NameMask\":[4,4,4,4,4,4],\"Offset\":0,\"SkipPrologue\":false,\"SymbolNames\":[\"_dl_debug_state\",\"rtld_db_dlactivity\",\"__dl_rtld_db_dlactivity\",\"r_debug_state\",\"_r_debug_state\",\"_rtld_debug_state\"]},\"Type\":\"SymbolName\"},\"Hardware\":false,\"SearchFilter\":{\"Options\":{\"ModuleList\":[\"/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2\"]},\"Type\":\"Modules\"}}},\"hitCount\":2,\"id\":-1,\"internal\":true,\"kindDescription\":\"shared-library-event\",\"numLocations\":1,\"numResolvedLocations\":1,\"resolveTime\":0.00012}],\"dyldPluginName\":\"posix-dyld\",\"expressionEvaluation\":{\"failures\":0,\"successes\":0},\"firstStopTime\":0.019686634000000001,\"frameVariable\":{\"failures\":0,\"successes\":0},\"launchOrAttachTime\":0.016308398000000002,\"moduleIdentifiers\":[531258944,531839648,530114928,138417669147584,138418072171760,138417937583040,138417199404688,138417870476224,138417669158192,138417803365712],\"signals\":[{\"SIGSTOP\":1}],\"sourceMapDeduceCount\":0,\"sourceRealpathAttemptCount\":0,\"sourceRealpathCompatibleCount\":0,\"stopCount\":8,\"summaryProviderStatistics\":[],\"targetCreateTime\":0.014864,\"totalBreakpointResolveTime\":0.0014440000000000002,\"totalSharedLibraryEventHitCount\":2}]","totalDebugInfoByteSize":1165,"totalDebugInfoEnabled":1,"totalDebugInfoIndexLoadedFromCache":0,"totalDebugInfoIndexSavedToCache":0,"totalDebugInfoIndexTime":0.013351,"totalDebugInfoParseTime":0.000107,"totalDwoErrorCount":0,"totalDwoFileCount":0,"totalLoadedDwoFileCount":0,"totalModuleCount":10,"totalModuleCountHasDebugInfo":1,"totalModuleCountWithIncompleteTypes":0,"totalModuleCountWithVariableErrors":0,"totalSymbolLocatorTime":"{\"Default\":0.003251,\"debuginfod\":3.0000000000000001e-06}","totalSymbolTableIndexTime":0.0058799999999999989,"totalSymbolTableParseTime":0.046279000000000001,"totalSymbolTableStripped":0,"totalSymbolTableSymbolCount":12617,"totalSymbolTablesLoaded":10,"totalSymbolTablesLoadedFromCache":0,"totalSymbolTablesSavedToCache":0}},"event":"terminated","seq":41,"type":"event"}
[18:24:23.116] (stdio) <-- {"command":"disconnect","request_seq":8,"seq":42,"success":true,"type":"response"}
[18:24:23.116] (stdio) <-- {"body":{"category":"console","output":"err\u0000\u0000\r\n"},"event":"output","seq":43,"type":"event"}

========= END =========
======================================================================
FAIL: test_output (TestDAP_output.TestDAP_output.test_output)
   Test output handling for the running process.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/tools/lldb-dap/output/TestDAP_output.py", line 49, in test_output
    self.assertIn(
AssertionError: 'out\x00\x00\r\nerr\x00\x00\r\n' not found in 'Running initCommands:\n(lldb) settings clear --all\n(lldb) settings set symbols.enable-external-lookup false\n(lldb) settings set target.inherit-tcc true\n(lldb) settings set target.disable-aslr false\n(lldb) settings set target.detach-on-error false\n(lldb) settings set target.auto-apply-fixits false\n(lldb) settings set plugin.process.gdb-remote.packet-timeout 60\n(lldb) settings set symbols.clang-modules-cache-path "/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build.noindex/module-cache-lldb/lldb-api"\n(lldb) settings set use-color false\n(lldb) settings set show-statusline false\nProcess 692050 exited with status = 0 (0x00000000) \nout\x00\x00\r\n' : full console message not found
Config=x86_64-/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang
----------------------------------------------------------------------
Ran 1 test in 0.726s

FAILED (failures=1)

--

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants