diff --git a/lib/ClangImporter/SwiftDeclSynthesizer.cpp b/lib/ClangImporter/SwiftDeclSynthesizer.cpp index 7ae73a79977a2..c739887820567 100644 --- a/lib/ClangImporter/SwiftDeclSynthesizer.cpp +++ b/lib/ClangImporter/SwiftDeclSynthesizer.cpp @@ -522,6 +522,8 @@ SwiftDeclSynthesizer::createDefaultConstructor(NominalTypeDecl *structDecl) { // Mark the constructor transparent so that we inline it away completely. constructor->getAttrs().add(new (context) TransparentAttr(/*implicit*/ true)); + constructor->setSynthesized(); + constructor->setBodySynthesizer(synthesizeStructDefaultConstructorBody, structDecl); @@ -652,6 +654,8 @@ ConstructorDecl *SwiftDeclSynthesizer::createValueConstructor( // Make the constructor transparent so we inline it away completely. constructor->getAttrs().add(new (context) TransparentAttr(/*implicit*/ true)); + constructor->setSynthesized(); + if (wantBody) { auto memberMemory = context.AllocateUninitialized(members.size() + 1); @@ -1294,6 +1298,7 @@ SwiftDeclSynthesizer::makeEnumRawValueConstructor(EnumDecl *enumDecl) { /*ThrownType=*/TypeLoc(), paramPL, /*GenericParams=*/nullptr, enumDecl); ctorDecl->setImplicit(); + ctorDecl->setSynthesized(); ctorDecl->copyFormalAccessFrom(enumDecl); ctorDecl->setBodySynthesizer(synthesizeEnumRawValueConstructorBody, enumDecl); return ctorDecl; diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 95784054690d7..5d91692fb0f3c 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -4437,7 +4437,22 @@ bool ConstraintSystem::isArgumentOfImportedDecl( return false; auto *choice = overload->choice.getDecl(); - return choice->hasClangNode(); + + // Imported declaration. + if (choice->hasClangNode()) + return true; + + // Implicit declaration synthesized by the compiler. + // Such declarations don't have clang nodes backing + // them but for the purposes of this check we consider + // them imported if the parent is. + if (choice->isSynthesized()) { + auto *dc = choice->getDeclContext(); + if (auto *parent = dc->getAsDecl()) + return parent->hasClangNode(); + } + + return false; } ConversionEphemeralness diff --git a/test/Constraints/swift_to_c_pointer_conversions_in_synthesized.swift b/test/Constraints/swift_to_c_pointer_conversions_in_synthesized.swift new file mode 100644 index 0000000000000..ea7beb45044f6 --- /dev/null +++ b/test/Constraints/swift_to_c_pointer_conversions_in_synthesized.swift @@ -0,0 +1,21 @@ +// RUN: %empty-directory(%t/src) +// RUN: %empty-directory(%t/sdk) +// RUN: split-file %s %t/src + +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %t/src/main.swift \ +// RUN: -import-objc-header %t/src/Test.h \ +// RUN: -module-name main -I %t -verify + +// REQUIRES: objc_interop + +//--- Test.h +#include + +typedef struct { + uint8_t* buffer; +} frame_t __attribute__((swift_name("Frame"))); + +//--- main.swift +func test(rawPointer: UnsafeMutableRawPointer) { + _ = Frame(buffer: rawPointer) // Ok (even though init is synthesized the type is imported) +}