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

    <tr>
        <th>Summary</th>
        <td>
            [analyzer] Static Analysis runs out of memory on a tiny test-case
        </td>
    </tr>

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

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

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

<pre>
    The test-case shown below demonstrates a problem with Static Analysis running out of memory.  This is reduced from a large C++20 test-case reported to us, although the reduced test-case here is valid C++17 (or C++20) code.

I've tested with a modern compiler from `main`: 5d6218d311854a0b5d48ae19636f6abe1e67fc69 (llvmorg-21-init-14792-g5d6218d31185).

Setting a 60GB virtual memory limit:
```
$ ulimit -v 60000000
$
```

shows the problem:
```
$ clang++ --version | grep ^clang
clang version 21.0.0git (https://github.com/llvm/llvm-project.git 5d6218d311854a0b5d48ae19636f6abe1e67fc69)
$ time clang++ --analyze -std=c++17 test.cpp
LLVM ERROR: out of memory
Allocation failed
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: clang++ --analyze -std=c++17 test.cpp
1.      <eof> parser at end of file
2.      While analyzing stack:
        #0 Calling Class3::operator=(const Class3 &) at line 77
 #1 Calling Class4::Struct8::operator=(const Struct8 &) at line 89
 #2 Calling Class4::Struct8::m_f2(const Struct8 &) at line 90
        #3 Calling Class4::Struct10::m_f3(const Struct10 &) at line 101
        #4 Calling Class4::m_f4()
3.      test.cpp:56:7: Error evaluating statement
 #0 0x000055b69b1027bf llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/warren/llvm/current/bin/clang+++0x47647bf)
 #1 0x000055b69b1002b4 llvm::sys::CleanupOnSignal(unsigned long) (/home/warren/llvm/current/bin/clang+++0x47622b4)
 #2 0x000055b69b03f538 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007fccefa11420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
    ...
#35 0x000055b697df4672 clang_main(int, char**, llvm::ToolContext const&) (/home/warren/llvm/current/bin/clang+++0x1456672)
#36 0x000055b697c93e9b main (/home/warren/llvm/current/bin/clang+++0x12f5e9b)
#37 0x00007fccef4dd083 __libc_start_main /build/glibc-B3wQXB/glibc-2.31/csu/../csu/libc-start.c:342:3
#38 0x000055b697dee72e _start (/home/warren/llvm/current/bin/clang+++0x145072e)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 21.0.0git (https://github.com/llvm/llvm-project.git 5d6218d311854a0b5d48ae19636f6abe1e67fc69)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/warren/llvm/current/bin
Build config: +assertions
clang++: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang++: note: diagnostic msg: /tmp/test-59716f.cpp
clang++: note: diagnostic msg: /tmp/test-59716f.sh
clang++: note: diagnostic msg:

********************
    1m11.19s real     0m52.79s user 0m17.48s system
$
```
As noted in the comments in the test-case, suppressing various (unused) members results in the static analysis completing using about 4 GB.  Suppressing one particular unused member makes it complete essentially immediately (not using much memory at all):
```
$ time clang++ --analyze -std=c++17 -DUSE_4GB test.cpp
    0m57.16s real 0m54.30s user     0m02.84s system
$ time clang++ --analyze -std=c++17 -DAVOID_PROBLEM test.cpp
    0m00.16s real     0m00.02s user     0m00.03s system
$

```

I've bisected when this issue for this reduced test-case appeared to 6194229c6287fa5d8a9a30aa489bcbb8a9754ae0 (llvmorg-16-init-8141-g6194229c6287).
Pinging @tomasz-kaminski-sonarsource 

I've verified that if I revert that commit in `main` (and also the immediately preceding commit, which that commit depends on), then my reduced test-case here does work fine.  But the original full test-case still runs out of memory with that llvm16-era work reverted from the head of `main`.  (I can't easily try the original full test-case with a compiler from that llvm16-era, because that test-case is C++20 code, and it uses C++20 constructs that weren't supported by Clang back then.)  And of course I'm not suggesting that reverting that work is the right thing to do -- I'm just pointing this out for reference.

In any case, here is the reduced test-case:

```
// When running the Static Analyzer on this test-case, in C++17 mode, it runs
// out of memory in a few minutes:
//      clang++ --analyze -std=c++17 test.cpp
// As an aside, in C++20 mode, it takes a very long time (more than an hour),
// and uses a massive amount of memory (around 55GB), but it does eventually
// complete.
//
// If any of the lines declaring `x1`. `x2`. `x3`, ... `x9` are commented out,
// then the `--analyze` run completes.  For most of them, the static analysis
// run uses about 4 GB of memory, and takes a couple minutes,  Use the switch:
// -DUSE_4GB
// to see that behavior.  For `x9`, if that one is suppressed, the problem
// disappears completely (very fast run, without using massive memory).  Use:
//      -DAVOID_PROBLEM
// to see that behavior.
// Note that eliminating many other items also makes the `--analyze` run
// complete.  But these x1, x2, ..x9 are somewhat interesting in that they are
// private members of classes that are unused (and so warnings happen with
// `-Wall`).
struct Struct1 {};
template <bool, class, class> using StructName = Struct1;
template <class T> class Arr {
  T Arr[1];
};
template <auto BITS> class Bits {
  StructName<BITS, unsigned, unsigned> TheBits;
};
enum EnumA : int;
class Class1 {
public:
  struct Struct2 {
    unsigned m_f1();
  };
};
enum EnumB : unsigned;
struct Struct3 {
  unsigned m_1;
  unsigned m_2;
  unsigned m_3;
};
struct Struct4 {
  unsigned m_1;
  unsigned m_2;
  unsigned m_3;
};
struct Struct5 {
  Arr<EnumB> m_ArrEnumB;
};
struct Struct6 {
  Arr<char> m_CharArr;
};
class Class2 {
public:
  void operator=(Class2 const &);
};
class Class3 {
  enum { SomeEnum };
  Bits<SomeEnum> x1;
 Struct3 x2;
#if !defined(USE_4GB)
  Struct4 x3;
#endif
  Struct4 x4;
 Struct5 x5;
  Struct6 x6;
  Arr<EnumA> x7;
  Arr<EnumA> x8;
#if !defined(AVOID_PROBLEM)
  // `--analyze` finishes quickly if this is commented out.
  Arr<Class2> x9;
#endif
};
class Class4 : Class1 {
 struct Struct7 {
    Struct2 m_S2;
  };
  struct Struct8 {
    Class3 m_C3;
    void m_f2(const Struct8 &);
  };
  struct Struct9 {
    Struct8 m_S8;
  };
  struct Struct10 : Struct9 {
    void m_f3(const Struct10 &);
  } m_S10Arr[];
  int m_f4();
};
void Class4::Struct8::m_f2(const Struct8 &s8_ref) { *this = s8_ref; }
void Class4::Struct10::m_f3(const Struct10 &s10_ref) { m_S8.m_f2(s10_ref.m_S8); }
long glb_l;
int Class4::m_f4() {
  Struct10 *s10_p1;
  Struct10 *s10_p2;
  Struct7 *c = (Struct7 *)glb_l;
  int i = c->m_S2.m_f1(), j = i;
  s10_p2 = &m_S10Arr[j];
  for (;;) {
    j = 0;
    s10_p1 = &m_S10Arr[j];
 s10_p2->m_f3(*s10_p1);
  }
}
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEWltz27iS_jX0S5dYJEiJ0oMfJNnOpCpnko09Z_ZNBZJNCQkJaAFQtufXbzUASqQvk8lJba3KiSUC-PqKvsncGLGXiNfRfBPNb654bw9KXz9-08JY9XhVqvr5-uGAYNHYWcUNgjmoRwkltuoRauyUNFZziwY4HLUqW-zgUdgD3FtuRQVrydtnIwzoXkoh96B6C6qBDjuln2OAh4MwQOtY9xXW0GjVAYeW6z3CNmKbiG1YMmJA41FpizVYBb2J2BZ4aw-q3x_AHvCMczlwQI1E4cRbUQ-QaQERWyp9IRGxFVSqxjhK1lGy_hix4uQFx9qLxKFTNWoJleqOokXtmY0WSceFjBZJlK1hXi9YuqyzNF3Oc56U8zpfckxXi2zRLHiJKS6KplqsiHzbnjql9zOWzoQUdpbmxYrN9mOIiK0CQ_doLSmQwyL5sIGT0LbnbVAktKITNspoIzHif5J1xHLo3RrMTrBI_MsvvNyarMm2xmkxmPJtwKrlcu_VBrPZCbURSkJUbGGv8QjR_NbvSNbuNww7WBoncbIXlmQ_WHs0hM_uIna3F_bQl3GluojdkVrCr9lRq29Y2ZhO_VPVRmwVOLWiwxfscnLIvxBmxtZRdlOd3YEsHVfHY5SsP33697_g9uvXz1_JohOPjZL1um1VxS1J1HDRYh0l6y-fbtf3t2D6klTNoez3wVHJTX9O1ojdCWN6NBG7Ay5rELJq-xqdYSrNzQFKXn23mldI7n_UeNSqQmOwBqN67R_TSW6MqgQnD9a9BFNpcbTkT_eWV9-h7rujN3ESg3t90WqveQdc7_sOpSWu_wMFpgEuyraomii7hSPXBjVwCyhrUmcjWoySNQs7_zyIFsFjk5cbYtDzBuEVsSyBLW9bWt-23JiMNmRrdUTNrdJRdhOxZUUhKaxDxBZ0r7mFVkiEoiC8iGXpFCj3QPdW95Vdvo8aNryEXa4CLPsxbLdr2I_wVslU7OxvYNPkjJu9wE2Tl8Bpkk6R8zeRu12TR2zp71EWLHQ2b7aeL6JsXZBr3GqtNOCJtz23wW4WyXOCRhJInijkzOflYlWmCSvKBpzTO0rm2fg3X7SQ1nnlg_fr5WWT5o87ZaxG3jl5tiCkJbEcj3cH1WHE7h651igvV6rq6TPdplLQ45EXR2yTPOXFIi_KxgvpfWLKasLK_C1Wty1y2R8_y3uxl7yN2LKXLo3W0Coi8euMMVbmF8bYhLEka-bZErYUCL5ipU6onz0nv3FZt6gjtgz6mezZKmnxaTBh4v55_CzgF01VYcPTNGcJ7HYajVUad9oGeVpRRuzuabnYLfJZK2T_NNvL3i8c7UEjr2Oj4sRJkea5y6nB3-LYpTGWZfOxNEXd5IuC-RCzc2k0cL-F6sB1xNbuZzsyxINSbRAGnLsHJ_8lpaf5fLEo2JA6smwxYbNaZbgqgRj8RTqsmeOqvNApJsrP6zpZZrDbtaKsdsZybXeB6F3Zi7am_EFrs032-F__vTl_ZHGWEjlD9ojj81u36HDiKsrWWc7o_0B7OTUFYsEQPNVf1mZSMPRSjhezNSCFjHNaoRJKWsoJleo6ylk-p_qKC5-EdUUZpFlOLPUGqZCxCgwiCHkKmXhE6f-p3HiggpUqMAgXpJffpXqUo4uSrB_cJXFlZEtbj8qIJyo2pbG8bbG-EU41_1TzyXpDTkHXoBF7f3LDjUFNSjGvlS-VRfpdC76XylCF3pl9KPPYL_y4-jFUQeuHh_X2N3j47RbuPn_69PnPj79_gLuPn27v4eGze7z54wN8vf3y-euDJ_3lrRJmaVzqeq-MOW_QCK4gwxp4KIH_qdSkaNsd6X9qF-arIl00oYb5NQxz-Enl_7L-KcqmXZrG6Yq6Kd66rJ10cxYXKwM9lV9JlxZxvjRgno3F7s0-YG0co1R2-opTda4SHD6fGyuKyqY_HjUaQ6n_xLVQvXHXVPYGa7JOh12JmhgyfXsBMb475EN3SB1Vi66C6B0YL6nszuHDJga4H1FREqmYtKLqW67BUwpkoOPf0YCLGQ4PgVxKWsHb9hlE12FNbtQ-E5NS2UCs66vD0EhxC7xt6U6_2fv8TEcxu_nj_naXf9iMS-NglCJOF8FMSTfP4ywJJvLrCYuX-dRMP0l6_e_PH292X75-3ny6_ddrBpLkwsD5ScKmTCRxkr32lVdtY2iVS2Gwcs3yAcnKrq83PUKjtP_4ujfnxyNy7Zv5RbrKGVtVC7YsGj6vl3zFs4TzfLkqq7Jc8lUxzzkm4845XfjOeZnm6Ww_RgiN8xch92TiKE-s6rj5a_add0Ka72JmlOTaBxuYCHJCLRpBTB24BdHAR9B4Qurl6AFdCGHJky-dP_HkIlVrlHPwsa8dNVZYExf-KF2cx4OoDhO8Go8oawM-mbEtwUjont-baNQKDTwq_R0aITEG2PTWkVZa7IXkLTR9244nN1a0LQVQM21pfap1rJBa08UMNffIXuxhKkPgB8pfqhmJHlMjsfwIFZcRKywgN6J9Bquf_5abMFGZjlJeMEFaKLHilPXd0uW4MKPhEFUIQ8sr6FLjdFUa1w8ZD_KILqMW1kUvP0sqn6kBknvXWTvNxxS9YO2b1Ur12iCQf3QUHcH0-z0aF68cplfU-aNTnvCjFC32BzKMW1RQK5jNAtK33lg4KiHDSeEtQ_dFY0NsVudxlAQun2GIu8NM682J1yWjTIIXFT7wJznVMIuj0-M53V-oQYWrOwnzQo7mZl3QtrDOmS7YU68SEjg0-AidkL1FMxQZbqt7_fxcIZxeG-ASuBH1C-5YMubOumzA6T4_u9bMh9CILTulnUeRUuGgeu2v3IUCeZJzIw4dN0acEHinejkWkK68Vr2sYT7_sAmXtuwtkXaXE08obU-p5wI8JKb4_Oiy9rFxNlaNMww17AZqrFquXQRbJE-pu2_0jp3fZWRftqUOy31eUTiioigkbqzJMBPprA_QSPvPiqdjVF0NHJoY4E5p6JSxgacuhKWX6fuCTABeb-f8PZqdhSs62KVS_bHFs3-wLcAfxo-5zKOw1WHiMudsOpLDtwHuypV44CehdOB60IRzhcZvodJBmHPNQgXKdjLtPAPXwvjMdK5MQs3gXKnhxrm-i-PCHkjSUEgEXxnkXcVOpNeu_yI__0Cky_LvyoZFbEUnpB-6dM5t7AE1CIud8WnIF0PvmPkNjzxnEIPwlJJwT8w71pOvso3q8NGlRGlRh_DnCjruzj3TrgvwUYsTt3guASmOttSchDhMkKF8C9nTKHjkmkKTgQMZQDr9XiBJkD-pPCPDuvzuI_sw8IKo2ETFTZSRk1jsji0xEGXbUqnWzRSIgcub7DYYzp__nVN4yG4GuNc47hg80EH_dq21I0p11QN9iuabNJoHFt7khfdWwebjw_0FZSOsOcNceImyrdvHtjCMmCbvs1t4OCAdfkEOZd_Brey7NVDDIaT1zz01N-pLA71jX7aiGiatE3WyM0twpgndrknDbDDzi2eqr8lvHPkLv5uXFsvOJEYE0gF59Iy98Sx7QXaCnP-fIc_PyGTubOsEJVt0u7XW4dP7xxcvjrsxlzu9PXDtnk0Oj2zG3rTZSYkaptPqsNsPg_147H3Uiw2c3aJiA_eqw1v_4WZQj3ez7bBELD8N-hyM-RSUGbFMNBCxtEYqTuuILYfgHSaCg5GesvMJlLVopov5BH8OT_OBm0GXT4vhycUYa8db8d7C8l0epzE5cDoKPeMY2ggpzAEN_E8vqu_UXTZDzzPNvPGICW8Xx8Xqldxv2SZ3F2hyYad3tBjd0eHWdrt79upyvrjby9G54AXdbpsNe4NX_c2XFT8isHrF2JIYW_7oXJo4kV-DDAy9-y3HCJkopYmPxudgDBQHYfTdxvRGOPyf_trGLHcaGzd-LjYQsbXzAcohYSXbOFHfxf_h9zcmTcYkSIdx4CYsxU6vTqBAyxW7-7bctV42EvztL3heZB1Hck24x3R61UYrbLpS0ELlZI7YcvQsYqsRD179wu2rZlF2S24aj9IJ28I3tyrOjuGoBeTFyKbfRkalbokQMhd12dhlPFxycWov2N8DeqKeQWeSi0KmXu99Z9RlXdXXWb3KVvwKr9MiX80TtsgXV4frNFsVFaa4rBJkWK_mbFVkVd6kVcKTYpVfiWuWsHmySFYsmRdsES_rmqd1sioWNZvPsYzyBDsu2pia41jp_ZUbrVyneZbnyVXLS2yN-ysOxiQ--sFLxFg0v7nS1260XfZ7E-VJK4w1FxgrbOv-_COENh3Nb976242XMwNF3Z0V8vnSKF71ur3-z7_qDqKcrtn_BgAA___YZIEs">