<html>
    <head>
      <base href="http://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 --- - fatal error: indirect goto in function with no address-of-label expressions"
   href="http://llvm.org/bugs/show_bug.cgi?id=18658">18658</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>fatal error: indirect goto in function with no address-of-label expressions
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>3.3
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>release blocker
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>C++
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>skaller@users.sourceforge.net
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>This code:

  // If there aren't any address-of-label expressions in this function,
  // complain about the first indirect goto.
  if (IndirectJumpTargets.empty()) {
    S.Diag(IndirectJumps[0]->getGotoLoc(),
           diag::err_indirect_goto_without_addrlabel);
    return;
  }

is misguided. It leads to this spurious error:

fatal error: indirect goto in function with no address-of-label expressions

The actual code is in a macro emitted mechanically whether or not
there is an address of a label taken in the function.

  #define FLX_START_SWITCH(name) name##_start: if(pc)goto *pc;

Since pc is initialised to 0, the indirect goto will not be taken.
Much worse, the assumption of the check is completely wrong:
in LLVM you can take the address of a non-local label, and my
test case actually does it.

Indeed in my actual application, I am using an assembler label hack 
which allows jumping anywhere, to defeat the poor performance of
most C++ compilers (including both gcc and clang) handling large
functions. Instead I borrow a trick from Mercury which allows jumping
between functions. I wouldn't be surprised if this hack broke something
but this is not the cause of this problem :)

The proof of the wrongness of this check is that the check is defeated
by including rubbish in the program; this code:

  crap: void *pcrap = &&crap;

defeats the check, despite being completely irrelevant, and hopefully
the optimiser will remove this (since pcrap is never used!).

Furthermore, with this crud added to defeat the check, the code actually
works correctly!

I am using an svn build of 3.3. Unfortunately I can't compile a new version
because it takes too long.</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>