LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 41018 - dllimport conflicts with exclude_from_explicit_instantiation.
Summary: dllimport conflicts with exclude_from_explicit_instantiation.
Status: CONFIRMED
Alias: None
Product: clang
Classification: Unclassified
Component: C++ (show other bugs)
Version: trunk
Hardware: PC All
: P normal
Assignee: Hans Wennborg
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-03-08 17:06 PST by Eric Fiselier
Modified: 2019-11-26 11:21 PST (History)
9 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Fiselier 2019-03-08 17:06:21 PST
When both dllimport and exclude_from_explicit_instantiation are passed, Clang still expects the function to have a externally available definition. But this is not the case.

For example: https://godbolt.org/z/gKOHCk

This leads to linker errors because of undefined symbols.

I think one approach would be to make Clang not inherit `dllimport` attributes on functions declared with exclude_from_explicit_instantiation. When dllimport is applied directly, we could emit an error for incompatible attributes.
Comment 1 Reid Kleckner 2019-03-11 16:06:41 PDT
Basically, we have two things that say the function will be externally available, one from the language (extern template) and one extension (dllimport), and then we have our own, new extension (exclude_from_expicit_instantiation), which says the opposite. I guess the "negative" available_externally attribute should win, since it only exists to say that an inline function is *not* available_externally.

I wonder if it makes sense to extend this attribute to work in non-template cases, consider:

class EXPORT Foo {
  // Too many methods to individually annotate with EXPORT:
  void baz00();
  void baz01();
  ...
  void baz99();

  // One inline method that I don't want to export, for whatever reason:
  int __attribute__((exclude_from_explicit_instantiation)) bar() {
    return 42;
  }
};

Obviously, the spelling "exclude_from_explicit_instantiation" doesn't make any sense, but what's really been created here is an available_externally-blocker attribute.

The same effect can also be achieved with clang-cl /Zc:dllExportInlines-, by the way: http://blog.llvm.org/2018/11/30-faster-windows-builds-with-clang-cl_14.html

Speculatively assigning to Hans since he supervised /Zc:dllExportInlines-.
Comment 2 Reid Kleckner 2019-03-11 16:14:18 PDT
+Louis, since he added the attribute.
Comment 3 Hans Wennborg 2019-03-12 06:23:27 PDT
(In reply to Reid Kleckner from comment #2)
> +Louis, since he added the attribute.

(For anyone looking, that was r343790.)



(In reply to Eric Fiselier from comment #0)
> I think one approach would be to make Clang not inherit `dllimport`
> attributes on functions declared with exclude_from_explicit_instantiation.
> When dllimport is applied directly, we could emit an error for incompatible
> attributes.

That sounds reasonable to me.
Comment 4 Nico Weber 2019-03-15 12:06:10 PDT
ldionne, as author of exclude_from_explicit_instantiation could you take a look? libc++ currently needs to carry a workaround for this.
Comment 5 Nico Weber 2019-11-20 11:54:14 PST
libc++ will need another workaround for this for https://bugs.chromium.org/p/chromium/issues/detail?id=923166#c44
Comment 6 Reid Kleckner 2019-11-20 16:01:48 PST
Separately from what clang should do, does Chromium use the libc++ ABI unstable macros? Can it?

If so, I would think that the "unstable ABI" build shouldn't use the exclude_from_explicit_instantiation attributes, since I believe those are only needed to stabilize the ABI.
Comment 7 Nico Weber 2019-11-26 11:21:48 PST
Yes, Chromium sets _LIBCPP_ABI_UNSTABLE (except, for now, in branded CrOS builds, but that's hopefully temporary).

That sounds like a good idea to me.

(Having said that, updating libc++ in Chromium is a bit of a mess atm, so a compiler-side fix might still help Chromium earlier even if we implemented that suggestion for libc++ very soon and the compiler fix a bit later.)