This is an archive of the discontinued LLVM Phabricator instance.

[clang-cl] Put dllexport attrs on static locals also in template instantiations (PR39496)
ClosedPublic

Authored by hans on Oct 30 2018, 8:08 AM.

Details

Summary

In the course of D51340, @takuto.ikuta discovered that Clang fails to put dllexport/import attributes on static locals during template instantiation.

For regular functions, this happens in Sema::FinalizeDeclaration(), however for template instantiations we need to do something in or around TemplateDeclInstantiator::VisitVarDecl(). This patch does that, and extracts the code to a utility function.

Please take a look!

Diff Detail

Event Timeline

hans created this revision.Oct 30 2018, 8:08 AM
rnk accepted this revision.Oct 30 2018, 2:25 PM

lgtm

test/CodeGenCXX/dllimport.cpp
1010

I notice that we don't emit foo as an available_externally definition right now. With your change, will we do so? Should we?

This revision is now accepted and ready to land.Oct 30 2018, 2:25 PM
takuto.ikuta accepted this revision.Oct 31 2018, 1:35 AM

LGTM, thank you for fix!

This revision was automatically updated to reflect the committed changes.
hans added inline comments.Oct 31 2018, 1:50 AM
test/CodeGenCXX/dllimport.cpp
1010

Ah, good point. It's actually the static local that was previously preventing us from emitting it available_externally. We normally would, but DLLImportFunctionVisitor would discover that the function referenced a non-dllimport "global" variable, and determine that it was not safe to emit the definition.

But now that the static local inherits the dll attribute, this works out automatically.

$ bin/clang -cc1 -triple i686-windows-msvc -fms-extensions -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - ../tools/clang/test/CodeGenCXX/dllimport.cpp -DMSABI -w | grep 'define.*?foo@?$T@H@pr39496'
define available_externally dllimport x86_thiscallcc i32 @"?foo@?$T@H@pr39496@@QAEHXZ"(%"struct.pr39496::T"* %this) #0 align 2 {

(Same for S<int>::foo() one.)

hans added a comment.Oct 31 2018, 3:10 AM

Bah, I should have known something was going to break if I touched this :-)
http://lab.llvm.org:8011/builders/sanitizer-windows/builds/37132
http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/1017

Here's a repro:

template <typename T> struct __declspec(dllimport) S {
  void foo() {
    static constexpr char src[] = {"hello"};
    T arr[sizeof(src)];
  }
};

void use() {
  S<int> s;
  s.foo();
}

$ bin/clang -target i686-pc-win32 -c /tmp/a.cc
/tmp/a.cc:4:17: error: invalid application of 'sizeof' to an incomplete type 'char const[]'
    T arr[sizeof(src)];
                ^~~~~
/tmp/a.cc:10:5: note: in instantiation of member function 'S<int>::foo' requested here
  s.foo();
    ^
1 error generated.

This is annoying. Looking into it now.

hans added a comment.Oct 31 2018, 3:37 AM

r345709 should do it.