r271969 - [Coverage] Fix an assertion failure if the definition of an unused function spans multiple files.

Igor Kudrin via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 6 19:17:05 PDT 2016


Author: ikudrin
Date: Mon Jun  6 21:17:03 2016
New Revision: 271969

URL: http://llvm.org/viewvc/llvm-project?rev=271969&view=rev
Log:
[Coverage] Fix an assertion failure if the definition of an unused function spans multiple files.

We have 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.

Differential Revision: http://reviews.llvm.org/D20997

Added:
    cfe/trunk/test/CoverageMapping/Inputs/ends_a_scope_only
    cfe/trunk/test/CoverageMapping/Inputs/starts_a_scope_only
    cfe/trunk/test/CoverageMapping/unused_function.cpp
Modified:
    cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp

Modified: cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp?rev=271969&r1=271968&r2=271969&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp (original)
+++ cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp Mon Jun  6 21:17:03 2016
@@ -130,6 +130,16 @@ public:
     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,27 @@ struct EmptyCoverageMappingBuilder : pub
     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 StartFileID = SM.getFileID(Start);
+      FileID EndFileID = SM.getFileID(End);
+      while (StartFileID != EndFileID && !isNestedIn(End, StartFileID)) {
+        Start = getIncludeOrExpansionLoc(Start);
+        assert(Start.isValid() &&
+               "Declaration start location not nested within a known region");
+        StartFileID = SM.getFileID(Start);
+      }
+      while (StartFileID != EndFileID) {
+        End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End));
+        assert(End.isValid() &&
+               "Declaration end location not nested within a known region");
+        EndFileID = SM.getFileID(End);
+      }
+    }
+    SourceRegions.emplace_back(Counter(), Start, End);
   }
 
   /// \brief Write the mapping data to the output stream
@@ -471,16 +501,6 @@ struct CounterCoverageMappingBuilder
       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

Added: cfe/trunk/test/CoverageMapping/Inputs/ends_a_scope_only
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CoverageMapping/Inputs/ends_a_scope_only?rev=271969&view=auto
==============================================================================
--- cfe/trunk/test/CoverageMapping/Inputs/ends_a_scope_only (added)
+++ cfe/trunk/test/CoverageMapping/Inputs/ends_a_scope_only Mon Jun  6 21:17:03 2016
@@ -0,0 +1 @@
+}

Added: cfe/trunk/test/CoverageMapping/Inputs/starts_a_scope_only
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CoverageMapping/Inputs/starts_a_scope_only?rev=271969&view=auto
==============================================================================
--- cfe/trunk/test/CoverageMapping/Inputs/starts_a_scope_only (added)
+++ cfe/trunk/test/CoverageMapping/Inputs/starts_a_scope_only Mon Jun  6 21:17:03 2016
@@ -0,0 +1 @@
+{

Added: cfe/trunk/test/CoverageMapping/unused_function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CoverageMapping/unused_function.cpp?rev=271969&view=auto
==============================================================================
--- cfe/trunk/test/CoverageMapping/unused_function.cpp (added)
+++ cfe/trunk/test/CoverageMapping/unused_function.cpp Mon Jun  6 21:17:03 2016
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only %s | 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"




More information about the cfe-commits mailing list