llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Anakala Sashikiran (AnSaki57) <details> <summary>Changes</summary> Made modifications to CGStmt.cpp and added a clang CodeGen test named "asm-srcloc-split-literal.c". --- Full diff: https://github.com/llvm/llvm-project/pull/167316.diff 2 Files Affected: - (modified) clang/lib/CodeGen/CGStmt.cpp (+34-9) - (added) clang/test/CodeGen/asm-srcloc-split-literal.c (+23) ``````````diff diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 36be3295950b8..5a062b74b0607 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -2572,24 +2572,49 @@ CodeGenFunction::EmitAsmInput(const TargetInfo::ConstraintInfo &Info, static llvm::MDNode *getAsmSrcLocInfo(const StringLiteral *Str, CodeGenFunction &CGF) { SmallVector<llvm::Metadata *, 8> Locs; + + // We need these to find the correct location for the first line. + StringRef StrVal = Str->getString(); + const SourceManager &SM = CGF.CGM.getContext().getSourceManager(); + const LangOptions &LangOpts = CGF.CGM.getLangOpts(); + unsigned StartToken = 0; + unsigned ByteOffset = 0; + // Add the location of the first line to the MDNode. + + // Find the offset of the first character that isn't horizontal whitespace. + size_t FirstLocOffset = StrVal.find_first_not_of(" \t\v\f"); + + // If the string is empty or all-whitespace, default to offset 0. + if (FirstLocOffset == StringRef::npos) + FirstLocOffset = 0; + + SourceLocation FirstLineLoc = Str->getLocationOfByte( + FirstLocOffset, SM, LangOpts, CGF.getTarget(), &StartToken, &ByteOffset); + Locs.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( - CGF.Int64Ty, Str->getBeginLoc().getRawEncoding()))); - StringRef StrVal = Str->getString(); - if (!StrVal.empty()) { - const SourceManager &SM = CGF.CGM.getContext().getSourceManager(); - const LangOptions &LangOpts = CGF.CGM.getLangOpts(); - unsigned StartToken = 0; - unsigned ByteOffset = 0; + CGF.Int64Ty, FirstLineLoc.getRawEncoding()))); + if (!StrVal.empty()) { // Add the location of the start of each subsequent line of the asm to the // MDNode. for (unsigned i = 0, e = StrVal.size() - 1; i != e; ++i) { if (StrVal[i] != '\n') continue; + + // The next line starts at byte offset i + 1. + // Find the first non-horizontal-whitespace at or after this offset. + size_t NextLineOffset = StrVal.find_first_not_of(" \t\v\f", i + 1); + + // If the rest of the string is empty or all-whitespace, + // just use the location right after the newline (i + 1). + if (NextLineOffset == StringRef::npos) + NextLineOffset = i + 1; + SourceLocation LineLoc = Str->getLocationOfByte( - i + 1, SM, LangOpts, CGF.getTarget(), &StartToken, &ByteOffset); + NextLineOffset, SM, LangOpts, CGF.getTarget(), &StartToken, &ByteOffset); + Locs.push_back(llvm::ConstantAsMetadata::get( - llvm::ConstantInt::get(CGF.Int64Ty, LineLoc.getRawEncoding()))); + llvm::ConstantInt::get(CGF.Int64Ty, LineLoc.getRawEncoding()))); } } diff --git a/clang/test/CodeGen/asm-srcloc-split-literal.c b/clang/test/CodeGen/asm-srcloc-split-literal.c new file mode 100644 index 0000000000000..a1d898264e6bd --- /dev/null +++ b/clang/test/CodeGen/asm-srcloc-split-literal.c @@ -0,0 +1,23 @@ +/// Test that inline asm source location corresponds to the actual +/// instruction line, not the first line of the asm block. +/// +/// RUN: not %clang_cc1 -triple x86_64-pc-linux-gnu -emit-obj %s 2>&1 | FileCheck %s + +// #include <stdint.h> +// #include <string.h> + +void *memset(void *dest, int c, int n)__attribute__((naked)); +void *memset(void *dest, int c, int n) { + __asm__( + "\t" // <-- line with only a tab + "xchg %eax, %eax\n" // <-- A valid instruction + "\t" // <-- line with only a tab + "mov rdi, 1\n" // <-- An invalid instruction + ); +} + +int main() { return 0; } + +// CHECK: error: unknown use of instruction mnemonic +// CHECK-NEXT: mov rdi, 1 + `````````` </details> https://github.com/llvm/llvm-project/pull/167316 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
