<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 --- - clang-cl generates incorrect code for globals without static initializers which have references to imported functions"
   href="http://llvm.org/bugs/show_bug.cgi?id=20076">20076</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>clang-cl generates incorrect code for globals without static initializers which have references to imported functions
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>unspecified
          </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>ehsan@mozilla.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>We hit this bug during the startup of Firefox built with clang-cl.  Here is a
reduced test case.  It consists of a DLL and an executable, and the bug only
hits the codegen in the executable (test.cc).  See below for the full test case
including building instructions.  We tested this against MSVC 2012.

Also note that if you force mi below to get a static initializer (for example
by initializing the second member to rand() instead of 5), the bug goes away.
This happens because clang-cl generates code to read the value of foo out of
the IAT in this scenario.

$ cat test.cc
extern __declspec(dllimport) void test_output(struct ehsan*);
extern __declspec(dllimport) int foo(const char *);

struct ehsan {
        int (*f)(const char *);
        int k;
};

ehsan mi = { foo, 5 };

int main(int argc, const char **argv)
{
        test_output(&mi);
        return 0;
}

$ cat foo.cc
#include <stdio.h>
__declspec(dllexport) int foo(const char*s)
{
return 5;
}
struct ehsan {
        int (*f)(const char *);
        int k;
};


__declspec(dllexport) void test_output(struct ehsan *s)
{
  printf("%p %p\n", foo, s->f);
}

$ cl foo.cc -link -dll -out:foo.dll

$ clang-cl test.cc foo.lib

$ ./test.exe
621F1000 008F1032

$ cl test.cc foo.lib

$ ./test.exe
621F1000 621F1000</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>