From 95cf518be438f67969a2aa9e43a1866a54789b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Mon, 1 Sep 2025 20:39:37 +0100 Subject: [PATCH] [6.2][cxx-interop] Do not consider function types fragile Explanationion: Function pointer types wee always considered fragile in C++ mode, this manifested as a regression when interfacing with glibc. Issues: rdar://159184118 Original PRs: #84040 Risk: Low, this only removes a spurious error for library evolution. Testing: Added a compiler test. Reviewers: @egorzhdan --- lib/Sema/TypeCheckAccess.cpp | 10 ++++++++++ .../allow-c-in-cxx-mode-in-evolving-libraries.swift | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index 067ccc28945d6..012a9f88dedaf 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -32,6 +32,7 @@ #include "swift/Basic/Assertions.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/Type.h" using namespace swift; @@ -1862,6 +1863,15 @@ bool isFragileClangType(clang::QualType type) { // Builtin clang types are compatible with library evolution. if (underlyingTypePtr->isBuiltinType()) return false; + if (const auto *ft = dyn_cast(underlyingTypePtr)) { + if (const auto *fpt = + dyn_cast(underlyingTypePtr)) { + for (auto paramTy : fpt->getParamTypes()) + if (isFragileClangType(paramTy)) + return true; + } + return isFragileClangType(ft->getReturnType()); + } // Pointers to non-fragile types are non-fragile. if (underlyingTypePtr->isPointerType()) return isFragileClangType(underlyingTypePtr->getPointeeType()); diff --git a/test/Interop/Cxx/library-evolution/allow-c-in-cxx-mode-in-evolving-libraries.swift b/test/Interop/Cxx/library-evolution/allow-c-in-cxx-mode-in-evolving-libraries.swift index 963998d3f6b9b..db4ca84e4ca8e 100644 --- a/test/Interop/Cxx/library-evolution/allow-c-in-cxx-mode-in-evolving-libraries.swift +++ b/test/Interop/Cxx/library-evolution/allow-c-in-cxx-mode-in-evolving-libraries.swift @@ -39,6 +39,9 @@ struct CStruct { } #endif +typedef void (*my_sighandler_t)(int); +typedef void (*my_other_cb)(CxxStruct); + //--- test.swift import CxxModule @@ -55,3 +58,9 @@ public func useCxxEnum(_ x: CxxEnum) { // expected-error {{cannot use enum 'CxxE // expected-error@+1 {{cannot use struct 'CxxStruct' here; C++ types from imported module 'CxxModule' do not support library evolution}} public func usesCxxStruct(_ x: CxxStruct) { } + +public func usesTypeAliasToFuncPtr(_ x: my_sighandler_t) { +} + +public func usesTypeAliasToFuncPtr2(_ x: my_other_cb) { // expected-error {{cannot use type alias 'my_other_cb' here; C++ types from imported module 'CxxModule' do not support library evolution}} +}