<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Optimizer removes unrelated test due to later static_cast"
   href="https://bugs.llvm.org/show_bug.cgi?id=39572">39572</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Optimizer removes unrelated test due to later static_cast
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>7.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>scott.smith@purestorage.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=21096" name="attach_21096" title="Complete test case">attachment 21096</a> <a href="attachment.cgi?id=21096&action=edit" title="Complete test case">[details]</a></span>
Complete test case

For the following code (see attachments for the full test case):

        for (size_t i = 0; i < 20; i++) {
                op * res = nullptr;
                if (rand() % 2) {   // compiler turns this into: if (rand(),
true) {                
                        count++;
                        res = get_an_op();
                }
                static_cast<no_dispose *>(res)->execute(); // nullptr
dereference 50% of the time   
        }
        printf("ASDF count = %d\n", count);

I expect the code to usually crash due to dereference of nullptr.  However when
compiled with -O3, it prints "ASDF count = 20".

Note the static_cast - if you remove it, the code crashes as you'd expect. 
This may be a case of the compiler making unrelated decisions due the
unexpected behavior of the null dereference (though the cast itself is legal,
and the change in behavior only happens with the cast).  However it does seem
odd to me that the cast affects the earlier if() statement.

To repeat:

good:
$ clang++-7 -o good a.cpp
$ ./good
Segmentation fault (core dumped)

bad:
$ clang++-7 -o bad -O3 a.cpp
$ ./bad
ASDF count = 20</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>