[clang] [inline-asm] Fixed issue no. 164973 (PR #167316)
Anakala Sashikiran via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 10 06:08:45 PST 2025
https://github.com/AnSaki57 created https://github.com/llvm/llvm-project/pull/167316
Made modifications to CGStmt.cpp and added a clang CodeGen test named "asm-srcloc-split-literal.c".
>From d7b4416ffe9182ccbdd55db58f265204bb798235 Mon Sep 17 00:00:00 2001
From: AnSaki57 <anakalasashikiran at gmail.com>
Date: Mon, 10 Nov 2025 19:33:59 +0530
Subject: [PATCH] [inline-asm] Fixed issue no. 164973, making modifications to
CGStmt.cpp and adding a clang CodeGen test named
"asm-srcloc-split-literal.c".
---
clang/lib/CodeGen/CGStmt.cpp | 43 +++++++++++++++----
clang/test/CodeGen/asm-srcloc-split-literal.c | 23 ++++++++++
2 files changed, 57 insertions(+), 9 deletions(-)
create mode 100644 clang/test/CodeGen/asm-srcloc-split-literal.c
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
+
More information about the cfe-commits
mailing list