@@ -341,31 +341,65 @@ class CounterExpr {
341
341
// / Returns true if this is a Zero node.
342
342
bool isZero () const { return K == Kind::Zero; }
343
343
344
+ // / Returns true if the counter is semantically a Zero node. This considers
345
+ // / the simplified version of the counter that has eliminated redundant
346
+ // / operations.
347
+ bool isSemanticallyZero () const {
348
+ // Run the counter through the counter builder to simplify it, using a dummy
349
+ // mapping of unique counter indices for each node reference. The value of
350
+ // the indices doesn't matter, but we need to ensure that e.g subtraction
351
+ // of a node from itself cancels out.
352
+ llvm::coverage::CounterExpressionBuilder Builder;
353
+ llvm::DenseMap<ASTNode, unsigned > DummyIndices;
354
+ unsigned LastIdx = 0 ;
355
+ auto Counter = expand (Builder, [&](auto Node) {
356
+ if (!DummyIndices.count (Node)) {
357
+ DummyIndices[Node] = LastIdx;
358
+ LastIdx += 1 ;
359
+ }
360
+ return DummyIndices[Node];
361
+ });
362
+ return Counter.isZero ();
363
+ }
364
+
344
365
// / Expand this node into an llvm::coverage::Counter.
345
366
// /
346
367
// / Updates \c Builder with any expressions that are needed to represent this
347
368
// / counter.
348
369
llvm::coverage::Counter
349
370
expand (llvm::coverage::CounterExpressionBuilder &Builder,
350
- llvm::DenseMap<ASTNode, unsigned > &Counters ) const {
371
+ llvm::function_ref< unsigned (ASTNode)> GetCounterIdx ) const {
351
372
switch (K) {
352
373
case Kind::Zero:
353
374
return llvm::coverage::Counter::getZero ();
354
375
case Kind::Node:
355
- return llvm::coverage::Counter::getCounter (Counters[ Node] );
376
+ return llvm::coverage::Counter::getCounter (GetCounterIdx ( Node) );
356
377
case Kind::Add:
357
- return Builder.add (LHS->expand (Builder, Counters ),
358
- RHS->expand (Builder, Counters ));
378
+ return Builder.add (LHS->expand (Builder, GetCounterIdx ),
379
+ RHS->expand (Builder, GetCounterIdx ));
359
380
case Kind::Sub:
360
- return Builder.subtract (LHS->expand (Builder, Counters ),
361
- RHS->expand (Builder, Counters ));
381
+ return Builder.subtract (LHS->expand (Builder, GetCounterIdx ),
382
+ RHS->expand (Builder, GetCounterIdx ));
362
383
case Kind::Ref:
363
- return LHS->expand (Builder, Counters );
384
+ return LHS->expand (Builder, GetCounterIdx );
364
385
}
365
386
366
387
llvm_unreachable (" Unhandled Kind in switch." );
367
388
}
368
389
390
+ // / Expand this node into an llvm::coverage::Counter.
391
+ // /
392
+ // / Updates \c Builder with any expressions that are needed to represent this
393
+ // / counter.
394
+ llvm::coverage::Counter
395
+ expand (llvm::coverage::CounterExpressionBuilder &Builder,
396
+ const llvm::DenseMap<ASTNode, unsigned > &Counters) const {
397
+ return expand (Builder, [&](auto Node) {
398
+ // FIXME: We ought to assert that the node is present.
399
+ return Counters.lookup (Node);
400
+ });
401
+ }
402
+
369
403
void print (raw_ostream &OS) const {
370
404
switch (K) {
371
405
case Kind::Zero:
@@ -769,7 +803,17 @@ struct CoverageMapping : public ASTWalker {
769
803
if (ControlFlowAdjust)
770
804
Count = &createCounter (CounterExpr::Sub (*Count, *ControlFlowAdjust));
771
805
772
- RegionStack.emplace_back (ASTNode (), *Count, getEndLoc (Scope), None);
806
+ if (Count->isSemanticallyZero ()) {
807
+ // If the counter is semantically zero, form an 'incomplete' region with
808
+ // no starting location. This prevents forming unreachable regions unless
809
+ // there is a following statement or expression to extend the region.
810
+ RegionStack.emplace_back (ASTNode (), *Count, None, None);
811
+ } else {
812
+ // Otherwise, we have a non-zero counter, so form a new region starting
813
+ // at the end of the previous scope. This ensures the user covers both
814
+ // branches of a condition.
815
+ RegionStack.emplace_back (ASTNode (), *Count, getEndLoc (Scope), None);
816
+ }
773
817
}
774
818
775
819
// / Push a region covering \c Node onto the stack.
0 commit comments