<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jan 5, 2022 at 5:32 PM Augie Fackler via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><span id="gmail-m_4106645987648096002gmail-docs-internal-guid-6b433c83-7fff-1432-96a7-42c8edd2bab6"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="background-color:transparent;color:rgb(0,0,0);font-family:Arial;font-size:11pt;white-space:pre-wrap">In addition to the benefits for Rust, the LLVM optimizer could also be improved to not optimize away defects like</span><br></p><br><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">{</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">  auto *foo = new Thing();</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">  free(foo);</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">}</span></p><br><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">which would then correctly crash instead of silently “working” until something actually uses the allocation. Similarly, there’s a potential defect when only one side of an overridden operator::new and operator::delete is visible to the optimizer and inlineable, which can look indistinguishable from the above after inlining.</span></p></span></div></blockquote><div><br></div><div>I think this is important to note -- tracking the pairing is something we should be doing already with the existing hardcoded list, as well. E.g. compile the following example with -O1 (<a href="https://godbolt.org/z/WsYKcexYG">https://godbolt.org/z/WsYKcexYG</a>).</div><div><br></div><div>When compiling "main", at first we cannot see the matched new/delete pair, because delete is hidden in the "deleteit" function. Then, we run the inliner, which inlines the "operator new" and "deleteit" functions. Now, main has a call to malloc followed by ::operator delete, which we proceed to remove, because they're allocation functions. But they're <i>unmatched</i> allocation functions, so this weirdly ends up skipping the side-effects of our custom operator delete, but NOT those of our custom operator new.</div><div><br></div><div><span style="background-color:rgb(255,255,254);font-family:Consolas,"Liberation Mono",Courier,monospace,Menlo,Monaco,"Courier New",monospace;font-size:14px;white-space:pre;color:rgb(0,0,255)">#include</span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0);font-family:Consolas,"Liberation Mono",Courier,monospace,Menlo,Monaco,"Courier New",monospace;font-size:14px;white-space:pre"> </span><span style="background-color:rgb(255,255,254);font-family:Consolas,"Liberation Mono",Courier,monospace,Menlo,Monaco,"Courier New",monospace;font-size:14px;white-space:pre;color:rgb(0,0,255)"><</span><span style="background-color:rgb(255,255,254);font-family:Consolas,"Liberation Mono",Courier,monospace,Menlo,Monaco,"Courier New",monospace;font-size:14px;white-space:pre;color:rgb(163,21,21)">stdlib.h</span><span style="background-color:rgb(255,255,254);font-family:Consolas,"Liberation Mono",Courier,monospace,Menlo,Monaco,"Courier New",monospace;font-size:14px;white-space:pre;color:rgb(0,0,255)">></span><br></div><div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254);font-family:Consolas,"Liberation Mono",Courier,monospace,Menlo,Monaco,"Courier New",monospace;font-size:14px;line-height:21px;white-space:pre"><div style="line-height:21px"><div style="line-height:21px"><div><span style="color:rgb(0,0,255)">#include</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">stdio.h</span><span style="color:rgb(0,0,255)">></span></div><br><div><span style="color:rgb(0,0,255)">int</span> allocs = <span style="color:rgb(9,134,88)">0</span>;</div><br><div><span style="color:rgb(0,0,255)">void</span> *<span style="color:rgb(0,0,255)">operator</span> <span style="color:rgb(0,0,255)">new</span>(size_t n) {</div><div>    allocs++;</div><div>    <span style="color:rgb(0,0,255)">void</span> *mem = malloc(n);</div><div>    <span style="color:rgb(0,0,255)">if</span> (!mem) abort();</div><div>    <span style="color:rgb(0,0,255)">return</span> mem;</div><div>}</div><br><div>__attribute__((noinline)) <span style="color:rgb(0,0,255)">void</span> <span style="color:rgb(0,0,255)">operator</span> <span style="color:rgb(0,0,255)">delete</span>(<span style="color:rgb(0,0,255)">void</span> *mem) <span style="color:rgb(0,0,255)">noexcept</span> {</div><div>    allocs--;</div><div>    free(mem);</div><div>}</div><br><div><span style="color:rgb(0,0,255)">void</span> deleteit(<span style="color:rgb(0,0,255)">int</span>*i) { <span style="color:rgb(0,0,255)">delete</span> i; }</div><div><span style="color:rgb(0,0,255)">int</span> main() {</div><div>    <span style="color:rgb(0,0,255)">int</span>*i = <span style="color:rgb(0,0,255)">new</span> <span style="color:rgb(0,0,255)">int</span>;</div><div>    deleteit(i);</div><div>    <span style="color:rgb(0,0,255)">if</span> (allocs != <span style="color:rgb(9,134,88)">0</span>)</div><div>      printf(<span style="color:rgb(163,21,21)">"MEMORY LEAK! allocs: %d\n"</span>, allocs);</div><div>}</div></div></div></div></div></div></div>