Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clang-cl tries to instantiate all of the methods on template dllexport classes #20537

Closed
ehsan opened this issue Jun 30, 2014 · 11 comments
Closed
Labels
bugzilla Issues migrated from bugzilla clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@ehsan
Copy link
Contributor

ehsan commented Jun 30, 2014

Bugzilla Link 20163
Resolution FIXED
Resolved on Aug 20, 2014 20:18
Version unspecified
OS Windows NT
CC @majnemer,@zmodem,@jrmuizel,@rnk,@rinon

Extended Description

We hit this when building Skia as a DLL with clang-cl. FWIW I think the semantics implemented by clang-cl is much saner, but I guess MSVC only exports the symbols that are used in the translation unit and doesn't try to instantiate all of the other members.

$ cat test.cpp
template struct __declspec(dllexport) Foo {
void f() { T::bar(); }
};
void x() {
Foo a;
}

$ cl -c test.cpp

$ clang-cl -c test.cpp
test.cpp(2,14) : error: type 'int' cannot be used prior to '::' because it has no members
void f() { T::bar(); }
^
test.cpp(1,49) : note: in instantiation of member function 'Foo::f' requested here
template struct __declspec(dllexport) Foo {
^
1 error generated.

@ehsan
Copy link
Contributor Author

ehsan commented Jul 3, 2014

If this is a relatively straightforward fix, I'd like to help fix it if someone can point me in the right direction. This bug hits us when building skia as a DLL, and it's preventing the last significant chunk of the tree with clang-cl.

Thanks!

@majnemer
Copy link
Mannequin

majnemer mannequin commented Jul 3, 2014

This is a pretty wild deviation from the standard, can the source code in skia be fixed instead?

@ehsan
Copy link
Contributor Author

ehsan commented Jul 3, 2014

This is a pretty wild deviation from the standard, can the source code in
skia be fixed instead?

The issue is in SkTDArray. This class has four members https://skia.googlesource.com/skia/+/master/include/core/SkTDArray.h#292 deleteAll, freeAll, unrefAll and safeUnrefAll which iterate over the contents of the array and delete it in various ways. I can't think of a way to fix this without breaking the interface contract of the class by basically removing those four functions. But a workaround would be to not dllexport this class in the first place. I've submitted a patch upstream for that: https://codereview.chromium.org/368253002/

@rnk
Copy link
Collaborator

rnk commented Jul 4, 2014

This is a pretty wild deviation from the standard, can the source code in
skia be fixed instead?

The issue is in SkTDArray. This class has four members
https://skia.googlesource.com/skia/+/master/include/core/SkTDArray.h#292
deleteAll, freeAll, unrefAll and safeUnrefAll which iterate over the
contents of the array and delete it in various ways. I can't think of a way
to fix this without breaking the interface contract of the class by
basically removing those four functions. But a workaround would be to not
dllexport this class in the first place. I've submitted a patch upstream
for that: https://codereview.chromium.org/368253002/

Why do they even put SK_API on a template class? We should probably just ask them to remove it. I wonder why we haven't hit this in Chrome already.

That SK_API usage dates back to the initial Windows DLL support in 2011:
https://skia.googlesource.com/skia/+/7ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577

It's probably unnecessary.

@ehsan
Copy link
Contributor Author

ehsan commented Jul 4, 2014

This is a pretty wild deviation from the standard, can the source code in
skia be fixed instead?

The issue is in SkTDArray. This class has four members
https://skia.googlesource.com/skia/+/master/include/core/SkTDArray.h#292
deleteAll, freeAll, unrefAll and safeUnrefAll which iterate over the
contents of the array and delete it in various ways. I can't think of a way
to fix this without breaking the interface contract of the class by
basically removing those four functions. But a workaround would be to not
dllexport this class in the first place. I've submitted a patch upstream
for that: https://codereview.chromium.org/368253002/

Why do they even put SK_API on a template class?

Unclear to me. As you note, looking at the history of that code, SK_API seems to have been added to that class alongside some others, so perhaps that's not intentional.

We should probably just ask them to remove it.

Yes, that is what my patch does.

I wonder why we haven't hit this in Chrome already.

In our builds, we link Skia in a library separate from the rest of our graphics code, so we need to define SKIA_DLL when building this code which makes SK_API map to __declspec(dllexport), so we end up exporting this class. But I think Chrome links this code into the mail DLL so there is no need to export the template, and then everything will work out fine as it should based on C++ (i.e., those methods do not even get instantiated.)

That SK_API usage dates back to the initial Windows DLL support in 2011:
https://skia.googlesource.com/skia/+/7ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577

It's probably unnecessary.

Yep, I'll get back to you once I've heard back on my patch in Skia, hopefully someone will review it soon.

@rnk
Copy link
Collaborator

rnk commented Jul 7, 2014

This is a pretty wild deviation from the standard, can the source code in
skia be fixed instead?

According to Richard, the Skia code is totally valid. We should fix this in Clang.

@ehsan
Copy link
Contributor Author

ehsan commented Jul 7, 2014

This is a pretty wild deviation from the standard, can the source code in
skia be fixed instead?

According to Richard, the Skia code is totally valid. We should fix this in
Clang.

Hmm, my patch is in the process of getting upstreamed... Is that not sufficient?

@rnk
Copy link
Collaborator

rnk commented Jul 7, 2014

Hmm, my patch is in the process of getting upstreamed... Is that not
sufficient?

Your skia patch is fine, because it makes no sense to have dllexport on a primary class template.

I think we should also fix this in clang, because the skia code as it was written is valid C++. dllexport shouldn't break that.

@ehsan
Copy link
Contributor Author

ehsan commented Jul 7, 2014

Hmm, my patch is in the process of getting upstreamed... Is that not
sufficient?

Your skia patch is fine, because it makes no sense to have dllexport on a
primary class template.

Agreed.

I think we should also fix this in clang, because the skia code as it was
written is valid C++. dllexport shouldn't break that.

Do you mean something along the lines of instantiating the template members and only export them if the instantiation succeeds? This sounds good to me.

@zmodem
Copy link
Collaborator

zmodem commented Aug 20, 2014

Another example of this: https://codereview.chromium.org/485323002/

I think we should also fix this in clang, because the skia code as it was
written is valid C++. dllexport shouldn't break that.

Do you mean something along the lines of instantiating the template members
and only export them if the instantiation succeeds? This sounds good to me.

I think we just shouldn't instantiate class template members eagerly like we do now. I've started looking.

@zmodem
Copy link
Collaborator

zmodem commented Aug 21, 2014

Should be fixed in r216145.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 9, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla clang:frontend Language frontend issues, e.g. anything involving "Sema"
Projects
None yet
Development

No branches or pull requests

3 participants