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

    <tr>
        <th>Summary</th>
        <td>
            CSA Exploded Graph will end on multiple non-`shouldInlineCall` destructors
        </td>
    </tr>

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

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

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

<pre>
    Requirements to trigger the bug:
1. Define a class with >=2 member objects of the same type `T`.
2. Type `T` must be a class that has a non-inlineable (a.k.a `ExprEngine::shouldInlineCall` return false) dtor.

```cpp
struct Test {
  Test() {}
  ~Test();
};

int foo() {
  struct a {
    Test b, c;
  } d;
  return 1;
}

int main() {
  if (foo()) return 1;
}
```

![image](https://user-images.githubusercontent.com/32470225/215742208-a2f5514c-3006-4f23-baba-c491c686d810.png)

https://github.com/llvm/llvm-project/blob/5bc4e1cd3be8844c1e7947647020710016925e9e/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp#L1076 will return false as there is no definition of `Test::~Test`. And I also tried to add a default dtor on `Test` (which will make `shouldInlineCall` return `true`) but force `shouldInlineCall` to return `false` when analyzing `b::~Test()` and `c::~Test()`, and the exploded graph will also end immediately.

Since the exploded graph ends here, it will report a false positive on unreachable code in the end.

```
warning: This statement is never executed [alpha.deadcode.UnreachableCode]
  if (foo()) return 1;
                    ^
1 warning generated.
```

I found this patch https://github.com/llvm/llvm-project/commit/aac73a31add5e80c746a7794d832f2cdf226486c may be related since it remove the following comments. And I tried to fix the bug by imitating this patch but failed.

```cpp
  // FIXME: We need to run the same destructor on every element of the array.
  // This workaround will just run the first destructor (which will still
  // invalidate the entire array).
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVkmP4zYT_TX0pWCBolYffOjNHxr4cpnpIMutRJYszlCkQ1K95JDfHlDy1pOeAabRkCWW-Gp7rygMQe8t0ZZVt6y6X-EUB-e3t-4PtH8Oq86pt-0n-mvSnkayMUB0EL3e78lDHAi6ac-KG8bvGb_JM7inXlsCBGkwBHjRcQBWPLDiXsBIY0ceXPeFZAzg-hkg4EgQ3w4ErOZPrObZAiYyeLpahXEKEboLdBwwwoABEKyza22NtoSdIWCixexrhmnrw-vBP9i9tpSiLG7C4CajHueX79CYhOwpTt5CjyYQExtQ0fljEMdrzZd_eTgsKyH6SUZ4ohCBNbfLIszPTLQJJK029yfDPxcLK46vJ_P5fr5qG6F37grhuP3oDq_XFm_QMXEH8gwEwJp7UFfPx-zyd36_cTqitv_1qvtUynNAyfoDsFON3hVO5Ky61SPuiVX3TLRDjIeQOiF2TOymQH49W0O213GYurQinY1kYybdyMSuEGXDhaiY2Im8akoheLtG0VdVXsp1wXm9LntRrDvscC3LTS7rtlZtzrOD3aeor8J5733xeHRjzPPpZ33wLjGUiV1nXMfErupkSblURUdtW5Yyp2ZTNnUKjDc553m9ERVtiImdNJjc7oxOGz9HjFreWDRvf5NnYnfnfHrrwsrEwRurPs11zRK_RPH_nDc1vGhj3lETMJGePIEOYB2oJDUdtbNJSkkmiWMzyxe61TyDG6vgEdCEWbWkknxRKcC0HScTZ7aDs2eAmqeuvwxaDksMI36dVfgD6bCaRz9R6r7YQDclGnv53V3RXW1cZFdzeBnIAs610nafTN11NgsHaw5oVTLKj4xJDMmeBgu9HoxTpGDv8XDMZS4EWQV6HElpjGTe3kn9s7aSPtpOVgVI1U8udDy15-B80uXSoIMLOupnSuWcrCeUwzyQpFME2i6wVn08W5bHF_RW2zRS4WnQAULEOA_euen0TB7oleQUSQGrbtEcBswUoUo-sl8vTu-cmjX3E1qGD_5Y9XCc7XAMDfZkyWOkcx4fKf8RejfNjdABDhjlAD-tPunGUacbRNkUWOSoVEUtl01ZY9NsStUWohdS9ULUZVtLGPEtHRGeTIoPwtxMHcHT6J6XtvbOGPeS8kjw6UQ7ieSsj16_no426N5AjzrJ2O6vk5k5jtrQd7p5PikAlnxh9_j7Lw-pr78RWFo8-clezkBFy5hf5Jha_QZkluYfz0r0Hk98PQPPPHlx_iv6ueQzM7-k0_IE32sf4jX-e4GHqI35BlTbZzRaYTyKwUbtj_6Z2Hzb-ZXaFmpTbHBF27xuqrwu6kashq1UXSM2Qqiub2XTSt7lPd9s2iZvqrIS5UpvBRcFz4s8z_OyEFmOG0FF0XYcUVBDrOQ0ojZZIkfm_H6lQ5hoW_MyFyuDHZlw-nbx25lB3bQPrORGhxgu26KOhrZ3n2_g4aTs_10GQ5oJzsI4magPhuZPiu9Mr0sdw2ryZvvTvJ4TCEzs5hz-DQAA__8G0Oq8">