commit 90c1a2c41aafb1e35e075fb7d0bdcf04c00db913 (tree)
parent 33de937fd91c64cd65894369cf7d92665a8e582e
Author: Andrew Kelley <andrew@ziglang.org>
Date: Sat, 2 Mar 2024 21:43:39 -0800
Merge pull request #19152 from antlilja/llvm-broken-debug
LLVM: Fail to emit if LLVM encounters broken debug info
Diffstat:
4 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
@@ -1245,9 +1245,11 @@ pub const Object = struct {
);
defer bitcode_memory_buffer.dispose();
+ context.enableBrokenDebugInfoCheck();
+
var module: *llvm.Module = undefined;
- if (context.parseBitcodeInContext2(bitcode_memory_buffer, &module).toBool()) {
- std.debug.print("Failed to parse bitcode\n", .{});
+ if (context.parseBitcodeInContext2(bitcode_memory_buffer, &module).toBool() or context.getBrokenDebugInfo()) {
+ log.err("Failed to parse bitcode", .{});
return error.FailedToEmit;
}
break :emit .{ context, module };
diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig
@@ -37,6 +37,12 @@ pub const Context = opaque {
pub const setOptBisectLimit = ZigLLVMSetOptBisectLimit;
extern fn ZigLLVMSetOptBisectLimit(C: *Context, limit: c_int) void;
+
+ pub const enableBrokenDebugInfoCheck = ZigLLVMEnableBrokenDebugInfoCheck;
+ extern fn ZigLLVMEnableBrokenDebugInfoCheck(C: *Context) void;
+
+ pub const getBrokenDebugInfo = ZigLLVMGetBrokenDebugInfo;
+ extern fn ZigLLVMGetBrokenDebugInfo(C: *Context) bool;
};
pub const Module = opaque {
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp
@@ -380,6 +380,31 @@ void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit) {
unwrap(context_ref)->setOptPassGate(opt_bisect);
}
+struct ZigDiagnosticHandler : public DiagnosticHandler {
+ bool BrokenDebugInfo;
+ ZigDiagnosticHandler() : BrokenDebugInfo(false) {}
+ bool handleDiagnostics(const DiagnosticInfo &DI) override {
+ // This dyn_cast should be casting to DiagnosticInfoIgnoringInvalidDebugMetadata
+ // but DiagnosticInfoIgnoringInvalidDebugMetadata is treated as DiagnosticInfoDebugMetadataVersion
+ // because of a bug in LLVM (see https://github.com/ziglang/zig/issues/19161).
+ // After this is fixed add an additional check for DiagnosticInfoIgnoringInvalidDebugMetadata
+ // but don't remove the current one as both indicate that debug info is broken.
+ if (auto *Remark = dyn_cast<DiagnosticInfoDebugMetadataVersion>(&DI)) {
+ BrokenDebugInfo = true;
+ }
+ return false;
+ }
+};
+
+void ZigLLVMEnableBrokenDebugInfoCheck(LLVMContextRef context_ref) {
+ unwrap(context_ref)->setDiagnosticHandler(std::make_unique<ZigDiagnosticHandler>());
+}
+
+bool ZigLLVMGetBrokenDebugInfo(LLVMContextRef context_ref) {
+ return ((const ZigDiagnosticHandler*)
+ unwrap(context_ref)->getDiagHandlerPtr())->BrokenDebugInfo;
+}
+
void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {
cl::ParseCommandLineOptions(argc, argv);
}
diff --git a/src/zig_llvm.h b/src/zig_llvm.h
@@ -44,6 +44,9 @@ ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, co
ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit);
+ZIG_EXTERN_C void ZigLLVMEnableBrokenDebugInfoCheck(LLVMContextRef context_ref);
+ZIG_EXTERN_C bool ZigLLVMGetBrokenDebugInfo(LLVMContextRef context_ref);
+
enum ZigLLVMTailCallKind {
ZigLLVMTailCallKindNone,
ZigLLVMTailCallKindTail,