[asan] Append line number to variable name if line is available and in the same file as the function.

PR30498

Reviewers: eugenis

Differential Revision: https://reviews.llvm.org/D25715

llvm-svn: 284546
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index e158302..507776a 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2247,7 +2247,8 @@
   if (LocalEscapeCall) LocalEscapeCall->moveBefore(InsBefore);
 
   // Find static allocas with lifetime analysis.
-  DenseMap<const AllocaInst *, const ASanStackVariableDescription *>
+  DenseMap<const AllocaInst *,
+           std::pair<const ASanStackVariableDescription *, unsigned>>
       AllocaToSVDMap;
   for (const auto &APC : StaticAllocaPoisonCallVec) {
     assert(APC.InsBefore);
@@ -2255,22 +2256,31 @@
     assert(ASan.isInterestingAlloca(*APC.AI));
     assert(APC.AI->isStaticAlloca());
 
-    AllocaToSVDMap[APC.AI] = nullptr;
+    auto &Pair = AllocaToSVDMap[APC.AI];
+    if (const DILocation *FnLoc = EntryDebugLocation.get()) {
+      if (const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
+        if (LifetimeLoc->getFile() == FnLoc->getFile())
+          if (unsigned Line = LifetimeLoc->getLine())
+            Pair.second = std::min(Pair.second ? Pair.second : Line, Line);
+      }
+    }
   }
 
   SmallVector<ASanStackVariableDescription, 16> SVD;
   SVD.reserve(AllocaVec.size());
   for (AllocaInst *AI : AllocaVec) {
-    size_t UseAfterScopePoisonSize =
-        AllocaToSVDMap.find(AI) != AllocaToSVDMap.end()
-            ? ASan.getAllocaSizeInBytes(*AI)
-            : 0;
     ASanStackVariableDescription D = {AI->getName().data(),
                                       ASan.getAllocaSizeInBytes(*AI),
-                                      UseAfterScopePoisonSize,
+                                      0,
                                       AI->getAlignment(),
                                       AI,
+                                      0,
                                       0};
+    auto It = AllocaToSVDMap.find(AI);
+    if (It != AllocaToSVDMap.end()) {
+      D.LifetimeSize = D.Size;
+      D.Line = It->second.second;
+    }
     SVD.push_back(D);
   }
   // Minimal header size (left redzone) is 4 pointers,
@@ -2386,7 +2396,7 @@
     for (const auto &Desc : SVD) {
       auto It = AllocaToSVDMap.find(Desc.AI);
       if (It != AllocaToSVDMap.end()) {
-        It->second = &Desc;
+        It->second.first = &Desc;
       }
     }
 
@@ -2395,8 +2405,8 @@
     // Poison static allocas near lifetime intrinsics.
     for (const auto &APC : StaticAllocaPoisonCallVec) {
       // Must be already set.
-      assert(AllocaToSVDMap[APC.AI]);
-      const auto &Desc = *AllocaToSVDMap[APC.AI];
+      assert(AllocaToSVDMap[APC.AI].first);
+      const auto &Desc = *AllocaToSVDMap[APC.AI].first;
       assert(Desc.Offset % L.Granularity == 0);
       size_t Begin = Desc.Offset / L.Granularity;
       size_t End = Begin + (APC.Size + L.Granularity - 1) / L.Granularity;
diff --git a/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp b/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp
index bdd55a2..dc226b2 100644
--- a/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp
+++ b/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 #include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/IR/DebugInfo.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -75,13 +76,17 @@
     size_t Alignment = std::max(Granularity, Vars[i].Alignment);
     (void)Alignment;  // Used only in asserts.
     size_t Size = Vars[i].Size;
-    const char *Name = Vars[i].Name;
+    std::string Name = Vars[i].Name;
     assert((Alignment & (Alignment - 1)) == 0);
     assert(Layout.FrameAlignment >= Alignment);
     assert((Offset % Alignment) == 0);
     assert(Size > 0);
     assert(Vars[i].LifetimeSize <= Size);
-    StackDescription << " " << Offset << " " << Size << " " << strlen(Name)
+    if (Vars[i].Line) {
+      Name += ":";
+      Name += std::to_string(Vars[i].Line);
+    }
+    StackDescription << " " << Offset << " " << Size << " " << Name.size()
                      << " " << Name;
     size_t NextAlignment = IsLast ? Granularity
                    : std::max(Granularity, Vars[i + 1].Alignment);