r315982 - [Coverage] Discard deferred region in closing if-else

Vedant Kumar via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 17 00:47:39 PDT 2017


Author: vedantk
Date: Tue Oct 17 00:47:39 2017
New Revision: 315982

URL: http://llvm.org/viewvc/llvm-project?rev=315982&view=rev
Log:
[Coverage] Discard deferred region in closing if-else

A trailing deferred region isn't necessary in a function that ends with
this pattern:

  ...
  else {
    ...
    return;
  }

Special-case this pattern so that the closing curly brace of the
function isn't marked as uncovered. This issue came up in PR34962.

Modified:
    cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
    cfe/trunk/test/CoverageMapping/deferred-region.cpp

Modified: cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp?rev=315982&r1=315981&r2=315982&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp (original)
+++ cfe/trunk/lib/CodeGen/CoverageMappingGen.cpp Tue Oct 17 00:47:39 2017
@@ -758,6 +758,22 @@ struct CounterCoverageMappingBuilder
     handleFileExit(getEnd(S));
   }
 
+  /// Determine whether the final deferred region emitted in \p Body should be
+  /// discarded.
+  static bool discardFinalDeferredRegionInDecl(Stmt *Body) {
+    if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
+      Stmt *LastStmt = CS->body_back();
+      if (auto *IfElse = dyn_cast<IfStmt>(LastStmt)) {
+        if (auto *Else = dyn_cast_or_null<CompoundStmt>(IfElse->getElse()))
+          LastStmt = Else->body_back();
+        else
+          LastStmt = IfElse->getElse();
+      }
+      return dyn_cast_or_null<ReturnStmt>(LastStmt);
+    }
+    return false;
+  }
+
   void VisitDecl(const Decl *D) {
     assert(!DeferredRegion && "Deferred region never completed");
 
@@ -770,14 +786,14 @@ struct CounterCoverageMappingBuilder
     Counter ExitCount = propagateCounts(getRegionCounter(Body), Body);
     assert(RegionStack.empty() && "Regions entered but never exited");
 
-    // Special case: if the last statement is a return, throw away the
-    // deferred region. This allows the closing brace to have a count.
-    if (auto *CS = dyn_cast_or_null<CompoundStmt>(Body))
-      if (dyn_cast_or_null<ReturnStmt>(CS->body_back()))
+    if (DeferredRegion) {
+      // Complete (or discard) any deferred regions introduced by the last
+      // statement.
+      if (discardFinalDeferredRegionInDecl(Body))
         DeferredRegion = None;
-
-    // Complete any deferred regions introduced by the last statement.
-    popRegions(completeDeferred(ExitCount, getEnd(Body)));
+      else
+        popRegions(completeDeferred(ExitCount, getEnd(Body)));
+    }
   }
 
   void VisitReturnStmt(const ReturnStmt *S) {

Modified: cfe/trunk/test/CoverageMapping/deferred-region.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CoverageMapping/deferred-region.cpp?rev=315982&r1=315981&r2=315982&view=diff
==============================================================================
--- cfe/trunk/test/CoverageMapping/deferred-region.cpp (original)
+++ cfe/trunk/test/CoverageMapping/deferred-region.cpp Tue Oct 17 00:47:39 2017
@@ -31,11 +31,28 @@ void baz() { // CHECK: [[@LINE]]:12 -> [
 // CHECK-LABEL: _Z3mazv:
 void maz() {
   if (true)
-    return; // CHECK: Gap,File 0, [[@LINE]]:11 -> 36:3 = (#0 - #1)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
 
   return; // CHECK-NOT: Gap
 }
 
+// CHECK-LABEL: _Z4maazv:
+void maaz() {
+  if (true)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11
+  else
+    return; // CHECK-NOT: Gap,File 0, [[@LINE]]
+}
+
+// CHECK-LABEL: _Z5maaazv:
+void maaaz() {
+  if (true) {
+    return;
+  } else {  // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE]]:10
+    return; // CHECK-NOT: Gap,File 0, [[@LINE]]
+  }
+}
+
 // CHECK-LABEL: _Z3bari:
 void bar(int x) {
   IF (x)
@@ -158,6 +175,9 @@ int main() {
   foo(1);
   fooo(0);
   fooo(1);
+  maz();
+  maaz();
+  maaaz();
   baz();
   bar(0);
   bar(1);




More information about the cfe-commits mailing list