swiftlang / swift-corelibs-foundation

The Foundation Project, providing core utilities, internationalization, and OS independence
swift.org
Apache License 2.0
5.29k stars 1.13k forks source link

__CFAllocatorRespectsHintZeroWhenAllocating not consistently declared extern C #5125

Closed lhoward closed 3 weeks ago

lhoward commented 3 weeks ago

when ForFoundationOnly.h and ForSwiftFoundationOnly.h end up being imported, compile fails due to different linkage of __CFAllocatorRespectsHintZeroWhenAllocating().

suggest removing it from ForFoundationOnly.h or adding CF_PRIVATE.

<module-includes>:1:10: note: in file included from <module-includes>:1:
1 | #include "CoreFoundation.h"
  |          `- note: in file included from <module-includes>:1:
2 | 

/opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/CoreFoundation/CoreFoundation.h:77:10: note: in file included from /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/CoreFoundation/CoreFoundation.h:77:
 75 | #include "CFConstantKeys.h"
 76 | 
 77 | #include "ForSwiftFoundationOnly.h"
    |          `- note: in file included from /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/CoreFoundation/CoreFoundation.h:77:
 78 | 
 79 | #if TARGET_OS_OSX || TARGET_OS_IPHONE || TARGET_OS_WIN32 || TARGET_OS_LINUX

<unknown>:0: error: could not build C module 'CoreFoundation'
/opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/CoreFoundation/ForSwiftFoundationOnly.h:108:20: error: declaration of '__CFAllocatorRespectsHintZeroWhenAllocating' has a different language linkage
106 | _CF_EXPORT_SCOPE_BEGIN
107 | 
108 | CF_PRIVATE Boolean __CFAllocatorRespectsHintZeroWhenAllocating(CFAllocatorRef _Nullable allocator);
    |                    `- error: declaration of '__CFAllocatorRespectsHintZeroWhenAllocating' has a different language linkage
109 | 
110 | struct __CFSwiftObject {

/opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/CoreFoundation/ForFoundationOnly.h:71:9: note: previous declaration is here
 69 | #endif
 70 | 
 71 | Boolean __CFAllocatorRespectsHintZeroWhenAllocating(CFAllocatorRef _Nullable allocator);
    |         `- note: previous declaration is here
 72 | typedef CF_ENUM(CFOptionFlags, _CFAllocatorHint) {
 73 |     _CFAllocatorHintZeroWhenAllocating = 1
lhoward commented 3 weeks ago

Hmm, still seeing this when adding CF_PRIVATE to ForFoundationOnly.h for reasons I haven't yet determined (although if CF_PRIVATE is already defined, ForSwiftFoundationOnly.h won't define it, so that could be it).

Is there a reason it needs to be in ForFoundationOnly.h?

parkera commented 3 weeks ago

It is there for historical reasons. We can move it to CFInternal.h and make it CF_PRIVATE.

parkera commented 3 weeks ago

@lhoward are you saying this is new to 6.0.2 (vs 6.0)?

lhoward commented 3 weeks ago

@lhoward are you saying this is new to 6.0.2 (vs 6.0)?

I am, although it doesn't really make sense (given the prototype in ForFoundationOnly.h was committed in 2021). I'll try to find out the real reason.

Edit: seeing this on 6.0 as well now.

lhoward commented 3 weeks ago

I can't easily explain why it's just started happening with one particular package I'm trying to build.

But from first principles it seems that this always should have raised an error:

The only reasons I can think of as to why this didn't raise an error by default:

lhoward commented 3 weeks ago

Actually, it's nothing to do with the visibility attribute. The issue is that __CFAllocatorRespectsHintZeroWhenAllocating in ForFoundationOnly.h is not within extern "C" (via _CF_EXPORT_SCOPE_BEGIN).

Moving __CFAllocatorRespectsHintZeroWhenAllocating after _CF_EXPORT_SCOPE_BEGIN in ForFoundationOnly.h also fixes it. Of course #5126 looks like a better fix.

Why did I only see this now? Perhaps it was there all along since Swift 6 and something has changed WRT C++ interoperability (which I am using)?

parkera commented 3 weeks ago

It makes sense that this could have started in 6.0 vs 6.0.2. Thanks for the investigation.

lhoward commented 3 weeks ago

Tangential: __CFSafelyReallocate() and __CFSafelyReallocateWithAllocator() are also declare with incorrect (but not conflicting) linkage when imported as C++. Suggest wrapping them in _CF_EXPORT_SCOPE_BEGIN/END.

parkera commented 2 weeks ago

Let's file a new bug/get a new PR for reallocate ones.