@@ -291,6 +291,45 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
291291 }
292292};
293293
294+ TEST (CoverageMappingTest, expression_subst) {
295+ CounterExpressionBuilder Builder;
296+ CounterExpressionBuilder::SubstMap MapToExpand;
297+
298+ auto C = [](unsigned ID) { return Counter::getCounter (ID); };
299+ auto A = [&](Counter LHS, Counter RHS) { return Builder.add (LHS, RHS); };
300+ // returns {E, N} in clangCodeGen
301+ auto getBranchCounterPair = [&](Counter E, Counter P, Counter N) {
302+ auto Skipped = Builder.subtract (P, E);
303+ MapToExpand[N] = Builder.subst (Skipped, MapToExpand);
304+ };
305+
306+ auto E18 = C (5 );
307+ auto P18 = C (2 );
308+ auto S18 = C (18 );
309+ // #18 => (#2 - #5)
310+ getBranchCounterPair (E18 , P18, S18);
311+
312+ auto E22 = S18;
313+ auto P22 = C (0 );
314+ auto S22 = C (22 );
315+ // #22 => #0 - (#2 - #5)
316+ getBranchCounterPair (E22 , P22, S22);
317+
318+ auto E28 = A (A (C (9 ), C (11 )), C (14 ));
319+ auto P28 = S22;
320+ auto S28 = C (28 );
321+ // #28 => (((((#0 + #5) - #2) - #9) - #11) - #14)
322+ getBranchCounterPair (E28 , P28, S28);
323+
324+ auto LHS = A (E28 , A (S28, S18));
325+ auto RHS = C (0 );
326+
327+ // W/o subst, LHS cannot be reduced.
328+ ASSERT_FALSE (Builder.subtract (LHS, RHS).isZero ());
329+ // W/ subst, C(18) and C(28) in LHS will be reduced.
330+ ASSERT_TRUE (Builder.subst (Builder.subtract (LHS, RHS), MapToExpand).isZero ());
331+ }
332+
294333TEST_P (CoverageMappingTest, basic_write_read) {
295334 startFunction (" func" , 0x1234 );
296335 addCMR (Counter::getCounter (0 ), " foo" , 1 , 1 , 1 , 1 );
0 commit comments