ikudrin created this revision.
ikudrin added reviewers: vsk, bogner, davidxl.
ikudrin added a subscriber: cfe-commits.
ikudrin set the repository for this revision to rL LLVM.

We had an assertion failure if, for example, the definition of an unused inline 
function starts
in one macro and ends in another. This patch fixes the issue by finding the 
common ancestor
of the start and end locations of that function's body and changing the 
locations accordingly.

Repository:
  rL LLVM

http://reviews.llvm.org/D20997

Files:
  lib/CodeGen/CoverageMappingGen.cpp
  test/CoverageMapping/Inputs/ends_a_scope_only
  test/CoverageMapping/Inputs/starts_a_scope_only
  test/CoverageMapping/unused_function.cpp

Index: test/CoverageMapping/unused_function.cpp
===================================================================
--- /dev/null
+++ test/CoverageMapping/unused_function.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only %s | tee %t.out | FileCheck %s
+
+#define START_SCOPE {
+#define END_SCOPE }
+
+// CHECK: _Z2f0v:
+// CHECK-NEXT: File 0, [[@LINE+1]]:18 -> [[@LINE+1]]:20 = 0
+inline void f0() {}
+
+// CHECK: _Z2f1v:
+// CHECK-NEXT: File 0, [[@LINE+1]]:18 -> [[@LINE+1]]:31 = 0
+inline void f1() START_SCOPE }
+
+// CHECK: _Z2f2v:
+// CHECK-NEXT: File 0, [[@LINE+1]]:18 -> [[@LINE+1]]:29 = 0
+inline void f2() { END_SCOPE
+
+// CHECK: _Z2f3v:
+// CHECK-NEXT: File 0, [[@LINE+1]]:18 -> [[@LINE+1]]:39 = 0
+inline void f3() START_SCOPE END_SCOPE
+
+// CHECK: _Z2f4v:
+// CHECK-NEXT: File 0, [[@LINE+2]]:10 -> [[@LINE+3]]:2 = 0
+inline void f4()
+#include "Inputs/starts_a_scope_only"
+}
+
+// CHECK: _Z2f5v:
+// CHECK-NEXT: File 0, [[@LINE+1]]:18 -> [[@LINE+2]]:36 = 0
+inline void f5() {
+#include "Inputs/ends_a_scope_only"
+
+// CHECK: _Z2f6v:
+// CHECK-NEXT: File 0, [[@LINE+2]]:10 -> [[@LINE+3]]:36 = 0
+inline void f6()
+#include "Inputs/starts_a_scope_only"
+#include "Inputs/ends_a_scope_only"
Index: test/CoverageMapping/Inputs/starts_a_scope_only
===================================================================
--- /dev/null
+++ test/CoverageMapping/Inputs/starts_a_scope_only
@@ -0,0 +1 @@
+{
Index: test/CoverageMapping/Inputs/ends_a_scope_only
===================================================================
--- /dev/null
+++ test/CoverageMapping/Inputs/ends_a_scope_only
@@ -0,0 +1 @@
+}
Index: lib/CodeGen/CoverageMappingGen.cpp
===================================================================
--- lib/CodeGen/CoverageMappingGen.cpp
+++ lib/CodeGen/CoverageMappingGen.cpp
@@ -130,6 +130,16 @@
     return strcmp(SM.getBufferName(SM.getSpellingLoc(Loc)), "<built-in>") == 0;
   }
 
+  /// \brief Check whether \c Loc is included or expanded from \c Parent.
+  bool isNestedIn(SourceLocation Loc, FileID Parent) {
+    do {
+      Loc = getIncludeOrExpansionLoc(Loc);
+      if (Loc.isInvalid())
+        return false;
+    } while (!SM.isInFileID(Loc, Parent));
+    return true;
+  }
+
   /// \brief Get the start of \c S ignoring macro arguments and builtin macros.
   SourceLocation getStart(const Stmt *S) {
     SourceLocation Loc = S->getLocStart();
@@ -310,7 +320,23 @@
     if (!D->hasBody())
       return;
     auto Body = D->getBody();
-    SourceRegions.emplace_back(Counter(), getStart(Body), getEnd(Body));
+    SourceLocation Start = getStart(Body);
+    SourceLocation End = getEnd(Body);
+    if (!SM.isWrittenInSameFile(Start, End)) {
+      // Walk up to find the common ancestor.
+      // Correct the locations accordingly.
+      FileID ParentFile = SM.getFileID(Start);
+      while (ParentFile != SM.getFileID(End) && !isNestedIn(End, ParentFile)) {
+        Start = getIncludeOrExpansionLoc(Start);
+        assert(Start.isValid());
+        ParentFile = SM.getFileID(Start);
+      }
+      while (ParentFile != SM.getFileID(End)) {
+        End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End));
+        assert(End.isValid());
+      }
+    }
+    SourceRegions.emplace_back(Counter(), Start, End);
   }
 
   /// \brief Write the mapping data to the output stream
@@ -471,16 +497,6 @@
       MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation);
   }
 
-  /// \brief Check whether \c Loc is included or expanded from \c Parent.
-  bool isNestedIn(SourceLocation Loc, FileID Parent) {
-    do {
-      Loc = getIncludeOrExpansionLoc(Loc);
-      if (Loc.isInvalid())
-        return false;
-    } while (!SM.isInFileID(Loc, Parent));
-    return true;
-  }
-
   /// \brief Adjust regions and state when \c NewLoc exits a file.
   ///
   /// If moving from our most recently tracked location to \c NewLoc exits any
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to