From 4d090dad54fb34c75c156acde0330782d349ae45 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Tue, 27 Sep 2016 23:30:36 +0000 Subject: [PATCH] [Coverage] The coverage region for switch covers the code after the switch. This patch fixes a regression introduced in r262697 that changed the way the coverage regions for switches are constructed. The PGO instrumentation counter for a switch statement refers to the counter at the exit of the switch. Therefore, the coverage region for the switch statement should cover the code that comes after the switch, and not the switch statement itself. rdar://28480997 Differential Revision: https://reviews.llvm.org/D24981 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@282554 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CoverageMappingGen.cpp | 6 +++++- test/CoverageMapping/switch.c | 24 ++++++++++++------------ test/CoverageMapping/switchmacro.c | 2 +- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/CodeGen/CoverageMappingGen.cpp b/lib/CodeGen/CoverageMappingGen.cpp index e008f44fc6..0e51658e4b 100644 --- a/lib/CodeGen/CoverageMappingGen.cpp +++ b/lib/CodeGen/CoverageMappingGen.cpp @@ -842,7 +842,11 @@ struct CounterCoverageMappingBuilder Counter ExitCount = getRegionCounter(S); SourceLocation ExitLoc = getEnd(S); - pushRegion(ExitCount, getStart(S), ExitLoc); + pushRegion(ExitCount); + + // Ensure that handleFileExit recognizes when the end location is located + // in a different file. + MostRecentLocation = getStart(S); handleFileExit(ExitLoc); } diff --git a/test/CoverageMapping/switch.c b/test/CoverageMapping/switch.c index 6aa2b31426..9463eb3ee3 100644 --- a/test/CoverageMapping/switch.c +++ b/test/CoverageMapping/switch.c @@ -1,44 +1,44 @@ // RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name switch.c %s | FileCheck %s // CHECK: foo void foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+8]]:2 = #0 - switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:4 = #1 + switch(i) { case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #2 return; case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #3 break; } - int x = 0; + int x = 0; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #1 } void nop() {} // CHECK: bar void bar(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+20]]:2 = #0 - switch (i) // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:6 = #1 + switch (i) ; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:6 = 0 - switch (i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:4 = #2 + switch (i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+16]]:2 = #1 } - switch (i) // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #3 + switch (i) // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+13]]:2 = #2 nop(); // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:10 = 0 - switch (i) // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #4 + switch (i) // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+10]]:2 = #3 case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #5 nop(); - switch (i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:4 = #6 + switch (i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+6]]:2 = #4 nop(); // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:10 = 0 case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #7 nop(); } - nop(); + nop(); // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #6 } // CHECK-NEXT: main int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+34]]:2 = #0 int i = 0; - switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+9]]:4 = #1 + switch(i) { case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+7]]:10 = #2 i = 1; break; @@ -48,7 +48,7 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+34]]:2 = #0 default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #4 break; } - switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+8]]:4 = #5 + switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+22]]:2 = #1 case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+6]]:10 = #6 i = 1; break; @@ -58,7 +58,7 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+34]]:2 = #0 break; } - switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+7]]:4 = #9 + switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+12]]:2 = #5 case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:11 = #10 case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:11 = (#10 + #11) i = 11; @@ -67,7 +67,7 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+34]]:2 = #0 i = 99; } - foo(1); + foo(1); // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:11 = #9 bar(1); return 0; } diff --git a/test/CoverageMapping/switchmacro.c b/test/CoverageMapping/switchmacro.c index f83d26fd16..55f93d8f60 100644 --- a/test/CoverageMapping/switchmacro.c +++ b/test/CoverageMapping/switchmacro.c @@ -4,7 +4,7 @@ // CHECK: foo int foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> {{[0-9]+}}:2 = #0 - switch (i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> {{[0-9]+}}:4 = #1 + switch (i) { default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> {{[0-9]+}}:11 = #2 if (i == 1) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = #2 return 0; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = #3 -- 2.40.0