From 65c7215773325cb4cd6da0d5fd428d87e38a2436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Ferreira?= Date: Sun, 22 Jan 2023 02:25:11 +0000 Subject: [PATCH] driver: add support for a more generic diagnostic handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luís Ferreira --- driver/codegenerator.cpp | 68 ++++++++++++++++++++++++---- tests/codegen/attr_warn_stack_size.d | 14 ++++++ 2 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 tests/codegen/attr_warn_stack_size.d diff --git a/driver/codegenerator.cpp b/driver/codegenerator.cpp index e92c71866f5..d028e66c8c6 100644 --- a/driver/codegenerator.cpp +++ b/driver/codegenerator.cpp @@ -33,6 +33,7 @@ #else #include "llvm/IR/RemarkStreamer.h" #endif +#include "llvm/Demangle/Demangle.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/ToolOutputFile.h" @@ -166,19 +167,68 @@ void inlineAsmDiagnosticHandler(const llvm::SMDiagnostic &d, void *context, inlineAsmDiagnostic(static_cast(context), d, locCookie); } #else -struct InlineAsmDiagnosticHandler : public llvm::DiagnosticHandler { +struct LDCDiagnosticHandler : public llvm::DiagnosticHandler { IRState *irs; - InlineAsmDiagnosticHandler(IRState *irs) : irs(irs) {} + LDCDiagnosticHandler(IRState *irs) : irs(irs) {} // return false to defer to LLVMContext::diagnose() bool handleDiagnostics(const llvm::DiagnosticInfo &DI) override { - if (DI.getKind() != llvm::DK_SrcMgr) + switch (DI.getKind()) + { + case llvm::DK_SrcMgr: + { + const auto &DISM = llvm::cast(DI); + switch (DISM.getSeverity()) + { + case llvm::DS_Error: + ++global.errors; + break; + case llvm::DS_Warning: + ++global.warnings; + break; + case llvm::DS_Remark: + case llvm::DS_Note: + return false; + } + + inlineAsmDiagnostic(irs, DISM.getSMDiag(), DISM.getLocCookie()); + return true; + } + case llvm::DK_StackSize: + { + const auto &DISS = llvm::cast(DI); +#if LDC_LLVM_VER > 1400 + llvm::StringRef fname; + unsigned line, column; + DISS.getLocation(fname, line, column); + const auto loc = Loc(fname.str().c_str(), line, column); +#else + const auto loc = Loc(nullptr, 0, 0); +#endif + switch (DISS.getSeverity()) + { + case llvm::DS_Error: + error(loc, "stack frame size (%ld) exceeds limit (%ld) in '%s'", + DISS.getStackSize(), + DISS.getStackLimit(), + llvm::demangle(DISS.getFunction().getName().str()).c_str() + ); + return true; + case llvm::DS_Warning: + warning(loc, "stack frame size (%ld) exceeds limit (%ld) in '%s'", + DISS.getStackSize(), + DISS.getStackLimit(), + llvm::demangle(DISS.getFunction().getName().str()).c_str() + ); + return true; + case llvm::DS_Remark: + case llvm::DS_Note: + return false; + } return false; - - const auto &DISM = llvm::cast(DI); - if (DISM.getKind() == llvm::SourceMgr::DK_Error) - ++global.errors; - return inlineAsmDiagnostic(irs, DISM.getSMDiag(), DISM.getLocCookie()); + } + } + return false; } }; #endif @@ -280,7 +330,7 @@ void CodeGenerator::writeAndFreeLLModule(const char *filename) { context_.setInlineAsmDiagnosticHandler(inlineAsmDiagnosticHandler, ir_); #else context_.setDiagnosticHandler( - std::make_unique(ir_)); + std::make_unique(ir_)); #endif std::unique_ptr diagnosticsOutputFile = diff --git a/tests/codegen/attr_warn_stack_size.d b/tests/codegen/attr_warn_stack_size.d new file mode 100644 index 00000000000..25e63b1294a --- /dev/null +++ b/tests/codegen/attr_warn_stack_size.d @@ -0,0 +1,14 @@ +module attr_warn_stack_size; +// Test diagnostics for warnings on stack size + +// RUN: not %ldc -w -c %s 2>&1 | FileCheck %s + +import ldc.attributes; + +// CHECK: {{.*}}Warning: stack frame size (8) exceeds limit (1) in '_D20attr_warn_stack_size6foobarFiZf' +@llvmAttr("warn-stack-size", "1") +float foobar(int f) +{ + float _ = f; + return _; +}