llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Bill Wendling (bwendling) <details> <summary>Changes</summary> A struct that declares an inner struct, but no fields, won't have a field count. So getting the offset of the inner struct fails. This happens in both C and C++: struct foo { struct bar { int Quantizermatrix[]; }; }; Here 'struct foo' has no fields. Fixes: https://github.com/llvm/llvm-project/issues/88931 --- Full diff: https://github.com/llvm/llvm-project/pull/89126.diff 3 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+14-1) - (added) clang/test/CodeGen/attr-counted-by-pr88931.c (+22) - (added) clang/test/CodeGen/attr-counted-by-pr88931.cpp (+21) ``````````diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index a05874e63c73c2..bee12c4469e7f7 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -829,6 +829,9 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( unsigned FieldNo = 0; bool IsUnion = RD->isUnion(); + if (RD->isImplicit()) + return nullptr; + for (const Decl *D : RD->decls()) { if (const auto *Field = dyn_cast<FieldDecl>(D); Field && (Name.empty() || Field->getNameAsString() == Name) && @@ -844,7 +847,17 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( if (const FieldDecl *Field = FindFlexibleArrayMemberField(Ctx, Record, Name, Offset)) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); - Offset += Layout.getFieldOffset(FieldNo); + if (Layout.getFieldCount()) { + // A struct that holds only an inner struct won't have any fields. E.g. + // + // struct foo { + // struct bar { + // int count; + // int array[]; + // }; + // }; + Offset += Layout.getFieldOffset(FieldNo); + } return Field; } diff --git a/clang/test/CodeGen/attr-counted-by-pr88931.c b/clang/test/CodeGen/attr-counted-by-pr88931.c new file mode 100644 index 00000000000000..baa1bbc8397456 --- /dev/null +++ b/clang/test/CodeGen/attr-counted-by-pr88931.c @@ -0,0 +1,22 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wno-missing-declarations -emit-llvm -o - %s | FileCheck %s + +struct foo { + struct bar { + int count; + int array[] __attribute__((counted_by(count))); + }; +}; + +void init(void * __attribute__((pass_dynamic_object_size(0)))); + +// CHECK-LABEL: define dso_local void @test1( +// CHECK-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 4 +// CHECK-NEXT: tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef -1) #[[ATTR2:[0-9]+]] +// CHECK-NEXT: ret void +// +void test1(struct bar *p) { + init(p->array); +} diff --git a/clang/test/CodeGen/attr-counted-by-pr88931.cpp b/clang/test/CodeGen/attr-counted-by-pr88931.cpp new file mode 100644 index 00000000000000..2a8cc1d07e50d9 --- /dev/null +++ b/clang/test/CodeGen/attr-counted-by-pr88931.cpp @@ -0,0 +1,21 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wall -emit-llvm -o - %s | FileCheck %s + +struct foo { + struct bar { + int array[]; + bar(); + }; +}; + +void init(void * __attribute__((pass_dynamic_object_size(0)))); + +// CHECK-LABEL: define dso_local void @_ZN3foo3barC1Ev( +// CHECK-SAME: ptr noundef nonnull align 4 dereferenceable(1) [[THIS:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] align 2 { +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @_Z4initPvU25pass_dynamic_object_size0(ptr noundef nonnull [[THIS]], i64 noundef -1) #[[ATTR2:[0-9]+]] +// CHECK-NEXT: ret void +// +foo::bar::bar() { + init(array); +} `````````` </details> https://github.com/llvm/llvm-project/pull/89126 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits