MaggieYi created this revision. MaggieYi added reviewers: vsk, zequanwu. MaggieYi added a project: clang. Herald added a project: All. MaggieYi requested review of this revision. Herald added a subscriber: cfe-commits.
In the current coverage mapping implementation, we terminate the current region and start a zero region when we hit a nonreturn function. However, for logical OR, the second operand is not executed if the first operand evaluates to true. If the nonreturn function is called in the right side of logical OR and the left side of logical OR is TRUE, we should not start a zero `GapRegionCounter`. This will also apply to `VisitAbstractConditionalOperator`. The following issues are fixed by this patch: 1. https://github.com/llvm/llvm-project/issues/59030 2. https://github.com/llvm/llvm-project/issues/57388 3. https://github.com/llvm/llvm-project/issues/57481 4. https://github.com/llvm/llvm-project/issues/60701 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D144371 Files: clang/lib/CodeGen/CoverageMappingGen.cpp clang/test/CoverageMapping/terminate-statements.cpp
Index: clang/test/CoverageMapping/terminate-statements.cpp =================================================================== --- clang/test/CoverageMapping/terminate-statements.cpp +++ clang/test/CoverageMapping/terminate-statements.cpp @@ -320,6 +320,30 @@ included_func(); } +// CHECK-LABEL: _Z7ornoretv: +void abort() __attribute__((noreturn)); + +int ornoret(void) { + ( true || (abort(), 0) ); // CHECK: Gap,File 0, [[@LINE]]:28 -> [[@LINE+1]]:3 = #0 + ( false || (abort(), 0) ); // CHECK: Gap,File 0, [[@LINE]]:29 -> [[@LINE+1]]:3 = 0 + return 0; +} + +// CHECK-LABEL: _Z17abstractcondnoretv: +int abstractcondnoret(void) { + ( true ? void (0) : abort() ); // CHECK: Gap,File 0, [[@LINE]]:33 -> [[@LINE+1]]:3 = #1 + ( false ? void (0) : abort() ); // CHECK: Gap,File 0, [[@LINE]]:34 -> [[@LINE+1]]:3 = #2 + return 0; +} + +// CHECK-LABEL: _Z13elsecondnoretv: +int elsecondnoret(void) { + if (true) {} else { + true ? void (0) : abort(); + } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+1]]:3 = (#1 + #2) + return 0; +} + int main() { foo(0); foo(1); @@ -339,5 +363,8 @@ while_loop(); gotos(); include(); + ornoret(); + abstractcondnoret(); + elsecondnoret(); return 0; } Index: clang/lib/CodeGen/CoverageMappingGen.cpp =================================================================== --- clang/lib/CodeGen/CoverageMappingGen.cpp +++ clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1466,6 +1466,7 @@ Counter TrueCount = getRegionCounter(E); propagateCounts(ParentCount, E->getCond()); + Counter OutCount; if (!isa<BinaryConditionalOperator>(E)) { // The 'then' count applies to the area immediately after the condition. @@ -1475,12 +1476,18 @@ fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), TrueCount); extendRegion(E->getTrueExpr()); - propagateCounts(TrueCount, E->getTrueExpr()); + OutCount = propagateCounts(TrueCount, E->getTrueExpr()); } extendRegion(E->getFalseExpr()); - propagateCounts(subtractCounters(ParentCount, TrueCount), - E->getFalseExpr()); + OutCount = addCounters( + OutCount, propagateCounts(subtractCounters(ParentCount, TrueCount), + E->getFalseExpr())); + + if (OutCount != ParentCount) { + pushRegion(OutCount); + GapRegionCounter = OutCount; + } // Create Branch Region around condition. createBranchRegion(E->getCond(), TrueCount, @@ -1514,9 +1521,19 @@ subtractCounters(RHSExecCnt, RHSTrueCnt)); } + // Determine whether the right side of OR operation need to be visited. + bool shouldVisitRHS(const Expr *LHS) { + bool LHSIsTrue = false; + bool LHSIsConst = false; + if (!LHS->isValueDependent()) + LHSIsConst = LHS->EvaluateAsBooleanCondition( + LHSIsTrue, CVM.getCodeGenModule().getContext()); + return !LHSIsConst || (LHSIsConst && !LHSIsTrue); + } + void VisitBinLOr(const BinaryOperator *E) { extendRegion(E->getLHS()); - propagateCounts(getRegion().getCounter(), E->getLHS()); + Counter OutCount = propagateCounts(getRegion().getCounter(), E->getLHS()); handleFileExit(getEnd(E->getLHS())); // Counter tracks the right hand side of a logical or operator. @@ -1529,6 +1546,10 @@ // Extract the RHS's "False" Instance Counter. Counter RHSFalseCnt = getRegionCounter(E->getRHS()); + if (!shouldVisitRHS(E->getLHS())) { + GapRegionCounter = OutCount; + } + // Extract the Parent Region Counter. Counter ParentCnt = getRegion().getCounter();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits