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

Reply via email to