<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - clang does not remove FDEs for zero-sized functions which breaks exceptions"
   href="https://llvm.org/bugs/show_bug.cgi?id=26739">26739</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>clang does not remove FDEs for zero-sized functions which breaks exceptions
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </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>Common Code Generator Code
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>egor.kochetov@intel.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Currently clang produces no assembly code for non-void functions without any
code inside (if using at least -O1). Definitely, calling such functions is UB
in C++, but this also has some side effects. In particular, these functions'
address range is zero that sometimes breaks exception handling.

Supposed solution is: remove FDE for the functions that are shrunk to zero
length. The details and rationale are below.

Consider the following source:

int f() {}
int main () {
  try {
    throw 1;
    return 1;
  } catch (int) {
    return 0;
  }
  return 2;
}

When the exception is thrown, then the runtime unwinder looks for the correct
stack frame information (FDE), and actually finds two of these: for the
function f and for main, both starting at the same address. Since normally no
two functions share the same starting address, only one of these FDEs is used,
and if we are unlucky, the unwinder chooses the FDE for the function f and the
exception misses the 'catch'.

The real test case which is broken because of this is here:
<a href="https://android.googlesource.com/platform/ndk/+/master/tests/device/test-stlport_static-exception/jni/dyncast2_1.cpp">https://android.googlesource.com/platform/ndk/+/master/tests/device/test-stlport_static-exception/jni/dyncast2_1.cpp</a>.
It is broken if using clang++ with gold linker, stlport c++ library statically
linked, and the unwinder from libgcc.a

Supposed solution is: remove FDE for the functions that are shrunk to zero
length since such functions can actually never throw an exception and need no
stack unwinding information.

To see the issue reproduced, you can compile the source above using 'clang++
-c' and examine the result with 'readelf -wf'. There will be a potentially
faulty entry with 'pc=00000000..00000000' followed by the entry for 'main' with
the same starting address.</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>