[Coverage] Introduce "partial fold" on BranchRegion (#112694)
Currently both True/False counts were folded. It lost the information, "It is True or False before folding." It prevented recalling branch counts in merging template instantiations. In `llvm-cov`, a folded branch is shown as: - `[True: n, Folded]` - `[Folded, False n]` In the case If `n` is zero, a branch is reported as "uncovered". This is distinguished from "folded" branch. When folded branches are merged, `Folded` may be dissolved. In the coverage map, either `Counter` is `Zero`. Currently both were `Zero`. Since "partial fold" has been introduced, either case in `switch` is omitted as `Folded`. Each `case:` in `switch` is reported as `[True: n, Folded]`, since `False` count doesn't show meaningful value. When `switch` doesn't have `default:`, `switch (Cond)` is reported as `[Folded, False: n]`, since `True` count was just the sum of `case`(s). `switch` with `default` can be considered as "the statement that doesn't have any `False`(s)".
This commit is contained in:
@@ -1098,12 +1098,6 @@ struct CounterCoverageMappingBuilder
|
||||
return ExitCount;
|
||||
}
|
||||
|
||||
/// Determine whether the given condition can be constant folded.
|
||||
bool ConditionFoldsToBool(const Expr *Cond) {
|
||||
Expr::EvalResult Result;
|
||||
return (Cond->EvaluateAsInt(Result, CVM.getCodeGenModule().getContext()));
|
||||
}
|
||||
|
||||
/// Create a Branch Region around an instrumentable condition for coverage
|
||||
/// and add it to the function's SourceRegions. A branch region tracks a
|
||||
/// "True" counter and a "False" counter for boolean expressions that
|
||||
@@ -1133,13 +1127,15 @@ struct CounterCoverageMappingBuilder
|
||||
// Alternatively, we can prevent any optimization done via
|
||||
// constant-folding by ensuring that ConstantFoldsToSimpleInteger() in
|
||||
// CodeGenFunction.c always returns false, but that is very heavy-handed.
|
||||
if (ConditionFoldsToBool(C))
|
||||
popRegions(pushRegion(Counter::getZero(), getStart(C), getEnd(C),
|
||||
Counter::getZero(), BranchParams));
|
||||
else
|
||||
// Otherwise, create a region with the True counter and False counter.
|
||||
popRegions(pushRegion(TrueCnt, getStart(C), getEnd(C), FalseCnt,
|
||||
BranchParams));
|
||||
Expr::EvalResult Result;
|
||||
if (C->EvaluateAsInt(Result, CVM.getCodeGenModule().getContext())) {
|
||||
if (Result.Val.getInt().getBoolValue())
|
||||
FalseCnt = Counter::getZero();
|
||||
else
|
||||
TrueCnt = Counter::getZero();
|
||||
}
|
||||
popRegions(
|
||||
pushRegion(TrueCnt, getStart(C), getEnd(C), FalseCnt, BranchParams));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,12 +1149,12 @@ struct CounterCoverageMappingBuilder
|
||||
|
||||
/// Create a Branch Region around a SwitchCase for code coverage
|
||||
/// and add it to the function's SourceRegions.
|
||||
void createSwitchCaseRegion(const SwitchCase *SC, Counter TrueCnt,
|
||||
Counter FalseCnt) {
|
||||
void createSwitchCaseRegion(const SwitchCase *SC, Counter TrueCnt) {
|
||||
// Push region onto RegionStack but immediately pop it (which adds it to
|
||||
// the function's SourceRegions) because it doesn't apply to any other
|
||||
// source other than the SwitchCase.
|
||||
popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(), FalseCnt));
|
||||
popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(),
|
||||
Counter::getZero()));
|
||||
}
|
||||
|
||||
/// Check whether a region with bounds \c StartLoc and \c EndLoc
|
||||
@@ -1870,24 +1866,16 @@ struct CounterCoverageMappingBuilder
|
||||
const SwitchCase *Case = S->getSwitchCaseList();
|
||||
for (; Case; Case = Case->getNextSwitchCase()) {
|
||||
HasDefaultCase = HasDefaultCase || isa<DefaultStmt>(Case);
|
||||
CaseCountSum =
|
||||
addCounters(CaseCountSum, getRegionCounter(Case), /*Simplify=*/false);
|
||||
createSwitchCaseRegion(
|
||||
Case, getRegionCounter(Case),
|
||||
subtractCounters(ParentCount, getRegionCounter(Case)));
|
||||
auto CaseCount = getRegionCounter(Case);
|
||||
CaseCountSum = addCounters(CaseCountSum, CaseCount, /*Simplify=*/false);
|
||||
createSwitchCaseRegion(Case, CaseCount);
|
||||
}
|
||||
// Simplify is skipped while building the counters above: it can get really
|
||||
// slow on top of switches with thousands of cases. Instead, trigger
|
||||
// simplification by adding zero to the last counter.
|
||||
CaseCountSum = addCounters(CaseCountSum, Counter::getZero());
|
||||
|
||||
// If no explicit default case exists, create a branch region to represent
|
||||
// the hidden branch, which will be added later by the CodeGen. This region
|
||||
// will be associated with the switch statement's condition.
|
||||
if (!HasDefaultCase) {
|
||||
Counter DefaultTrue = subtractCounters(ParentCount, CaseCountSum);
|
||||
Counter DefaultFalse = subtractCounters(ParentCount, DefaultTrue);
|
||||
createBranchRegion(S->getCond(), DefaultTrue, DefaultFalse);
|
||||
Counter DefaultCount = subtractCounters(ParentCount, CaseCountSum);
|
||||
createBranchRegion(S->getCond(), Counter::getZero(), DefaultCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,94 +5,94 @@
|
||||
|
||||
// CHECK-LABEL: _Z6fand_0b:
|
||||
bool fand_0(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:20 = M:3, C:2
|
||||
return false && a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, 0
|
||||
return false && a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, (#0 - #1)
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:20 = #2, (#1 - #2)
|
||||
|
||||
// CHECK-LABEL: _Z6fand_1b:
|
||||
bool fand_1(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:19 = M:3, C:2
|
||||
return a && true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = #1, (#0 - #1)
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = 0, 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = #2, 0
|
||||
|
||||
// CHECK-LABEL: _Z6fand_2bb:
|
||||
bool fand_2(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:25 = M:4, C:3
|
||||
return false && a && b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, 0
|
||||
return false && a && b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, (#0 - #3)
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:20 = #4, (#3 - #4)
|
||||
// CHECK: Branch,File 0, [[@LINE-2]]:24 -> [[@LINE-2]]:25 = #2, (#1 - #2)
|
||||
|
||||
// CHECK-LABEL: _Z6fand_3bb:
|
||||
bool fand_3(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:24 = M:4, C:3
|
||||
return a && true && b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = #3, (#0 - #3)
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = 0, 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = #4, 0
|
||||
// CHECK: Branch,File 0, [[@LINE-2]]:23 -> [[@LINE-2]]:24 = #2, (#1 - #2)
|
||||
|
||||
// CHECK-LABEL: _Z6fand_4bb:
|
||||
bool fand_4(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:25 = M:4, C:3
|
||||
return a && b && false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = #3, (#0 - #3)
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:16 = #4, (#3 - #4)
|
||||
// CHECK: Branch,File 0, [[@LINE-2]]:20 -> [[@LINE-2]]:25 = 0, 0
|
||||
// CHECK: Branch,File 0, [[@LINE-2]]:20 -> [[@LINE-2]]:25 = 0, (#1 - #2)
|
||||
|
||||
// CHECK-LABEL: _Z6fand_5b:
|
||||
bool fand_5(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:23 = M:3, C:2
|
||||
return false && true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:23 = 0, 0
|
||||
return false && true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, (#0 - #1)
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:23 = #2, 0
|
||||
|
||||
// CHECK-LABEL: _Z6fand_6b:
|
||||
bool fand_6(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:19 = M:3, C:2
|
||||
return true && a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = 0, 0
|
||||
return true && a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = #1, 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:19 = #2, (#1 - #2)
|
||||
|
||||
// CHECK-LABEL: _Z6fand_7b:
|
||||
bool fand_7(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:20 = M:3, C:2
|
||||
return a && false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = #1, (#0 - #1)
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, (#1 - #2)
|
||||
|
||||
// CHECK-LABEL: _Z5for_0b:
|
||||
bool for_0(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:19 = M:3, C:2
|
||||
return true || a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = 0, 0
|
||||
return true || a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = (#0 - #1), 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:19 = (#1 - #2), #2
|
||||
|
||||
// CHECK-LABEL: _Z5for_1b:
|
||||
bool for_1(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:20 = M:3, C:2
|
||||
return a || false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = (#0 - #1), #1
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, #2
|
||||
|
||||
// CHECK-LABEL: _Z5for_2bb:
|
||||
bool for_2(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:24 = M:4, C:3
|
||||
return true || a || b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = 0, 0
|
||||
return true || a || b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = (#0 - #3), 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:19 = (#3 - #4), #4
|
||||
// CHECK: Branch,File 0, [[@LINE-2]]:23 -> [[@LINE-2]]:24 = (#1 - #2), #2
|
||||
|
||||
// CHECK-LABEL: _Z5for_3bb:
|
||||
bool for_3(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:25 = M:4, C:3
|
||||
return a || false || b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = (#0 - #3), #3
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, #4
|
||||
// CHECK: Branch,File 0, [[@LINE-2]]:24 -> [[@LINE-2]]:25 = (#1 - #2), #2
|
||||
|
||||
// CHECK-LABEL: _Z5for_4bb:
|
||||
bool for_4(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:24 = M:4, C:3
|
||||
return a || b || true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = (#0 - #3), #3
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:16 = (#3 - #4), #4
|
||||
// CHECK: Branch,File 0, [[@LINE-2]]:20 -> [[@LINE-2]]:24 = 0, 0
|
||||
// CHECK: Branch,File 0, [[@LINE-2]]:20 -> [[@LINE-2]]:24 = (#1 - #2), 0
|
||||
|
||||
// CHECK-LABEL: _Z5for_5b:
|
||||
bool for_5(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:23 = M:3, C:2
|
||||
return true || false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = 0, 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:23 = 0, 0
|
||||
return true || false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = (#0 - #1), 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:23 = 0, #2
|
||||
|
||||
// CHECK-LABEL: _Z5for_6b:
|
||||
bool for_6(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:20 = M:3, C:2
|
||||
return false || a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, 0
|
||||
return false || a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, #1
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:20 = (#1 - #2), #2
|
||||
|
||||
// CHECK-LABEL: _Z5for_7b:
|
||||
bool for_7(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:19 = M:3, C:2
|
||||
return a || true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = (#0 - #1), #1
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = 0, 0
|
||||
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = (#1 - #2), 0
|
||||
|
||||
// CHECK-LABEL: _Z5for_8b:
|
||||
bool for_8(bool a) { // MCDC: Decision,File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:20 = M:3, C:2
|
||||
// CHECK: Branch,File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:11 = 0, 0
|
||||
// CHECK: Branch,File 0, [[@LINE+1]]:15 -> [[@LINE+1]]:20 = 0, 0
|
||||
// CHECK: Branch,File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:11 = #2, 0
|
||||
// CHECK: Branch,File 0, [[@LINE+1]]:15 -> [[@LINE+1]]:20 = 0, (#2 - #3)
|
||||
if (true && false)
|
||||
return true;
|
||||
else
|
||||
|
||||
@@ -14,7 +14,7 @@ struct S {
|
||||
// CHECK-LABEL: _Z3foov:
|
||||
// CHECK-NEXT: [[@LINE+3]]:12 -> [[@LINE+8]]:2 = #0
|
||||
// CHECK-NEXT: [[@LINE+3]]:15 -> [[@LINE+3]]:19 = #0
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE+2]]:15 -> [[@LINE+2]]:19 = 0, 0
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE+2]]:15 -> [[@LINE+2]]:19 = #2, 0
|
||||
void foo() { // CHECK-NEXT: Gap,File 0, [[@LINE+1]]:21 -> [[@LINE+1]]:22 = #2
|
||||
if (int j = true ? nop() // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = #2
|
||||
: nop(); // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = (#0 - #2)
|
||||
@@ -168,7 +168,7 @@ int main() { // CHECK: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 =
|
||||
// GH-45481
|
||||
S s;
|
||||
s.the_prop = 0? 1 : 2; // CHECK-NEXT: File 0, [[@LINE]]:16 -> [[@LINE]]:17 = #0
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:16 -> [[@LINE-1]]:17 = 0, 0
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:16 -> [[@LINE-1]]:17 = 0, (#0 - #7)
|
||||
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:18 -> [[@LINE-2]]:19 = #7
|
||||
// CHECK-NEXT: File 0, [[@LINE-3]]:19 -> [[@LINE-3]]:20 = #7
|
||||
// CHECK-NEXT: File 0, [[@LINE-4]]:23 -> [[@LINE-4]]:24 = (#0 - #7)
|
||||
|
||||
@@ -4,29 +4,29 @@
|
||||
// CHECK: File 1, [[@LINE+7]]:12 -> [[@LINE+7]]:38 = #0
|
||||
// CHECK-NEXT: File 1, [[@LINE+6]]:15 -> [[@LINE+6]]:28 = (#0 + #2)
|
||||
// CHECK-NEXT: File 1, [[@LINE+5]]:21 -> [[@LINE+5]]:22 = (#0 + #2)
|
||||
// CHECK: Branch,File 1, [[@LINE+4]]:21 -> [[@LINE+4]]:22 = 0, 0
|
||||
// CHECK: Branch,File 1, [[@LINE+4]]:21 -> [[@LINE+4]]:22 = 0, ((#0 + #2) - #3)
|
||||
// CHECK-NEXT: File 1, [[@LINE+3]]:24 -> [[@LINE+3]]:26 = #3
|
||||
// CHECK-NEXT: File 1, [[@LINE+2]]:36 -> [[@LINE+2]]:37 = (#0 + #2)
|
||||
// CHECK-NEXT: Branch,File 1, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = 0, 0
|
||||
// CHECK-NEXT: Branch,File 1, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = 0, #0
|
||||
#define M1 do { if (0) {} } while (0)
|
||||
// CHECK-NEXT: File 2, [[@LINE+12]]:15 -> [[@LINE+12]]:41 = #0
|
||||
// CHECK-NEXT: File 2, [[@LINE+11]]:18 -> [[@LINE+11]]:31 = (#0 + #4)
|
||||
// CHECK-NEXT: File 2, [[@LINE+10]]:24 -> [[@LINE+10]]:25 = (#0 + #4)
|
||||
// CHECK: File 2, [[@LINE+9]]:27 -> [[@LINE+9]]:29 = #5
|
||||
// CHECK-NEXT: File 2, [[@LINE+8]]:39 -> [[@LINE+8]]:40 = (#0 + #4)
|
||||
// CHECK-NEXT: Branch,File 2, [[@LINE+7]]:39 -> [[@LINE+7]]:40 = 0, 0
|
||||
// CHECK-NEXT: Branch,File 2, [[@LINE+7]]:39 -> [[@LINE+7]]:40 = 0, #0
|
||||
// CHECK-NEXT: File 3, [[@LINE+6]]:15 -> [[@LINE+6]]:41 = #0
|
||||
// CHECK-NEXT: File 3, [[@LINE+5]]:18 -> [[@LINE+5]]:31 = (#0 + #6)
|
||||
// CHECK-NEXT: File 3, [[@LINE+4]]:24 -> [[@LINE+4]]:25 = (#0 + #6)
|
||||
// CHECK: File 3, [[@LINE+3]]:27 -> [[@LINE+3]]:29 = #7
|
||||
// CHECK-NEXT: File 3, [[@LINE+2]]:39 -> [[@LINE+2]]:40 = (#0 + #6)
|
||||
// CHECK-NEXT: Branch,File 3, [[@LINE+1]]:39 -> [[@LINE+1]]:40 = 0, 0
|
||||
// CHECK-NEXT: Branch,File 3, [[@LINE+1]]:39 -> [[@LINE+1]]:40 = 0, #0
|
||||
#define M2(x) do { if (x) {} } while (0)
|
||||
// CHECK-NEXT: File 4, [[@LINE+5]]:15 -> [[@LINE+5]]:38 = #0
|
||||
// CHECK-NEXT: File 4, [[@LINE+4]]:18 -> [[@LINE+4]]:28 = (#0 + #8)
|
||||
// CHECK-NEXT: Expansion,File 4, [[@LINE+3]]:20 -> [[@LINE+3]]:22 = (#0 + #8)
|
||||
// CHECK-NEXT: File 4, [[@LINE+2]]:36 -> [[@LINE+2]]:37 = (#0 + #8)
|
||||
// CHECK-NEXT: Branch,File 4, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = 0, 0
|
||||
// CHECK-NEXT: Branch,File 4, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = 0, #0
|
||||
#define M3(x) do { M2(x); } while (0)
|
||||
// CHECK-NEXT: File 5, [[@LINE+4]]:15 -> [[@LINE+4]]:27 = #0
|
||||
// CHECK-NEXT: File 5, [[@LINE+3]]:16 -> [[@LINE+3]]:19 = #0
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CHECK: builtin_macro0:
|
||||
int builtin_macro0(int a) {
|
||||
// CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:15 = M:3, C:2
|
||||
return (__LINE__ // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:11 = 0, 0 [1,2,0]
|
||||
return (__LINE__ // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:11 = #1, 0 [1,2,0]
|
||||
&& a); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:15 = #2, (#1 - #2) [2,0,0]
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ int builtin_macro0(int a) {
|
||||
int builtin_macro1(int a) {
|
||||
// CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:22 = M:3, C:2
|
||||
return (a // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = (#0 - #1), #1 [1,0,2]
|
||||
|| __LINE__); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:14 = 0, 0 [2,0,0]
|
||||
|| __LINE__); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:14 = (#1 - #2), 0 [2,0,0]
|
||||
}
|
||||
|
||||
#define PRE(x) pre_##x
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
int func0(int a) {
|
||||
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+3]]:21 = M:3, C:2
|
||||
// W_SYS: Expansion,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:16 = #0 (Expanded file = 1)
|
||||
// X_SYS: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:11 = 0, 0 [1,2,0]
|
||||
// X_SYS: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:11 = #1, 0 [1,2,0]
|
||||
return (CONST && a);
|
||||
// CHECK: Branch,File 0, [[@LINE-1]]:20 -> [[@LINE-1]]:21 = #2, (#1 - #2) [2,0,0]
|
||||
// W_SYS: Branch,File 1, [[@LINE-16]]:15 -> [[@LINE-16]]:17 = 0, 0 [1,2,0]
|
||||
// W_SYS: Branch,File 1, [[@LINE-16]]:15 -> [[@LINE-16]]:17 = #1, 0 [1,2,0]
|
||||
}
|
||||
|
||||
// CHECK: _Z5func1ii:
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
// CHECK: foo
|
||||
void foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+11]]:2 = #0
|
||||
switch(i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = ((#0 - #2) - #3), (#2 + #3)
|
||||
switch(i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = 0, ((#0 - #2) - #3)
|
||||
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+5]]:10 = 0
|
||||
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:11 = #2
|
||||
return; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, (#0 - #2)
|
||||
return; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, 0
|
||||
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:12 -> [[@LINE+1]]:3 = 0
|
||||
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #3
|
||||
break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, (#0 - #3)
|
||||
break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, 0
|
||||
|
||||
} // CHECK-NEXT: Gap,File 0, [[@LINE]]:4 -> [[@LINE+1]]:3 = #1
|
||||
int x = 0; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
|
||||
@@ -18,24 +18,24 @@ int nop() { return 0; }
|
||||
|
||||
// CHECK: bar
|
||||
void bar(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+21]]:2 = #0
|
||||
switch (i) // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = #0, 0
|
||||
switch (i) // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = 0, #0
|
||||
; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:6 = 0
|
||||
|
||||
switch (i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+17]]:2 = #1
|
||||
} // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = #1, 0
|
||||
} // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = 0, #1
|
||||
|
||||
switch (i) // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+14]]:2 = #2
|
||||
nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = #2, 0
|
||||
nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = 0, #2
|
||||
// CHECK-NEXT: File 0, [[@LINE-1]]:5 -> [[@LINE-1]]:10 = 0
|
||||
switch (i) // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+11]]:2 = #3
|
||||
case 1: // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = (#3 - #5), #5
|
||||
case 1: // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = 0, (#3 - #5)
|
||||
// CHECK-NEXT: File 0, [[@LINE-1]]:3 -> [[@LINE+1]]:10 = #5
|
||||
nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-2]]:3 -> [[@LINE-2]]:9 = #5, (#3 - #5)
|
||||
nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-2]]:3 -> [[@LINE-2]]:9 = #5, 0
|
||||
// CHECK-NEXT: File 0, [[@LINE+1]]:3 -> [[@LINE+7]]:2 = #4
|
||||
switch (i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = (#4 - #7), #7
|
||||
switch (i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = 0, (#4 - #7)
|
||||
nop(); // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+2]]:10 = 0
|
||||
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #7
|
||||
nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #7, (#4 - #7)
|
||||
nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #7, 0
|
||||
}
|
||||
nop(); // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #6
|
||||
}
|
||||
@@ -44,7 +44,7 @@ void bar(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+21]]:2 = #0
|
||||
void baz() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
|
||||
switch (int i = true ? nop() // CHECK: [[@LINE]]:26 -> [[@LINE]]:31 = #2
|
||||
: nop(); // CHECK-NEXT: [[@LINE]]:26 -> [[@LINE]]:31 = (#0 - #2)
|
||||
i) {} // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = #0, 0
|
||||
i) {} // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = 0, #0
|
||||
nop(); // CHECK-NEXT: [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
|
||||
}
|
||||
|
||||
@@ -53,35 +53,35 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+39]]:2 = #0
|
||||
int i = 0;
|
||||
switch(i) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+8]]:10 = 0
|
||||
case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #2
|
||||
i = 1; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, (#0 - #2)
|
||||
i = 1; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, 0
|
||||
break; // CHECK-NEXT: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:3 = 0
|
||||
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #3
|
||||
i = 2; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, (#0 - #3)
|
||||
i = 2; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, 0
|
||||
break; // CHECK-NEXT: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:3 = 0
|
||||
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #4
|
||||
break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #4, (#0 - #4)
|
||||
break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #4, 0
|
||||
} // CHECK-NEXT: Gap,File 0, [[@LINE]]:4 -> [[@LINE+1]]:3 = #1
|
||||
switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+27]]:2 = #1
|
||||
case 0: // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+7]]:10 = 0
|
||||
i = 1; // CHECK-NEXT: File 0, [[@LINE-1]]:3 -> [[@LINE+1]]:10 = #6
|
||||
break; // CHECK-NEXT: Branch,File 0, [[@LINE-2]]:3 -> [[@LINE-2]]:9 = #6, (#1 - #6)
|
||||
break; // CHECK-NEXT: Branch,File 0, [[@LINE-2]]:3 -> [[@LINE-2]]:9 = #6, 0
|
||||
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = 0
|
||||
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #7
|
||||
i = 2; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #7, (#1 - #7)
|
||||
i = 2; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #7, 0
|
||||
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = (#7 + #8)
|
||||
break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #8, (#1 - #8)
|
||||
break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #8, 0
|
||||
} // CHECK-NEXT: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:3 = #5
|
||||
// CHECK-NEXT: File 0, [[@LINE+1]]:3 -> [[@LINE+17]]:2 = #5
|
||||
switch(i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = ((((#5 - #10) - #11) - #12) - #13), (((#10 + #11) + #12) + #13)
|
||||
switch(i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = 0, ((((#5 - #10) - #11) - #12) - #13)
|
||||
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+8]]:11 = 0
|
||||
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+7]]:11 = #10
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #10, (#5 - #10)
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #10, 0
|
||||
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:11 = (#10 + #11)
|
||||
i = 11; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #11, (#5 - #11)
|
||||
i = 11; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #11, 0
|
||||
case 3: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:11 = ((#10 + #11) + #12)
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #12, (#5 - #12)
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #12, 0
|
||||
case 4: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:11 = (((#10 + #11) + #12) + #13)
|
||||
i = 99; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #13, (#5 - #13)
|
||||
i = 99; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #13, 0
|
||||
}
|
||||
|
||||
foo(1); // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:11 = #9
|
||||
@@ -95,10 +95,10 @@ int pr44011(int i) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> {{.*}}:2 = #0
|
||||
switch (i) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:14 -> [[@LINE+6]]:13 = 0
|
||||
|
||||
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13 = #2
|
||||
return 0; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, (#0 - #2)
|
||||
return 0; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, 0
|
||||
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:3 = 0
|
||||
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13 = #3
|
||||
return 1; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #3, (#0 - #3)
|
||||
return 1; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #3, 0
|
||||
}
|
||||
} // A region for counter #1 is missing due to the missing return.
|
||||
|
||||
@@ -106,17 +106,17 @@ int pr44011(int i) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> {{.*}}:2 = #0
|
||||
// FIXME: End location for "case 1" shouldn't point at the end of the switch.
|
||||
// CHECK: fallthrough
|
||||
int fallthrough(int i) { // CHECK-NEXT: File 0, [[@LINE]]:24 -> [[@LINE+14]]:2 = #0
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:11 = ((((#0 - #2) - #3) - #4) - #5), (((#2 + #3) + #4) + #5)
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:11 = 0, ((((#0 - #2) - #3) - #4) - #5)
|
||||
switch(i) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+10]]:10 = 0
|
||||
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+9]]:10 = #2
|
||||
i = 23; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, (#0 - #2)
|
||||
i = 23; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, 0
|
||||
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = (#2 + #3)
|
||||
i = 11; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, (#0 - #3)
|
||||
i = 11; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, 0
|
||||
break; // CHECK-NEXT: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:3 = 0
|
||||
case 3: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:10 = #4
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, (#0 - #4)
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, 0
|
||||
case 4: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = (#4 + #5)
|
||||
i = 99; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #5, (#0 - #5)
|
||||
i = 99; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #5, 0
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -126,12 +126,12 @@ void abort(void) __attribute((noreturn));
|
||||
int noret(int x) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+11]]:2
|
||||
switch (x) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:14 -> [[@LINE+8]]:14 = 0
|
||||
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:12
|
||||
abort(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #2, (#0 - #2)
|
||||
abort(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #2, 0
|
||||
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:3 = 0
|
||||
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13
|
||||
return 5; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, (#0 - #3)
|
||||
return 5; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, 0
|
||||
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:3 = 0
|
||||
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:14
|
||||
return 10; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, (#0 - #4)
|
||||
return 10; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
int foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> {{[0-9]+}}:2 = #0
|
||||
switch (i) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:14 -> {{[0-9]+}}:11 = 0
|
||||
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> {{[0-9]+}}:11 = #2
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #2, (#0 - #2)
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #2, 0
|
||||
if (i == 1) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = #2
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:15 = #3, (#2 - #3)
|
||||
return 0; // CHECK: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = #3
|
||||
@@ -15,7 +15,7 @@ int foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> {{[0-9]+}}:2 = #0
|
||||
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> {{[0-9]+}}:11 = (#2 - #3)
|
||||
FOO(1);
|
||||
case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:13 = ((#2 + #4) - #3)
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, (#0 - #4)
|
||||
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, 0
|
||||
return 2; // CHECK-NEXT: Gap,File 0, [[@LINE]]:14 -> [[@LINE+4]]:3 = 0
|
||||
|
||||
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:6 = 0
|
||||
|
||||
@@ -358,20 +358,21 @@ struct CounterMappingRegion {
|
||||
struct CountedRegion : public CounterMappingRegion {
|
||||
uint64_t ExecutionCount;
|
||||
uint64_t FalseExecutionCount;
|
||||
bool Folded;
|
||||
bool TrueFolded;
|
||||
bool FalseFolded;
|
||||
bool HasSingleByteCoverage;
|
||||
|
||||
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
|
||||
bool HasSingleByteCoverage)
|
||||
: CounterMappingRegion(R), ExecutionCount(ExecutionCount),
|
||||
FalseExecutionCount(0), Folded(false),
|
||||
FalseExecutionCount(0), TrueFolded(false), FalseFolded(true),
|
||||
HasSingleByteCoverage(HasSingleByteCoverage) {}
|
||||
|
||||
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
|
||||
uint64_t FalseExecutionCount, bool HasSingleByteCoverage)
|
||||
: CounterMappingRegion(R), ExecutionCount(ExecutionCount),
|
||||
FalseExecutionCount(FalseExecutionCount), Folded(false),
|
||||
HasSingleByteCoverage(HasSingleByteCoverage) {}
|
||||
FalseExecutionCount(FalseExecutionCount), TrueFolded(false),
|
||||
FalseFolded(false), HasSingleByteCoverage(HasSingleByteCoverage) {}
|
||||
};
|
||||
|
||||
/// MCDC Record grouping all information together.
|
||||
@@ -719,10 +720,10 @@ struct FunctionRecord {
|
||||
Region.Kind == CounterMappingRegion::MCDCBranchRegion) {
|
||||
CountedBranchRegions.emplace_back(Region, Count, FalseCount,
|
||||
HasSingleByteCoverage);
|
||||
// If both counters are hard-coded to zero, then this region represents a
|
||||
// If either counter is hard-coded to zero, then this region represents a
|
||||
// constant-folded branch.
|
||||
if (Region.Count.isZero() && Region.FalseCount.isZero())
|
||||
CountedBranchRegions.back().Folded = true;
|
||||
CountedBranchRegions.back().TrueFolded = Region.Count.isZero();
|
||||
CountedBranchRegions.back().FalseFolded = Region.FalseCount.isZero();
|
||||
return;
|
||||
}
|
||||
if (CountedRegions.empty())
|
||||
|
||||
@@ -503,7 +503,7 @@ public:
|
||||
const auto &BranchParams = B->getBranchParams();
|
||||
PosToID[I] = BranchParams.ID;
|
||||
CondLoc[I] = B->startLoc();
|
||||
Folded[I++] = (B->Count.isZero() && B->FalseCount.isZero());
|
||||
Folded[I++] = (B->Count.isZero() || B->FalseCount.isZero());
|
||||
}
|
||||
|
||||
// Using Profile Bitmap from runtime, mark the executed test vectors.
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
// CHECK: Branch (103:9): [True: 9, False: 1]
|
||||
|
||||
// CHECK: switches()
|
||||
// CHECK: Branch (113:3): [True: 1, False: 0]
|
||||
// CHECK: Branch (113:3): [True: 1, Folded]
|
||||
// CHECK: Branch (117:63): [True: 15, False: 0]
|
||||
// CHECK: Branch (119:5): [True: 1, False: 14]
|
||||
// CHECK: Branch (120:11): [True: 0, False: 1]
|
||||
@@ -57,7 +57,7 @@
|
||||
// CHECK: Branch (126:11): [True: 3, False: 0]
|
||||
// CHECK: Branch (128:5): [True: 4, False: 11]
|
||||
// CHECK: Branch (129:11): [True: 4, False: 0]
|
||||
// CHECK: Branch (131:7): [True: 4, False: 0]
|
||||
// CHECK: Branch (131:7): [True: 4, Folded]
|
||||
// CHECK: Branch (132:13): [True: 4, False: 0]
|
||||
// CHECK: Branch (136:5): [True: 5, False: 10]
|
||||
// CHECK: Branch (137:11): [True: 1, False: 4]
|
||||
@@ -114,13 +114,13 @@
|
||||
|
||||
|
||||
|
||||
// REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover
|
||||
// REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover
|
||||
// REPORT-NEXT: ---
|
||||
// REPORT-NEXT: simple_loops 8 0 100.00% 9 0 100.00% 6 0 100.00%
|
||||
// REPORT-NEXT: conditionals 24 0 100.00% 15 0 100.00% 16 2 87.50%
|
||||
// REPORT-NEXT: early_exits 20 4 80.00% 25 2 92.00% 16 6 62.50%
|
||||
// REPORT-NEXT: jumps 39 12 69.23% 48 2 95.83% 26 9 65.38%
|
||||
// REPORT-NEXT: switches 28 5 82.14% 38 4 89.47% 30 9 70.00%
|
||||
// REPORT-NEXT: switches 28 5 82.14% 38 4 89.47% 28 7 75.00%
|
||||
// REPORT-NEXT: big_switch 25 1 96.00% 32 0 100.00% 30 6 80.00%
|
||||
// REPORT-NEXT: boolean_operators 16 0 100.00% 13 0 100.00% 22 2 90.91%
|
||||
// REPORT-NEXT: boolop_loops 19 0 100.00% 14 0 100.00% 16 2 87.50%
|
||||
@@ -129,12 +129,12 @@
|
||||
// REPORT-NEXT: main 1 0 100.00% 16 0 100.00% 0 0 0.00%
|
||||
// REPORT-NEXT: c-general.c:static_func 4 0 100.00% 4 0 100.00% 2 0 100.00%
|
||||
// REPORT-NEXT: ---
|
||||
// REPORT-NEXT: TOTAL 197 24 87.82% 234 8 96.58% 174 38 78.16%
|
||||
// REPORT-NEXT: TOTAL 197 24 87.82% 234 8 96.58% 172 36 79.07%
|
||||
|
||||
// Test file-level report.
|
||||
// RUN: llvm-profdata merge %S/Inputs/branch-c-general.proftext -o %t.profdata
|
||||
// RUN: llvm-cov report %S/Inputs/branch-c-general.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-c-general.c | FileCheck %s -check-prefix=FILEREPORT
|
||||
// FILEREPORT: TOTAL{{.*}}174 38 78.16%
|
||||
// FILEREPORT: TOTAL{{.*}}172 36 79.07%
|
||||
|
||||
// Test color True/False output.
|
||||
// RUN: llvm-cov show --use-color --show-branches=count %S/Inputs/branch-c-general.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-c-general.c | FileCheck %s -check-prefix=USECOLOR
|
||||
@@ -161,6 +161,6 @@
|
||||
// HTML-INDEX: <td class='column-entry-yellow'>
|
||||
// HTML-INDEX: 87.82% (173/197)
|
||||
// HTML-INDEX: <td class='column-entry-red'>
|
||||
// HTML-INDEX: 78.16% (136/174)
|
||||
// HTML-INDEX: 79.07% (136/172)
|
||||
// HTML-INDEX: <tr class='light-row-bold'>
|
||||
// HTML-INDEX: Totals
|
||||
|
||||
@@ -125,7 +125,7 @@ json::Array renderRegions(ArrayRef<coverage::CountedRegion> Regions) {
|
||||
json::Array renderBranchRegions(ArrayRef<coverage::CountedRegion> Regions) {
|
||||
json::Array RegionArray;
|
||||
for (const auto &Region : Regions)
|
||||
if (!Region.Folded)
|
||||
if (!Region.TrueFolded || !Region.FalseFolded)
|
||||
RegionArray.push_back(renderBranch(Region));
|
||||
return RegionArray;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ void renderBranchExecutionCounts(raw_ostream &OS,
|
||||
unsigned BranchIndex = 0;
|
||||
|
||||
while (NextBranch != EndBranch && CurrentLine == NextBranch->LineStart) {
|
||||
if (!NextBranch->Folded) {
|
||||
if (!NextBranch->TrueFolded || !NextBranch->FalseFolded) {
|
||||
unsigned BC1 = NextBranch->ExecutionCount;
|
||||
unsigned BC2 = NextBranch->FalseExecutionCount;
|
||||
bool BranchNotExecuted = (BC1 == 0 && BC2 == 0);
|
||||
|
||||
@@ -19,18 +19,18 @@ using namespace coverage;
|
||||
static void sumBranches(size_t &NumBranches, size_t &CoveredBranches,
|
||||
const ArrayRef<CountedRegion> &Branches) {
|
||||
for (const auto &BR : Branches) {
|
||||
// Skip folded branches.
|
||||
if (BR.Folded)
|
||||
continue;
|
||||
|
||||
// "True" Condition Branches.
|
||||
++NumBranches;
|
||||
if (BR.ExecutionCount > 0)
|
||||
++CoveredBranches;
|
||||
// "False" Condition Branches.
|
||||
++NumBranches;
|
||||
if (BR.FalseExecutionCount > 0)
|
||||
++CoveredBranches;
|
||||
if (!BR.TrueFolded) {
|
||||
// "True" Condition Branches.
|
||||
++NumBranches;
|
||||
if (BR.ExecutionCount > 0)
|
||||
++CoveredBranches;
|
||||
}
|
||||
if (!BR.FalseFolded) {
|
||||
// "False" Condition Branches.
|
||||
++NumBranches;
|
||||
if (BR.FalseExecutionCount > 0)
|
||||
++CoveredBranches;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1128,36 +1128,45 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV,
|
||||
"line-number") +
|
||||
"): [";
|
||||
|
||||
if (R.Folded) {
|
||||
if (R.TrueFolded && R.FalseFolded) {
|
||||
OS << "Folded - Ignored]\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Display TrueCount or TruePercent.
|
||||
std::string TrueColor = R.ExecutionCount ? "None" : "red branch";
|
||||
std::string TrueColor =
|
||||
(R.TrueFolded || R.ExecutionCount ? "None" : "red branch");
|
||||
std::string TrueCovClass =
|
||||
(R.ExecutionCount > 0) ? "covered-line" : "uncovered-line";
|
||||
(R.TrueFolded || R.ExecutionCount > 0 ? "covered-line"
|
||||
: "uncovered-line");
|
||||
|
||||
OS << tag("span", "True", TrueColor);
|
||||
OS << ": ";
|
||||
if (getOptions().ShowBranchCounts)
|
||||
OS << tag("span", formatCount(R.ExecutionCount), TrueCovClass) << ", ";
|
||||
else
|
||||
OS << format("%0.2f", TruePercent) << "%, ";
|
||||
if (R.TrueFolded)
|
||||
OS << "Folded, ";
|
||||
else {
|
||||
OS << tag("span", "True", TrueColor) << ": ";
|
||||
if (getOptions().ShowBranchCounts)
|
||||
OS << tag("span", formatCount(R.ExecutionCount), TrueCovClass) << ", ";
|
||||
else
|
||||
OS << format("%0.2f", TruePercent) << "%, ";
|
||||
}
|
||||
|
||||
// Display FalseCount or FalsePercent.
|
||||
std::string FalseColor = R.FalseExecutionCount ? "None" : "red branch";
|
||||
std::string FalseColor =
|
||||
(R.FalseFolded || R.FalseExecutionCount ? "None" : "red branch");
|
||||
std::string FalseCovClass =
|
||||
(R.FalseExecutionCount > 0) ? "covered-line" : "uncovered-line";
|
||||
(R.FalseFolded || R.FalseExecutionCount > 0 ? "covered-line"
|
||||
: "uncovered-line");
|
||||
|
||||
OS << tag("span", "False", FalseColor);
|
||||
OS << ": ";
|
||||
if (getOptions().ShowBranchCounts)
|
||||
OS << tag("span", formatCount(R.FalseExecutionCount), FalseCovClass);
|
||||
else
|
||||
OS << format("%0.2f", FalsePercent) << "%";
|
||||
|
||||
OS << "]\n";
|
||||
if (R.FalseFolded)
|
||||
OS << "Folded]\n";
|
||||
else {
|
||||
OS << tag("span", "False", FalseColor) << ": ";
|
||||
if (getOptions().ShowBranchCounts)
|
||||
OS << tag("span", formatCount(R.FalseExecutionCount), FalseCovClass)
|
||||
<< "]\n";
|
||||
else
|
||||
OS << format("%0.2f", FalsePercent) << "%]\n";
|
||||
}
|
||||
}
|
||||
OS << EndPre;
|
||||
OS << EndExpansionDiv;
|
||||
|
||||
@@ -309,31 +309,38 @@ void SourceCoverageViewText::renderBranchView(raw_ostream &OS, BranchView &BRV,
|
||||
renderLinePrefix(OS, ViewDepth);
|
||||
OS << " Branch (" << R.LineStart << ":" << R.ColumnStart << "): [";
|
||||
|
||||
if (R.Folded) {
|
||||
if (R.TrueFolded && R.FalseFolded) {
|
||||
OS << "Folded - Ignored]\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
colored_ostream(OS, raw_ostream::RED,
|
||||
getOptions().Colors && !R.ExecutionCount,
|
||||
/*Bold=*/false, /*BG=*/true)
|
||||
<< "True";
|
||||
if (R.TrueFolded)
|
||||
OS << "Folded, ";
|
||||
else {
|
||||
colored_ostream(OS, raw_ostream::RED,
|
||||
getOptions().Colors && !R.ExecutionCount,
|
||||
/*Bold=*/false, /*BG=*/true)
|
||||
<< "True";
|
||||
|
||||
if (getOptions().ShowBranchCounts)
|
||||
OS << ": " << formatCount(R.ExecutionCount) << ", ";
|
||||
else
|
||||
OS << ": " << format("%0.2f", TruePercent) << "%, ";
|
||||
if (getOptions().ShowBranchCounts)
|
||||
OS << ": " << formatCount(R.ExecutionCount) << ", ";
|
||||
else
|
||||
OS << ": " << format("%0.2f", TruePercent) << "%, ";
|
||||
}
|
||||
|
||||
colored_ostream(OS, raw_ostream::RED,
|
||||
getOptions().Colors && !R.FalseExecutionCount,
|
||||
/*Bold=*/false, /*BG=*/true)
|
||||
<< "False";
|
||||
if (R.FalseFolded)
|
||||
OS << "Folded]\n";
|
||||
else {
|
||||
colored_ostream(OS, raw_ostream::RED,
|
||||
getOptions().Colors && !R.FalseExecutionCount,
|
||||
/*Bold=*/false, /*BG=*/true)
|
||||
<< "False";
|
||||
|
||||
if (getOptions().ShowBranchCounts)
|
||||
OS << ": " << formatCount(R.FalseExecutionCount);
|
||||
else
|
||||
OS << ": " << format("%0.2f", FalsePercent) << "%";
|
||||
OS << "]\n";
|
||||
if (getOptions().ShowBranchCounts)
|
||||
OS << ": " << formatCount(R.FalseExecutionCount) << "]\n";
|
||||
else
|
||||
OS << ": " << format("%0.2f", FalsePercent) << "%]\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user