swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.33k stars 10.34k forks source link

[SR-14964] [C++-Interop] crash with deserialization of 'ReferenceConvertible' with ObjC & C++ Interop enabled #57306

Open swift-ci opened 3 years ago

swift-ci commented 3 years ago
Previous ID SR-14964
Radar rdar://problem/83361941
Original Reporter plotfi (JIRA User)
Type Sub-task
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | | |Labels | Sub-task, CxxInterop | |Assignee | None | |Priority | Medium | md5: f98f95ad8507497363af125ad59fbc18

Parent-Task:

Issue Description:

In some cases (When enabling objc and C++ Interop with -enable-cxx-interop -enable-objc-interop) it can be possible to cause the swift compiler to crash on clang import when using operator==. The repro is below, but it is worth noting that there is no crash if either the `let eq = (a == b)` line is removed or if the `import Foundation` line is removed. If either are removed there is simply a compile error (most likely because the types for the rhs are currently `rhs: UnsafePointer\<S>` while the type or the lhs is `inout S`.

C++ (header):

// Module MyModule (MyModule.h)
struct S { bool operator==(const S& rhs) const; };

Swift:

import Foundation // NOTE: If this line is removed there is no crash.
import MyModule
let a = S()
let b = S()
let eq = (a == b)

Module Map:

module MyModule {
  header "MyModule.h"
  requires cplusplus
  export *
}

Stack Trace:

<unknown>:0: error: fatal error encountered while reading from module 'Foundation';

*** DESERIALIZATION FAILURE (please include this section in any bug report) *** could not deserialize type for 'ReferenceConvertible': result is ambiguous Cross-reference to module 'ObjectiveC' ... NSObject
...
abort + 104
swift::ModuleFileSharedCore::~ModuleFileSharedCore() + 0
swift::ModuleFile::readParameterList() + 0

It is also worth noting that before the crash there is a lengthy compile error as well, but it is not related to the inout versus UnsafePointer issue:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.5.sdk/usr/include/c++/v1/memory:1603:25: error: no member named 'select_on_container_copy_construction' in 'std::__1::allocator<char>' 

Also, here's the output of the ide tool for the above C++ header:

struct S {
  init()
  static func == (lhs: inout S, rhs: UnsafePointer<S>) -> Bool
}
static func == (lhs: inout S, rhs: UnsafePointer<S>) -> Bool

Command Line (module map and header file are in include dir):

swift -frontend -S -emit-ir -disable-implicit-concurrency-module-import \
    -enable-cxx-interop -enable-objc-interop \
    -target arm64-apple-ios14.5 -target-sdk-version 14.5 \
    -I include main.swift \
    -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.5.sdk
zoecarver commented 3 years ago

@swift-ci create