Author: Bill Wendling Date: 2024-07-23T00:49:46-07:00 New Revision: 6db5f4fd2a287de9d20adc7a44cfcc66fc462c9c
URL: https://github.com/llvm/llvm-project/commit/6db5f4fd2a287de9d20adc7a44cfcc66fc462c9c DIFF: https://github.com/llvm/llvm-project/commit/6db5f4fd2a287de9d20adc7a44cfcc66fc462c9c.diff LOG: [Clang] Ignore empty FieldDecls when asking for the field number (#100040) A FieldDecl that's an empty struct may not show up in CGRecordLayout. Go ahead and ignore such a field as it shouldn't make a difference to these calculations. Fixes: 1f6f97e2b64a ("[Clang] Loop over FieldDecls instead of all Decls (#99574)") Co-authored-by: Eli Friedman <efrie...@quicinc.com> Added: Modified: clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGRecordLayout.h clang/test/CodeGen/attr-counted-by.c Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index aa53f96358044..5f58a64d8386c 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1076,6 +1076,11 @@ static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD, const CGRecordLayout &Layout = CGF.CGM.getTypes().getCGRecordLayout(RD); int64_t FieldNo = -1; for (const FieldDecl *FD : RD->fields()) { + if (!Layout.containsFieldDecl(FD)) + // This could happen if the field has a struct type that's empty. I don't + // know why either. + continue; + FieldNo = Layout.getLLVMFieldNo(FD); if (FD == Field) { Indices.emplace_back(std::make_pair(RD, CGF.Builder.getInt32(FieldNo))); diff --git a/clang/lib/CodeGen/CGRecordLayout.h b/clang/lib/CodeGen/CGRecordLayout.h index 6c06ad20fbe56..44e888c93108f 100644 --- a/clang/lib/CodeGen/CGRecordLayout.h +++ b/clang/lib/CodeGen/CGRecordLayout.h @@ -193,6 +193,10 @@ class CGRecordLayout { return IsZeroInitializableAsBase; } + bool containsFieldDecl(const FieldDecl *FD) const { + return FieldInfo.count(FD) != 0; + } + /// Return llvm::StructType element number that corresponds to the /// field FD. unsigned getLLVMFieldNo(const FieldDecl *FD) const { diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c index 32db136076d7d..46a6c2b492dbe 100644 --- a/clang/test/CodeGen/attr-counted-by.c +++ b/clang/test/CodeGen/attr-counted-by.c @@ -1906,3 +1906,51 @@ struct test30_struct { void test30(struct test30_struct *ptr, int idx) { ptr->pcpu_refcnt.__padding[idx] = __builtin_dynamic_object_size(ptr, 1); } + +struct test31_empty {}; + +struct test31_struct { + struct test31_empty y; + int s; + int x[] __counted_by(s); +}; + +// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test31( +// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[PTR]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[TMP1]], i64 0) +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = trunc i64 [[TMP2]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 4 +// SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP4]] +// SANITIZE-WITH-ATTR-NEXT: ret i32 [[CONV]] +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test31( +// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[PTR]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[TMP1]], i64 0) +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = trunc i64 [[TMP2]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 [[TMP4]] +// NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[CONV]] +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test31( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 -1 +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test31( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 -1 +// +int test31(struct test31_struct *ptr, int idx) { + return __builtin_dynamic_object_size(ptr, 0); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits