<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/139122>139122</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [coverage] incorrect coverage when a macro contains break or continue statements
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            coverage
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          justincady
      </td>
    </tr>
</table>

<pre>
    Code coverage reporting is incorrect for macros that contain statements such as `break` and `continue`:

```
// coverage.c
#include <stdio.h>

#define MY_MACRO()                                                             \
 do { \
    int n = 0; \
    if (n == 87) { \
      break; \
    } \
  } while (0)

static void func(void) {
 MY_MACRO();
  printf("Hello, World!\n");
}

int main(void) {
 MY_MACRO();
  func();
  return 0;
}
```

```
# build.sh
/usr/bin/clang++ --version | /bin/grep "clang version"
/usr/bin/clang++ -fprofile-instr-generate -fcoverage-mapping coverage.c -o coverage
./coverage
/usr/bin/llvm-profdata merge -sparse default.profraw -o default.profdata
/usr/bin/llvm-cov show ./coverage -instr-profile=default.profdata
```

The coverage report incorrectly marks lines following `MY_MACRO()` as uncovered:

```
$ ./build.sh
clang version 21.0.0
Hello, World!
    1|       |#include <stdio.h>
    2| |
    3|       |#define MY_MACRO() \
    4|      2|  do { \
    5|      2|    int n = 0; \
    6|      2| if (n == 87) { \
    7|      0|      break; \
    8|      0|    } \
    9|      2|  } while (0)
   10| |
   11|      1|static void func(void) {
   12|      1| MY_MACRO();
   13|      0|  printf("Hello, World!\n"); // INCORRECT
 14|      1|}
   15|       |
   16|      1|int main(void) {
   17|      1| MY_MACRO();
   18|      0|  func();                    // INCORRECT
   19| 1|  return 0;
   20|      1|}
```

These region terminating statements trigger the incorrect coverage:

- `break`
- `continue`

But these region terminating statements do _not_ appear to trigger the incorrect coverage:

- `return`
- `goto`
- call to `__noreturn__` function

Also, removing the `break` line from the example eliminates the incorrectly reported code coverage.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJykVs2O4jgQfhpzKRE5DiTkwIGGQbuH2ZFaI632hExSSTzj2Mh26O23X9kJkNB0T68GcUjZ9f_zlbm1olaIa7J8IsvdjHeu0Wb9o7NOqIKXr7OjLl_XW10iFPqMhtcIBk_aOKFqEBaEKrQxWDiotIGWF0ZbcA13UGjluFBgHXfYonIWbFc0wC2QlB4N8p8kpcBV6WnPLVSHJKUk2RAa_ikd_nRD2J6w_dWJqAhniVCF7EoEkmytK4WOGpJ8GaRZUmIlFMLXfw5fN9vnb4StCMvhd35kuSV0A6UGkj1dKAAQyoECkuyAkmRyUQFhq3Dlb1eZ92AqC9AnYyJHst2V8t8vjZDoVVHC8j5An1hRwFmLEqpOFYSt_PdgwEtOAydJOISTEcpV4Yz9gVJqwrbwtzayJCwmy60ijF3ZSbbrrfkIWy7UZ60MHo1ODLrOqJCgm-Jxie8rnsCxE7KMbNM3QGcNYfuj92FfSK5qwp4Ie4L5_IzGCq2AZFu4stQGT0AYC6wwsPjYPlZWnYyuhMS5UNaZeY0KDXcI8-rSfPOWn06-_2_dCHN9pQjdRF7pjbwzJ-W5nXsrJXccWjQ1wtyeuLEIJVa8ky7y14a_eL3jIy_xjsJCn8E2-gXGxmGIYoiJJLtH2qZF-N68GfbbmMtXaLn5aUEKhRYqLaV-8bkgKb1rBD_cFjoVdGH5zlgvgr-jQk_KBSyOaOQ533ZqPyixr_kwnNn2A0jwHCw0SHYZsuRe9jFg3KZycRUImt7iwPKO4QNkSKesnwCK7CpBr18PoGP1hm0MJgD5nY-P4MUnlk6SFd8S7b9-DT4AMZuIvAMUECd3Dn8eoGBYC3_-tf32_Pxl-91rjBcTsz3QeGI5LXd_mE6Y30c5gDj7XDj3-Z8g4cOl8iAIgDjUqc_6FDp95eiDGN_OsfUDXPs5cmhaoXhY26ON7IyoazTgGhyt8it0XUZ2Pl7ZF3q8sgPXU-e8ol8aLTUclHYH4KcTcgNO_y8_-mSMHKm10xey4FJ6hSSlh4PSPe_h4MHI18H5FRBUbaQNfWWw1WfvoDc9fph4gIPK6Dbc4L-8PUkElCKEhHbqq3wdoBJLKMbPpWhWrpMyT3I-w3WcLdKMrdJsOWvWMcuxrPJVXmFcpMecY5Gnx-OK50dK80UxE2tG2ZIu6SpesUWyjKqioLygcZqW8Qp5TBYUWy5k5BdApE09E9Z2uI6TPGZsJvkRpQ1vO8auuWTMv_TMOiyNY1dbsqBSWGdvWpxwMrwJr0LL3YOywEuDCnj_6ru892wPSaANXBpkVPtZZ-S6ce5kfU1D39fCNd0xKnQ7bLLRhvyBhSNsH6KyhO2HwM5r9l8AAAD__6mQBmw">