<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 - Handling C++ exceptions on Windows x64 corrupts local variables"
   href="https://bugs.llvm.org/show_bug.cgi?id=43585">43585</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Handling C++ exceptions on Windows x64 corrupts local variables
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>9.0
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>normal
          </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>brian.apps@oxfordsemantic.tech
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=22638" name="attach_22638" title="x64 Disassembly">attachment 22638</a> <a href="attachment.cgi?id=22638&action=edit" title="x64 Disassembly">[details]</a></span>
x64 Disassembly

I see segmentation faults in my product when switching from Clang 8 to Clang 9.
Sometimes local variables are incorrectly initialised after an exception has
been successfully caught. With certain input this can lead to a crash at a
later point. For one of our unit tests this crash is 100% repeatable.

After some investigation I'm confident this is a Windows only issue with
exception funclets incorrectly spilling XMM registers. I can confirm this issue
does not occur when I use the master branch of Clang because of the change
<a href="https://reviews.llvm.org/D66596">https://reviews.llvm.org/D66596</a> ([WinEH] Allocate space in funclets stack to
save XMM CSRs). This issue is a bit of showstopper for me because it leaves me
worried that there are similar problems in our product code that we have not
found through testing. I'm raising this issue in the hope of getting the D66596
change incorporated into a future clang 9 release.

It's hard to come up with a simple example. The code below demonstrates the
corruption problem (but not the crash). It shows how a constant data member is
initialised to the wrong value.

When the following code is compiled with:
clang-cl /O2 /Ob1 /EHsc code.cpp
and run it prints "This shouldn't happen to Two, value of a is 1". I would
expect the code to run without showing this message.

#include <iostream>

struct One {
    const size_t a = 1;
    const size_t b = 0;

    ~One() {
        if (a != 1)
            std::cout << "This shouldn't happen to One, value of a is " << a <<
"." << std::endl;
    }
};

struct Two {
    const size_t a = 2;
    const size_t b = 0;

    ~Two() {
        if (a != 2)
            std::cout << "This shouldn't happen to Two, value of a is " << a <<
"." << std::endl;
    }
};

void throwIt() {
    throw std::string();
}

bool mytest() {
    for (int i = 0; i < 2; ++i) {
        try {
            One one;
            throwIt();
        }
        catch (const std::string& s) {
            return true;
        }
    }
    return false;
}

int main(int argc, char* argv[]) {
    for (int i = 0; i < 2; ++i) {
        Two two;
        mytest();
    }
    return 0;
}


For more details see annotated attached disassembly it shows how mytest()
overwrites the CSR slot for XMM6 in both the unwinding and catch handling
funclets.</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>