[llvm-dev] [UPDATE] Disabling inline compilation (Clang with VS2019)

Reid Kleckner via llvm-dev
Mon, 06 Dec 2021 18:37:45 -0000

Thanks for asking about the rules. I think, at the moment, we should leave
clang's dllimport+inline heuristics alone, but we should at least document
our behavior, perhaps in AttributeReference.html
<https://clang.llvm.org/docs/AttributeReference.html>.

On Fri, Dec 3, 2021 at 8:21 AM John Emmas via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Just an update to a long gone thread....
>
> Back in September I flagged up some problematic code which was building
> fine with MSVC but failing to link when built with Visual Studio and Clang.
> In the end, it turned out to be a typo at my end but along the way we
> discovered a difference in the way that MSVC and Clang will each treat
> functions declared using '__declspec(dllimport) '  Basically, Clang
was
> sometimes trying to inline them when MSVC wasn't (I've added the
relevant
> part of the discussion below...)
>
> The devs here said they'd be happy to make Clang's behaviour match
MSVC
> but that it was traditionally hard to find out what Visual Studio's
'rules'
> are.  So I posted a question on the VS developer forum - and 3 months
> later, Microsoft's own devs have finally replied:-
>
>
>
https://developercommunity.visualstudio.com/t/__declspecdllimport-and-inline-abili/1537756#T-ND1602459
>
> I know it's ancient history now but given that the situation's been
> clarified at last, I figured I might as well feed it back here.  Basically,
> although the rules can change over time, currently (for dllimport
> functions) MSVC carries out 2 simple tests when deciding whether or not
> they can be candidates for inlining:-
>
>     1) the MSVC optimizer won't inline a candidate if that candidate
calls
> some other function - and/or
>
>     2) the MSVC optimizer won't inline a candidate if that candidate
> accesses a global variable
>
> For class variables, a static member is treated as being a global variable.
>
> Like I said, I know it's all a long gone problem but I figured
Microsoft's
> reply would be worth flagging up.  Hope it all helps,
>
> John
>
>
> On 22/09/2021 13:53, Eric Astor wrote:
>
> I've transferred John's example into Compiler Explorer, which will
> hopefully be a useful demonstration. Both clang and MSVC handle the
> dllexport case identically... but they do differ in the dllimport case:
> https://godbolt.org/z/vTrEevY8o
>
> Just as John suggested, disassembling the output shows that clang is
> inlining this function, even at -O1, where MSVC doesn't, even at /O3.
>
> I'd agree that this isn't a great match, though it *is* a point of
> ambiguity in the handling of __declspec(dllimport).
>
>
> On 22/09/2021 13:22, John Emmas wrote:
>>
>> Hi there - I first asked this question over on clang-users but I got
>> advised to ask it here (sorry about the length...)
>>
>> I'm a VS2019 user and I've been trying to switch it here to use
Clang as
>> the compiler, rather than MSVC. But I seem to have hit a common
problem.
>> Consider the following code:-
>>
>> #if defined (BUILDING_DLL)
>>   #define DLL_API __declspec(dllexport)
>> #else
>>   #define DLL_API __declspec(dllimport)
>> #endif
>>
>> namespace Gtkmm2ext {
>>
>>   class DLL_API Keyboard
>>   {
>>     public:
>>       Keyboard ();
>>       ~Keyboard ();
>>
>>       static Keyboard& get_keyboard() { return *_the_keyboard; }
>>
>>     protected:
>>       static Keyboard* _the_keyboard;
>>   };
>>
>> } /* namespace */
>>
>> The above code is from a DLL which gets used by an exe.  The DLL
compiles
>> and links just fine and the exe compiles.  But when I try to link the
exe,
>> Clang's linker complains that it can't find
'_the_keyboard'
>>
>> But here's the thing... '_the_keyboard' is an internal
variable that's
>> private to the DLL. It should never need to get accessed by the exe.
If I
>> change 'get_keyboard()' to be just a declaration (and then
implement it in
>> a DLL source file) Clang is then happy - but unfortunately, this is one
of
>> several hundred similar linker errors.
>>
>> So I'm wondering if (maybe) the compiler implemented its call to
>> 'get_keyboard()' as inline code, rather than importing it from
the DLL?
>> Maybe for very simple code like this, Clang is trying to be clever and
>> implement stuff inline if it can?
>>
>> VS2019 can disable inline code via a compiler option called
"/Ob0" - and
>> typing "clang-cl /?" indicates that "/Ob0" is
supported.   But I still see
>> the error, even if I specify "/Ob0" during compilation.
>>
>> So will "/Ob0" disable all inline compilation for Clang?  Or
does it only
>> take effect where there's an actual 'inline' keyword?  Hope
that all makes
>> sense...
>>
>> John
>>
>>
>>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20211206/b7119314/attachment-0001.html>