-
Notifications
You must be signed in to change notification settings - Fork 12.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Clang] Loop over FieldDecls instead of all Decls #99574
Conversation
Only FieldDecls are important when determining GEP indices. A struct defined within another struct has the same semantics as if it were defined outside of the struct. So there's no need to look into RecordDecls that aren't a field. See commit 5bcf31e ("[Clang] Loop over FieldDecls instead of all Decls (llvm#89453)") Fixes 2039.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Bill Wendling (bwendling) ChangesOnly FieldDecls are important when determining GEP indices. A struct defined within another struct has the same semantics as if it were defined outside of the struct. So there's no need to look into RecordDecls that aren't a field. See commit 5bcf31e ("[Clang] Loop over FieldDecls instead of all Decls (#89453)") Fixes 2039. Full diff: https://github.com/llvm/llvm-project/pull/99574.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 6a0af00b9e186..69fa05e7a94ea 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1071,21 +1071,19 @@ using RecIndicesTy =
SmallVector<std::pair<const RecordDecl *, llvm::Value *>, 8>;
static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD,
- const FieldDecl *FD, RecIndicesTy &Indices) {
+ const FieldDecl *Field, RecIndicesTy &Indices) {
const CGRecordLayout &Layout = CGF.CGM.getTypes().getCGRecordLayout(RD);
int64_t FieldNo = -1;
- for (const Decl *D : RD->decls()) {
- if (const auto *Field = dyn_cast<FieldDecl>(D)) {
- FieldNo = Layout.getLLVMFieldNo(Field);
- if (FD == Field) {
- Indices.emplace_back(std::make_pair(RD, CGF.Builder.getInt32(FieldNo)));
- return true;
- }
+ for (const FieldDecl *FD : RD->fields()) {
+ FieldNo = Layout.getLLVMFieldNo(FD);
+ if (FD == Field) {
+ Indices.emplace_back(std::make_pair(RD, CGF.Builder.getInt32(FieldNo)));
+ return true;
}
- if (const auto *Record = dyn_cast<RecordDecl>(D)) {
- ++FieldNo;
- if (getGEPIndicesToField(CGF, Record, FD, Indices)) {
+ QualType Ty = FD->getType();
+ if (Ty->isRecordType()) {
+ if (getGEPIndicesToField(CGF, Ty->getAsRecordDecl(), Field, Indices)) {
if (RD->isUnion())
FieldNo = 0;
Indices.emplace_back(std::make_pair(RD, CGF.Builder.getInt32(FieldNo)));
diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c
index 79922eb4159f1..32db136076d7d 100644
--- a/clang/test/CodeGen/attr-counted-by.c
+++ b/clang/test/CodeGen/attr-counted-by.c
@@ -1852,3 +1852,57 @@ struct annotated_struct_array {
void test29(struct annotated_struct_array *ann, int idx1, int idx2) {
ann->ann_array[idx1]->array[idx2] = __builtin_dynamic_object_size(ann->ann_array[idx1]->array, 1);
}
+
+typedef struct {
+ char __padding[0];
+} test30_spinlock_t;
+
+struct test30_struct {
+ struct test30_decl *name_node;
+ int priv_len;
+ test30_spinlock_t pcpu_refcnt;
+ char priv[] __counted_by(priv_len);
+};
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30(
+// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR5]] {
+// SANITIZE-WITH-ATTR-NEXT: entry:
+// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB39:[0-9]+]], i64 [[TMP0]]) #[[ATTR10]], !nosanitize [[META2]]
+// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] {
+// NO-SANITIZE-WITH-ATTR-NEXT: entry:
+// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 8
+// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 4)
+// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8
+// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], 12
+// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i8 0, i8 [[TMP2]]
+// NO-SANITIZE-WITH-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 12
+// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[PCPU_REFCNT]], i64 0, i64 [[IDXPROM]]
+// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]]
+// NO-SANITIZE-WITH-ATTR-NEXT: ret void
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30(
+// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] {
+// SANITIZE-WITHOUT-ATTR-NEXT: entry:
+// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META9]]
+// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP0]]) #[[ATTR8]], !nosanitize [[META9]]
+// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]]
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30(
+// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 12
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[PCPU_REFCNT]], i64 0, i64 [[IDXPROM]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]]
+// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
+//
+void test30(struct test30_struct *ptr, int idx) {
+ ptr->pcpu_refcnt.__padding[idx] = __builtin_dynamic_object_size(ptr, 1);
+}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/51/builds/1493 Here is the relevant piece of the build log for the reference:
|
I see a crash in struct swait_queue_head {};
struct completion {
int done;
struct swait_queue_head wait;
};
struct {
struct completion removal;
int num_trips;
int trips[] __attribute__((__counted_by__(num_trips)));
} *thermal_zone_device_register_with_trips_tz;
int thermal_zone_device_register_with_trips() {
if (thermal_zone_device_register_with_trips_tz)
goto free_tz;
if (0)
goto free_tzp;
{
long __p_size_field = __builtin_dynamic_object_size(
thermal_zone_device_register_with_trips_tz, 1);
_Bool __ret_do_once = __p_size_field, __ret_cond = __ret_do_once;
static _Bool __already_done;
if (__builtin_expect(__ret_cond && __already_done, 0))
;
}
free_tzp:
free_tz:
return 0;
}
|
Okay. I'll look into it.
…On Sun, Jul 21, 2024 at 4:35 PM Nathan Chancellor ***@***.***> wrote:
I see a crash in drivers/thermal/thermal_core.c in Linux kernels without
commit daeeb032f42d
<https://git.kernel.org/linus/daeeb032f42d066a49e07b7f6effc9f51b7a5479>
("thermal: core: Move threshold out of struct thermal_trip") after this
change. cvise spits out:
struct swait_queue_head {};struct completion {
int done;
struct swait_queue_head wait;
};struct {
struct completion removal;
int num_trips;
int trips[] __attribute__((__counted_by__(num_trips)));
} *thermal_zone_device_register_with_trips_tz;int thermal_zone_device_register_with_trips() {
if (thermal_zone_device_register_with_trips_tz)
goto free_tz;
if (0)
goto free_tzp;
{
long __p_size_field = __builtin_dynamic_object_size(
thermal_zone_device_register_with_trips_tz, 1);
_Bool __ret_do_once = __p_size_field, __ret_cond = __ret_do_once;
static _Bool __already_done;
if (__builtin_expect(__ret_cond && __already_done, 0))
;
}
free_tzp:
free_tz:
return 0;
}
$ clang -c -o /dev/null thermal_core.i
clang: /home/nathan/tmp/cvise.YrEYUS5WBZ/src/clang/lib/CodeGen/CGRecordLayout.h:200: unsigned int clang::CodeGen::CGRecordLayout::getLLVMFieldNo(const FieldDecl *) const: Assertion `FieldInfo.count(FD) && "Invalid field for record!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0. Program arguments: clang -c -o /dev/null thermal_core.i
1. <eof> parser at end of file
2. thermal_core.i:11:5: LLVM IR generation of declaration 'thermal_zone_device_register_with_trips'
3. thermal_core.i:11:5: Generating code for declaration 'thermal_zone_device_register_with_trips'
4. thermal_core.i:16:3: LLVM IR generation of compound statement ('{}')
#0 0x00005585369d0446 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x55fc446)
#1 0x00005585369cdf0e llvm::sys::RunSignalHandlers() (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x55f9f0e)
#2 0x00005585369513ad CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#3 0x00007f3d209bdae0 (/usr/lib/libc.so.6+0x3cae0)
#4 0x00007f3d20a15e44 (/usr/lib/libc.so.6+0x94e44)
#5 0x00007f3d209bda30 raise (/usr/lib/libc.so.6+0x3ca30)
#6 0x00007f3d209a54c3 abort (/usr/lib/libc.so.6+0x244c3)
#7 0x00007f3d209a53df (/usr/lib/libc.so.6+0x243df)
#8 0x00007f3d209b5c67 (/usr/lib/libc.so.6+0x34c67)
#9 0x0000558536de6281 clang::CodeGen::CGRecordLayout::getLLVMFieldNo(clang::FieldDecl const*) const CGExpr.cpp:0:0
#10 0x0000558536dcd526 getGEPIndicesToField(clang::CodeGen::CodeGenFunction&, clang::RecordDecl const*, clang::FieldDecl const*, llvm::SmallVector<std::pair<clang::RecordDecl const*, llvm::Value*>, 8u>&) CGExpr.cpp:0:0
#11 0x0000558536dcd581 getGEPIndicesToField(clang::CodeGen::CodeGenFunction&, clang::RecordDecl const*, clang::FieldDecl const*, llvm::SmallVector<std::pair<clang::RecordDecl const*, llvm::Value*>, 8u>&) CGExpr.cpp:0:0
#12 0x0000558536dca542 clang::CodeGen::CodeGenFunction::EmitCountedByFieldExpr(clang::Expr const*, clang::FieldDecl const*, clang::FieldDecl const*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x59f6542)
#13 0x0000558536fb0927 clang::CodeGen::CodeGenFunction::emitFlexibleArrayMemberSize(clang::Expr const*, unsigned int, llvm::IntegerType*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5bdc927)
#14 0x0000558536fafdf8 clang::CodeGen::CodeGenFunction::emitBuiltinObjectSize(clang::Expr const*, unsigned int, llvm::IntegerType*, llvm::Value*, bool) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5bdbdf8)
#15 0x0000558536fb9cfc clang::CodeGen::CodeGenFunction::EmitBuiltinExpr(clang::GlobalDecl, unsigned int, clang::CallExpr const*, clang::CodeGen::ReturnValueSlot) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5be5cfc)
#16 0x0000558536de827c clang::CodeGen::CodeGenFunction::EmitCallExpr(clang::CallExpr const*, clang::CodeGen::ReturnValueSlot) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a1427c)
#17 0x0000558536e024cb (anonymous namespace)::ScalarExprEmitter::VisitCallExpr(clang::CallExpr const*) CGExprScalar.cpp:0:0
#18 0x0000558536dee27b (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) CGExprScalar.cpp:0:0
#19 0x0000558536e0bedd (anonymous namespace)::ScalarExprEmitter::VisitCastExpr(clang::CastExpr*) CGExprScalar.cpp:0:0
#20 0x0000558536dee11c clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a1a11c)
#21 0x0000558536e301e4 clang::CodeGen::CodeGenFunction::EmitScalarInit(clang::Expr const*, clang::ValueDecl const*, clang::CodeGen::LValue, bool) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a5c1e4)
#22 0x0000558536e335d1 clang::CodeGen::CodeGenFunction::EmitAutoVarInit(clang::CodeGen::CodeGenFunction::AutoVarEmission const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a5f5d1)
#23 0x0000558536e2da7d clang::CodeGen::CodeGenFunction::EmitVarDecl(clang::VarDecl const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a59a7d)
#24 0x0000558536e2d4b7 clang::CodeGen::CodeGenFunction::EmitDecl(clang::Decl const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a594b7)
#25 0x0000558536d66ddb clang::CodeGen::CodeGenFunction::EmitDeclStmt(clang::DeclStmt const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5992ddb)
#26 0x0000558536d59acb clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5985acb)
#27 0x0000558536d58b33 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5984b33)
#28 0x0000558536d59aa1 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5985aa1)
#29 0x0000558536d58b33 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5984b33)
#30 0x0000558536d67f40 clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5993f40)
#31 0x0000558536d44ee6 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5970ee6)
#32 0x0000558536bfb47b clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x582747b)
#33 0x0000558536bf2a75 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x581ea75)
#34 0x0000558536bf7a1a clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5823a1a)
#35 0x0000558536bf13e2 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x581d3e2)
#36 0x0000558537240fbc (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) ModuleBuilder.cpp:0:0
#37 0x0000558537237057 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5e63057)
#38 0x00005585386c199a clang::ParseAST(clang::Sema&, bool, bool) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x72ed99a)
#39 0x00005585376ca08d clang::FrontendAction::Execute() (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x62f608d)
#40 0x000055853762e7ad clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x625a7ad)
#41 0x00005585377a673c clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x63d273c)
#42 0x0000558534a3220a cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x365e20a)
#43 0x0000558534a2e85d ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#44 0x0000558537454199 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_0>(long) Job.cpp:0:0
#45 0x00005585369510e6 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x557d0e6)
#46 0x0000558537453833 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x607f833)
#47 0x000055853740b427 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x6037427)
#48 0x000055853740b987 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x6037987)
#49 0x000055853742e0e9 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x605a0e9)
#50 0x0000558534a2dcfd clang_main(int, char**, llvm::ToolContext const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x3659cfd)
#51 0x0000558534a3f806 main (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x366b806)
#52 0x00007f3d209a6c88 (/usr/lib/libc.so.6+0x25c88)
#53 0x00007f3d209a6d4c __libc_start_main (/usr/lib/libc.so.6+0x25d4c)
#54 0x0000558534a2c125 _start (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x3658125)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
ClangBuiltLinux clang version 19.0.0git (https://github.com/llvm/llvm-project.git 1f6f97e)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin
Build config: +assertions
clang: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.
—
Reply to this email directly, view it on GitHub
<#99574 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABNXLPQ6246XJ5ZFLAJOMU3ZNRAUBAVCNFSM6AAAAABLDPC57GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENBRHAYTIOBUGI>
.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***>
|
+Eli Friedman ***@***.***>
I'm confused by what's going on. Here's a shorter testcase:
struct a {};
struct c {
int done;
struct a x;
};
struct b {
struct a y;
int s;
int x[] __attribute__((counted_by(s)));
};
int foo(struct b *p, int idx) {
return __builtin_dynamic_object_size(p, 0);
}
The CGRecordLayout doesn't have 'y' listed as a field. It shows 's' and
'x', but not 'y'... Yet the RecordDecl *does* have 'y' as a FieldDecl. My
only guess is that, because it's an empty struct, the
CGRecordLayout decides that it doesn't need to count it as part of the
record layout? That doesn't make a whole lot of sense to me. I realize that
it has zero size (in C), but I thought we'd still have to deal with it......
Eli, does that make any sense?
…-bw
On Mon, Jul 22, 2024 at 5:00 PM Bill Wendling ***@***.***> wrote:
Okay. I'll look into it.
On Sun, Jul 21, 2024 at 4:35 PM Nathan Chancellor <
***@***.***> wrote:
> I see a crash in drivers/thermal/thermal_core.c in Linux kernels without
> commit daeeb032f42d
> <https://git.kernel.org/linus/daeeb032f42d066a49e07b7f6effc9f51b7a5479>
> ("thermal: core: Move threshold out of struct thermal_trip") after this
> change. cvise spits out:
>
> struct swait_queue_head {};struct completion {
> int done;
> struct swait_queue_head wait;
> };struct {
> struct completion removal;
> int num_trips;
> int trips[] __attribute__((__counted_by__(num_trips)));
> } *thermal_zone_device_register_with_trips_tz;int thermal_zone_device_register_with_trips() {
> if (thermal_zone_device_register_with_trips_tz)
> goto free_tz;
> if (0)
> goto free_tzp;
> {
> long __p_size_field = __builtin_dynamic_object_size(
> thermal_zone_device_register_with_trips_tz, 1);
> _Bool __ret_do_once = __p_size_field, __ret_cond = __ret_do_once;
> static _Bool __already_done;
> if (__builtin_expect(__ret_cond && __already_done, 0))
> ;
> }
> free_tzp:
> free_tz:
> return 0;
> }
>
> $ clang -c -o /dev/null thermal_core.i
> clang: /home/nathan/tmp/cvise.YrEYUS5WBZ/src/clang/lib/CodeGen/CGRecordLayout.h:200: unsigned int clang::CodeGen::CGRecordLayout::getLLVMFieldNo(const FieldDecl *) const: Assertion `FieldInfo.count(FD) && "Invalid field for record!"' failed.
> PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
> Stack dump:
> 0. Program arguments: clang -c -o /dev/null thermal_core.i
> 1. <eof> parser at end of file
> 2. thermal_core.i:11:5: LLVM IR generation of declaration 'thermal_zone_device_register_with_trips'
> 3. thermal_core.i:11:5: Generating code for declaration 'thermal_zone_device_register_with_trips'
> 4. thermal_core.i:16:3: LLVM IR generation of compound statement ('{}')
> #0 0x00005585369d0446 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x55fc446)
> #1 0x00005585369cdf0e llvm::sys::RunSignalHandlers() (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x55f9f0e)
> #2 0x00005585369513ad CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
> #3 0x00007f3d209bdae0 (/usr/lib/libc.so.6+0x3cae0)
> #4 0x00007f3d20a15e44 (/usr/lib/libc.so.6+0x94e44)
> #5 0x00007f3d209bda30 raise (/usr/lib/libc.so.6+0x3ca30)
> #6 0x00007f3d209a54c3 abort (/usr/lib/libc.so.6+0x244c3)
> #7 0x00007f3d209a53df (/usr/lib/libc.so.6+0x243df)
> #8 0x00007f3d209b5c67 (/usr/lib/libc.so.6+0x34c67)
> #9 0x0000558536de6281 clang::CodeGen::CGRecordLayout::getLLVMFieldNo(clang::FieldDecl const*) const CGExpr.cpp:0:0
> #10 0x0000558536dcd526 getGEPIndicesToField(clang::CodeGen::CodeGenFunction&, clang::RecordDecl const*, clang::FieldDecl const*, llvm::SmallVector<std::pair<clang::RecordDecl const*, llvm::Value*>, 8u>&) CGExpr.cpp:0:0
> #11 0x0000558536dcd581 getGEPIndicesToField(clang::CodeGen::CodeGenFunction&, clang::RecordDecl const*, clang::FieldDecl const*, llvm::SmallVector<std::pair<clang::RecordDecl const*, llvm::Value*>, 8u>&) CGExpr.cpp:0:0
> #12 0x0000558536dca542 clang::CodeGen::CodeGenFunction::EmitCountedByFieldExpr(clang::Expr const*, clang::FieldDecl const*, clang::FieldDecl const*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x59f6542)
> #13 0x0000558536fb0927 clang::CodeGen::CodeGenFunction::emitFlexibleArrayMemberSize(clang::Expr const*, unsigned int, llvm::IntegerType*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5bdc927)
> #14 0x0000558536fafdf8 clang::CodeGen::CodeGenFunction::emitBuiltinObjectSize(clang::Expr const*, unsigned int, llvm::IntegerType*, llvm::Value*, bool) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5bdbdf8)
> #15 0x0000558536fb9cfc clang::CodeGen::CodeGenFunction::EmitBuiltinExpr(clang::GlobalDecl, unsigned int, clang::CallExpr const*, clang::CodeGen::ReturnValueSlot) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5be5cfc)
> #16 0x0000558536de827c clang::CodeGen::CodeGenFunction::EmitCallExpr(clang::CallExpr const*, clang::CodeGen::ReturnValueSlot) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a1427c)
> #17 0x0000558536e024cb (anonymous namespace)::ScalarExprEmitter::VisitCallExpr(clang::CallExpr const*) CGExprScalar.cpp:0:0
> #18 0x0000558536dee27b (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) CGExprScalar.cpp:0:0
> #19 0x0000558536e0bedd (anonymous namespace)::ScalarExprEmitter::VisitCastExpr(clang::CastExpr*) CGExprScalar.cpp:0:0
> #20 0x0000558536dee11c clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a1a11c)
> #21 0x0000558536e301e4 clang::CodeGen::CodeGenFunction::EmitScalarInit(clang::Expr const*, clang::ValueDecl const*, clang::CodeGen::LValue, bool) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a5c1e4)
> #22 0x0000558536e335d1 clang::CodeGen::CodeGenFunction::EmitAutoVarInit(clang::CodeGen::CodeGenFunction::AutoVarEmission const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a5f5d1)
> #23 0x0000558536e2da7d clang::CodeGen::CodeGenFunction::EmitVarDecl(clang::VarDecl const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a59a7d)
> #24 0x0000558536e2d4b7 clang::CodeGen::CodeGenFunction::EmitDecl(clang::Decl const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5a594b7)
> #25 0x0000558536d66ddb clang::CodeGen::CodeGenFunction::EmitDeclStmt(clang::DeclStmt const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5992ddb)
> #26 0x0000558536d59acb clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5985acb)
> #27 0x0000558536d58b33 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5984b33)
> #28 0x0000558536d59aa1 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5985aa1)
> #29 0x0000558536d58b33 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5984b33)
> #30 0x0000558536d67f40 clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5993f40)
> #31 0x0000558536d44ee6 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5970ee6)
> #32 0x0000558536bfb47b clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x582747b)
> #33 0x0000558536bf2a75 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x581ea75)
> #34 0x0000558536bf7a1a clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5823a1a)
> #35 0x0000558536bf13e2 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x581d3e2)
> #36 0x0000558537240fbc (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) ModuleBuilder.cpp:0:0
> #37 0x0000558537237057 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x5e63057)
> #38 0x00005585386c199a clang::ParseAST(clang::Sema&, bool, bool) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x72ed99a)
> #39 0x00005585376ca08d clang::FrontendAction::Execute() (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x62f608d)
> #40 0x000055853762e7ad clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x625a7ad)
> #41 0x00005585377a673c clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x63d273c)
> #42 0x0000558534a3220a cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x365e20a)
> #43 0x0000558534a2e85d ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
> #44 0x0000558537454199 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::$_0>(long) Job.cpp:0:0
> #45 0x00005585369510e6 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x557d0e6)
> #46 0x0000558537453833 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x607f833)
> #47 0x000055853740b427 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x6037427)
> #48 0x000055853740b987 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x6037987)
> #49 0x000055853742e0e9 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x605a0e9)
> #50 0x0000558534a2dcfd clang_main(int, char**, llvm::ToolContext const&) (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x3659cfd)
> #51 0x0000558534a3f806 main (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x366b806)
> #52 0x00007f3d209a6c88 (/usr/lib/libc.so.6+0x25c88)
> #53 0x00007f3d209a6d4c __libc_start_main (/usr/lib/libc.so.6+0x25d4c)
> #54 0x0000558534a2c125 _start (/home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin/clang-19+0x3658125)
> clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
> ClangBuiltLinux clang version 19.0.0git (https://github.com/llvm/llvm-project.git 1f6f97e)
> Target: x86_64-pc-linux-gnu
> Thread model: posix
> InstalledDir: /home/nathan/tmp/cvise.YrEYUS5WBZ/install/llvm-bad/bin
> Build config: +assertions
> clang: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.
>
> —
> Reply to this email directly, view it on GitHub
> <#99574 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ABNXLPQ6246XJ5ZFLAJOMU3ZNRAUBAVCNFSM6AAAAABLDPC57GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENBRHAYTIOBUGI>
> .
> You are receiving this because you modified the open/close state.Message
> ID: ***@***.***>
>
|
Empty fields sometimes don't have a corresponding LLVM field number, in order to make the layout work correctly. We slightly extended the cases where this applies recently; see #96422. |
So is it enough to test if the FieldDecl exists in the CGRecordLayout before asking for the FieldNo? When I do that, there are some other subtle changes that occur, though maybe those are from other changes... |
If a field doesn't correspond to an LLVM field, it has to be empty. Which should mean it's irrelevant to this calculation, I think. |
That was my thinking too. I'll send a PR for people to gaze at. I'm concerned about some of the changes to the test (technically, there should be none, but I've seen this happen before). |
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: 1f6f97e ("[Clang] Loop over FieldDecls instead of all Decls (llvm#99574)")
Only FieldDecls are important when determining GEP indices. A struct defined within another struct has the same semantics as if it were defined outside of the struct. So there's no need to look into RecordDecls that aren't a field. See commit 5bcf31e ("[Clang] Loop over FieldDecls instead of all Decls (llvm#89453)") Fixes 2039.
…m#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: 1f6f97e ("[Clang] Loop over FieldDecls instead of all Decls (llvm#99574)") Co-authored-by: Eli Friedman <efriedma@quicinc.com>
Summary: Only FieldDecls are important when determining GEP indices. A struct defined within another struct has the same semantics as if it were defined outside of the struct. So there's no need to look into RecordDecls that aren't a field. See commit 5bcf31e ("[Clang] Loop over FieldDecls instead of all Decls (#89453)") Fixes 2039. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250945
Only FieldDecls are important when determining GEP indices. A struct defined within another struct has the same semantics as if it were defined outside of the struct. So there's no need to look into RecordDecls that aren't a field.
See commit 5bcf31e ("[Clang] Loop over FieldDecls instead of all Decls (#89453)")
Fixes 2039.