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

    <tr>
        <th>Summary</th>
        <td>
            clang-analyzer: false positive destructing a union containing a union
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    TL;DR https://godbolt.org/z/6nW54nTh5

Consider this bit:
```
template<typename T>
union U {
  U() {}
  ~U() {}
  T t;
};

template<typename T>
struct A {
  ~A() {
    if(b) {
      u.t.T::~T();
    }
  }
  U<T> u;
  bool b = false;
};


int main() {
  A<A<int>> nested;
  return 0;
}
```

clang-analyzer thinks `U<A<int>>::~U()` will implicitly call `A<int>::~A()`, therefore accessing an uninitialized `A<int>::b`:
```
[<source>:11:8: warning: Branch condition evaluates to a garbage value [clang-analyzer-core.uninitialized.Branch]]
    if(b) {
       ^
[<source>:21:13: note: Calling implicit default constructor for 'A<A<int>>']
  A<A<int>> nested;
            ^~~~~~
[<source>:21:13: note: Calling default constructor for 'U<A<int>>']
  A<A<int>> nested;
            ^~~~~~
[<source>:3:8: note: Returning without writing to 'this->t.b']
  U() {}
       ^
[<source>:21:13: note: Returning from default constructor for 'U<A<int>>']
  A<A<int>> nested;
            ^~~~~~
[<source>:21:13: note: Returning from default constructor for 'A<A<int>>']
  A<A<int>> nested;
            ^~~~~~
[<source>:22:10: note: Calling '~A']
  return 0;
         ^
[<source>:11:8: note: Field 'b' is false]
    if(b) {
       ^
[<source>:11:5: note: Taking false branch]
    if(b) {
    ^
[<source>:14:3: note: Calling '~U']
  }
  ^
[<source>:4:9: note: Calling '~A']
  ~U() {}
        ^
[<source>:11:8: note: Branch condition evaluates to a garbage value]
    if(b) {
       ^
1 warning generated.
```

However, assembly shows there is no implicit `A<int>::~A()` called from `U<A<int>>::~U()`.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNVkuP2zgM_jXyhRjDjyQeH3zIJFP0sIdFkcGeZZtx1CpSIMkTzPz6pew87CaZRwt0N5Adi5L4fSIpUqWuX4rVXyx9WH6DjXM7y9I5S75Qa3RdaulCbRrqvdIzU_9MJ2q1mbJoyaJ5_15oZUWNBtxGWCiF8wr68Vl0aF3X4XYnuUOWLtzLDhXfIqxY-tiPtkpoBU_AsodeAPDEknuW5J0oWx6lLHu8PrACgj4s9uLT9wfQrTNt5WA-hCeg-QDoIAUQa5KWF2KANnThyu-eWva46teeaPgZo20sz_tMF54KtIPJpdYSSmDpEtZcWnxja_1bKAdbLtQlZSK08A_N8BsmIIXWYT1AM-haoyAaoVxzYv-uJFfNHVdcvrz2nlc_LNCkp5-hTuY4-IzmwF5ICYLcISrh5AtUnPo0MFx4WDU_rWLJgnDQ4FobBF5VaK1QDXAFFDpKOMGleMX6mqLSr78RlWz6QLOtbk2F_YI4ptc9PbDnhlQ3_vPBcFVtoNKqJiiKVHzmsqV4suA0cGi4KXmD4KUIpHRsoruKWIcjomGvkk2Xvr0fXaT08RblxFOOU09UaR_jc1iQUb19jnaGGte8lc5voY92bYBsCSzJLgKEZANSH4if88-zzMbt86Tf4HoZYX-Ca3oMiSPTb92B8Vz3wm1062BvyLXUp3AgSj4Z3tFaF5Zjgtdz1y84-MxgbfT2_2ey36L8H0Vk4ilH1yLS43fpaEjjImuOMN9NL0eMLwJl7RF8qAAV0T7h_3ZW6JCmQ6QV_9FZ3-uH8pR_3oN5C2NyOB03LPY0ttiwAN5W6nXmH_bCzQvBL7jiU2n-sx6KjwUFGlRoSGsdvlFkv-o9PqPxhY9bi9uSSqXd6L3t66APFKXP-f29AtqVWaqP3dH7YKkOAyzi2SyP0ox-QV2kdZ7mPHBUt7EYlzhvvj6wdtqS8Z6RDnh_rrs6Df0Nj0zr6JYyEAWtkcVPV0_KqW0ZVnpLHSmfj393O6O_Y-WoK6xt0dLHNI-jPNgUs0k0W0_S6D7K8nLCszqr1jlm67qMk2hW80DyEqUtfBgkicI9dCrom_wYiCKJkiSOqaXpLM7CKMZ8Gld5VE0xSvKUTSKk65UMPQ9_Jw5M0VEq28bSoBTW2fMgeUw0CrGDI_28pSphir9xYyylu6DDLjru_wLvSB5a">