diff --git a/clang/test/Misc/inline-asm-clobber-warning.c b/clang/test/Misc/inline-asm-clobber-warning.c new file mode 100644 --- /dev/null +++ b/clang/test/Misc/inline-asm-clobber-warning.c @@ -0,0 +1,18 @@ +/// This test checks that the warning includes the location in the C source +/// file that contains the inline asm. Instead of saying for both. +/// Although this warning is emitted in llvm it cannot be tested from IR as +/// it does not have that location information at that stage. + +// RUN: %clang -target arm-arm-none-eabi -march=armv7-m -c %s -o /dev/null \ +// RUN: 2>&1 | FileCheck %s + +// REQUIRES: arm-registered-target + +void bar(void) { + __asm__ __volatile__ ( "nop" : : : "sp"); +} + +// CHECK: inline-asm-clobber-warning.c:12:28: warning: inline asm clobber list contains reserved registers: SP [-Winline-asm] +// CHECK-NEXT: __asm__ __volatile__ ( "nop" : : : "sp"); +// CHECK-NEXT: ^ +// CHECK-NEXT: inline-asm-clobber-warning.c:12:28: note: Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour. diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h --- a/llvm/include/llvm/IR/LLVMContext.h +++ b/llvm/include/llvm/IR/LLVMContext.h @@ -294,6 +294,16 @@ void emitError(const Instruction *I, const Twine &ErrorStr); void emitError(const Twine &ErrorStr); + /// emitWarning - Emit a warning message to the currently installed warning + /// handler with location information. Message will be implicitly prefixed + /// with "warning: " and should not end with a ".". + void emitWarning(unsigned LocCookie, const Twine &WarningStr); + + /// emitNote - Emit a note to the currently installed note handler with + /// location information. Same rules as emitWarning except the prefix will + /// be "note: ". + void emitNote(unsigned LocCookie, const Twine &NoteStr); + /// Access the object which can disable optional passes and individual /// optimizations at compile time. OptPassGate &getOptPassGate() const; diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -527,11 +527,6 @@ } if (!RestrRegs.empty()) { - unsigned BufNum = addInlineAsmDiagBuffer(OS.str(), LocMD); - auto &SrcMgr = *MMI->getContext().getInlineSourceManager(); - SMLoc Loc = SMLoc::getFromPointer( - SrcMgr.getMemoryBuffer(BufNum)->getBuffer().begin()); - std::string Msg = "inline asm clobber list contains reserved registers: "; ListSeparator LS; for (const Register &RR : RestrRegs) { @@ -542,8 +537,8 @@ "Reserved registers on the clobber list may not be " "preserved across the asm statement, and clobbering them may " "lead to undefined behaviour."; - SrcMgr.PrintMessage(Loc, SourceMgr::DK_Warning, Msg); - SrcMgr.PrintMessage(Loc, SourceMgr::DK_Note, Note); + MMI->getModule()->getContext().emitWarning(LocCookie, Msg.c_str()); + MMI->getModule()->getContext().emitNote(LocCookie, Note); } emitInlineAsm(OS.str(), getSubtargetInfo(), TM.Options.MCOptions, LocMD, diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp --- a/llvm/lib/IR/LLVMContext.cpp +++ b/llvm/lib/IR/LLVMContext.cpp @@ -252,6 +252,14 @@ diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); } +void LLVMContext::emitWarning(unsigned LocCookie, const Twine &WarningStr) { + diagnose(DiagnosticInfoInlineAsm(LocCookie, WarningStr, DS_Warning)); +} + +void LLVMContext::emitNote(unsigned LocCookie, const Twine &NoteStr) { + diagnose(DiagnosticInfoInlineAsm(LocCookie, NoteStr, DS_Note)); +} + //===----------------------------------------------------------------------===// // Metadata Kind Uniquing //===----------------------------------------------------------------------===//