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

    <tr>
        <th>Summary</th>
        <td>
            [clang code-gen] #pragma FENV_ACCESS leaking across template declarations/definitions
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            bug,
            clang:codegen,
            platform:linux
      </td>
    </tr>

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

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

<pre>
    We have encountered an assertion being hit in codegen relating to FENV_ACCESS:

`Assertion failed: (CGF.CurFuncDecl == nullptr || CGF.Builder.getIsFPConstrained() || isa<CXXConstructorDecl>(CGF.CurFuncDecl) || isa<CXXDestructorDecl>(CGF.CurFuncDecl) || (NewExceptionBehavior == llvm::fp::ebIgnore && NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) && "FPConstrained should be enabled on entire function", file  clang/lib/CodeGen/CodeGenFunction.cpp, line 163, void clang::CodeGen::CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(clang::FPOptions)()`

This is reproducible with: 

```
template <class> struct a {
  a(int, char);
  void b() { c() ?: 0; }
  bool c();
};
#pragma STDC FENV_ACCESS ON
void d() {
  a<char> e(1, 'j');
 e.b();
}
```

Basically, as it stands, it looks like when a template is declared under the scope of this pragma being set to one value, and then instantiated under the scope of this pragma being set to another, the value of the pragma at instantiation is taking precedence, which can cause this assertion as well as undefined behaviour when you flip the values. For example, 

```
#pragma STDC FENV_ACCESS ON
template <typename>
int b() {
  int x;
  if ((float)0xFFFFFFFF != (float)0x100000000) {
    x = 1;
  }
  return x;
}
#pragma STDC FENV_ACCESS OFF
int f() { return b<void>(); }
```

exposes the same issue without the assertion being tripped. With `Wuninitialized` on, this shows as "uninitialized". As the definition is under the scope of this pragma being turned on, FENV_ACCESS should have the rounding mode set to dynamic, which would lead this expected warning to be "sometimes uninitialized". This proves that the pragma being set above the instantiation is taking precedence rather than the pragma above the definition being preserved. 

FYI @hubert-reinterpretcast 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVt1y27gOfhr6BhOPTDn-ufBFIkc9uThpp82c9lztUCRssaVJDUnZzj79DijJlrvdbpvJWBIJfADBDz8iBL23iBt2_8g4t1o6g15UX11tGefsfjsRbayd39xsTSqn3jafEWpxREArXWsjelQgLIgQ0EftLFSo7R5qHUFbkE7hHi14NCLSenRQPr3874-Honj69InlDyzbsmz4XWQPF5yd0AYVyx-A8VXxrpwWrS9bK7coDbB8y_It2NaYJnpgy4ItCyCpx1YbhX66x_gcyg-FsyF6oS0qxleMrwdZHQTLi-LLl06ildF5gmb509_t_Uhvi7-jxvjqBU9PZ4kNne4Ra3HUzg8HMeZ4oGDkD7ume2L1vLfOIzC-YHwBL3j66FqrtN3_s_Ig8V-nsFt5QeExxFeN4dU9HdEyvk5udaiM85sYQahdaxRUdMGiMqjAWUAbtUfYtVaS88QRXsBOGwSQRtg946XRFeNl4RS-IyPDW9nrTGXTkJLRFmG2yOn96LTq9ZOvg_L4Y9DvF9-VH96nAIaPD8_Pg-TlAv-DpkHP-GqEetFIJycKsEU2Zt1rrQPoAB4b71QrdWUQTjrWiXu39Oz_02fEQ2NERGB5IY0IgeVP0HkCAtjysRMDEIyvtI10ZFkLTx7kl80UhOrCzUeQw3tekgMZyx-BLbeDfOWcGWQuMLR_eed548X-IODT67YYZxu8f-lEks1rPowczYvkYf4EyPhqRi4zvvzK-PLGa5xWP_DgR0Hqfh9F0FIY80aAIoCOEKKwKtC3jmCc-xbA6G8IpxotCLgEVwdQKI2gOtNahR5ijRCkaxDcDiJdXn_ervIEjFRlnEU4CtNiMmkVqVnQluxGLeJvwgnrYk3UKpJCQu4UcJAXcQRPFUwHiOIbgTQeJSq0MnlzqrWsQQoLUrQBO6PXAioCnNAYepKHu5SXVZfzre8C9OZa2BndXJ0JUyidBzyLQ2OSmZ9Q9xc4MmZ3fGvQigNSkUub2sYxZwf-0PJ5xG29gyS02hknIuPr7Fz2f8D4jGrXzeYs6_--wwU4U62D2Qh7lBIeY-vtyPKVjD85Z1lez7Ib5V-PVrG8oDzpCntHdfg5y_HcuIChY5Q4EHdD25US18a0_H2bjF43DaopfNaxBrbIPrdWWx21MPpPVGyRAdXbouNIqN2JmEJl-1aO8yk8dJYTY_RAwF_iOB04VXqyNA5S3w1SwycM3_cXODiFQ2qoNysOWl6ZfUpKBoXqbOG5QUkJdxLe9kNARY2NB3fAqA9Ifn5_nNfOTXdMERVxnGrX1BSV633799wDLyiHCc3eJO4FYxS7zkTjMaA_0g2Nb7r8_zOweVa3Ffp451HTINR4jFKECBO1ydU6X4sJbmaL1f1iPudLPqk3uZrdZ2LO52K-ni93QuGsWi6qNQpcr-65nOgNz3ieLbLZbJXPZnx6L-eLareu5Hq93s2VYvMMD0KbKfX8qfP7SeLYZpFni3xiRIUm9GNd1e67Rs04H9phP45d1inDd87T9GC0bc_99Oc3BH9XtfvA5pnRIYarwaijSaNjAk0T3h1h3lMyD-k2JpHB7iKE9C6Ea2Xvyrroe3N5jX2YtN5s6hibQC2cl4yXex3rtppKd6BZgwae7nHXePcVZWS8TJEgpBSMvwIAAP__ZQlrqw">