[PATCH] MIR Serialization: Report diagnostics with correct locations for LLVM IR Errors.
Duncan P. N. Exon Smith
dexonsmith at apple.com
Thu May 28 16:34:15 PDT 2015
> On 2015-May-28, at 15:52, Alex Lorenz <arphaman at gmail.com> wrote:
>
> Hi dexonsmith, bob.wilson, bogner,
>
> This patch translates the line and column numbers from LLVM IR block string to the
> line and column numbers in the MIR file so that llc reports LLVM IR errors with
> correct locations.
>
> REPOSITORY
> rL LLVM
>
> http://reviews.llvm.org/D10108
>
> Files:
> lib/CodeGen/MIRParser/MIRParser.cpp
> test/CodeGen/MIR/llvm-ir-error-reported.mir
>
> Index: lib/CodeGen/MIRParser/MIRParser.cpp
> ===================================================================
> --- lib/CodeGen/MIRParser/MIRParser.cpp
> +++ lib/CodeGen/MIRParser/MIRParser.cpp
> @@ -18,6 +18,7 @@
> #include "llvm/AsmParser/Parser.h"
> #include "llvm/CodeGen/MIRYamlMapping.h"
> #include "llvm/IR/Module.h"
> +#include "llvm/Support/LineIterator.h"
> #include "llvm/Support/SMLoc.h"
> #include "llvm/Support/SourceMgr.h"
> #include "llvm/Support/MemoryBuffer.h"
> @@ -49,6 +50,11 @@
> ///
> /// Return true if an error occurred.
> bool parseMachineFunction(yaml::Input &In);
> +
> +private:
> + /// Return a MIR diagnostic converted from an LLVM assembly diagnostic.
> + SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
> + SMRange SourceRange);
> };
>
> } // end anonymous namespace
> @@ -81,8 +87,10 @@
> dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
> M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
> Context);
> - if (!M)
> + if (!M) {
> + Error = diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange());
> return M;
> + }
> In.nextDocument();
> if (!In.setCurrentDocument())
> return M;
> @@ -111,6 +119,36 @@
> return false;
> }
>
> +SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
> + SMRange SourceRange) {
> + assert(SourceRange.isValid());
> +
> + // Translate the location of the error from the location in the llvm IR string
> + // to the corresponding location in the MIR file.
> + auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start);
> + unsigned Line = LineAndColumn.first + Error.getLineNo() - 1;
> + unsigned Column = Error.getColumnNo();
> + StringRef LineStr = Error.getLineContents();
> + SMLoc Loc = Error.getLoc();
> +
> + // Get the full line and adjust the column number by taking the indentation of
> + // LLVM IR into account.
> + line_iterator Lines(*SM.getMemoryBuffer(SM.getMainFileID()), false);
> + while (!Lines.is_at_end() && Lines.line_number() != Line)
> + ++Lines;
> + if (Lines.line_number() == Line) {
> + LineStr = *Lines;
> + Loc = SMLoc::getFromPointer(LineStr.data());
> + auto Indent = LineStr.find(Error.getLineContents());
> + if (Indent != StringRef::npos)
> + Column += Indent;
> + }
According to the `line_iterator` docs, calling `line_number()` isn't
safe at EOF. Your `if` statement looks like it could violate that.
I think you should change this to use a standard iterator pattern, and
only use the iterator when it's valid:
for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E;
L != E; ++L)
if (L.line_number() == Line) {
LineStr = *L;
Loc = SMLoc::getFromPointer(LineStr.data());
auto Indent = LineStr.find(Error.getLineContents());
if (Indent != StringRef::npos)
Column += Indent;
break;
}
With that change, this LGTM.
> +
> + return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(),
> + Error.getMessage(), LineStr, Error.getRanges(),
> + Error.getFixIts());
> +}
> +
> std::unique_ptr<Module> llvm::parseMIRFile(StringRef Filename,
> SMDiagnostic &Error,
> LLVMContext &Context) {
> Index: test/CodeGen/MIR/llvm-ir-error-reported.mir
> ===================================================================
> --- /dev/null
> +++ test/CodeGen/MIR/llvm-ir-error-reported.mir
> @@ -0,0 +1,22 @@
> +# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
> +# This test ensures an error is reported if the embedded LLVM IR contains an
> +# error.
> +
> +--- |
> +
> + ; CHECK: [[@LINE+3]]:15: error: use of undefined value '%a'
> + define i32 @foo(i32 %x, i32 %y) {
> + %z = alloca i32, align 4
> + store i32 %a, i32* %z, align 4
> + br label %Test
> + Test:
> + %m = load i32, i32* %z, align 4
> + %cond = icmp eq i32 %y, %m
> + br i1 %cond, label %IfEqual, label %IfUnequal
> + IfEqual:
> + ret i32 1
> + IfUnequal:
> + ret i32 0
> + }
> +
> +...
>
More information about the llvm-commits
mailing list