Skip to content

Commit 0fff0cf

Browse files
author
Gabor Horvath
committed
[cxx-interop] Fix import virtual methods with rvalue ref params
We generate forwarding calls for virutal methods. These forwarding calls had a type error when the original parameter had an rvalue reference type. In those scenarios we need to insert a static cast to make the type checker happy. rdar://154969620
1 parent a47d392 commit 0fff0cf

File tree

4 files changed

+45
-5
lines changed

4 files changed

+45
-5
lines changed

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,11 +2176,18 @@ clang::CXXMethodDecl *SwiftDeclSynthesizer::synthesizeCXXForwardingMethod(
21762176
for (size_t i = 0; i < newMethod->getNumParams(); ++i) {
21772177
auto *param = newMethod->getParamDecl(i);
21782178
auto type = param->getType();
2179-
if (type->isReferenceType())
2180-
type = type->getPointeeType();
2181-
args.push_back(new (clangCtx) clang::DeclRefExpr(
2182-
clangCtx, param, false, type, clang::ExprValueKind::VK_LValue,
2183-
clang::SourceLocation()));
2179+
clang::Expr *argExpr = new (clangCtx) clang::DeclRefExpr(
2180+
clangCtx, param, false, type.getNonReferenceType(),
2181+
clang::ExprValueKind::VK_LValue, clang::SourceLocation());
2182+
if (type->isRValueReferenceType()) {
2183+
argExpr = clangSema
2184+
.BuildCXXNamedCast(
2185+
clang::SourceLocation(), clang::tok::kw_static_cast,
2186+
clangCtx.getTrivialTypeSourceInfo(type), argExpr,
2187+
clang::SourceRange(), clang::SourceRange())
2188+
.get();
2189+
}
2190+
args.push_back(argExpr);
21842191
}
21852192
auto memberCall = clangSema.BuildCallExpr(
21862193
nullptr, memberExpr, clang::SourceLocation(), args,

test/Interop/Cxx/reference/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ module ConstRefCxxObjCCtorInitParameter {
2424
requires objc
2525
requires cplusplus
2626
}
27+
28+
module VirtMethodWithRvalRef {
29+
header "virtual-methods-with-rvalue-reference.h"
30+
requires cplusplus
31+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
#include "swift/bridging"
4+
5+
class CxxForeignRef;
6+
7+
void retain(CxxForeignRef * obj);
8+
void release(CxxForeignRef * obj);
9+
10+
struct NonTrivial {
11+
~NonTrivial();
12+
};
13+
14+
class CxxForeignRef {
15+
public:
16+
CxxForeignRef(const CxxForeignRef &) = delete;
17+
CxxForeignRef() = default;
18+
19+
virtual void takesRValRef(NonTrivial&&);
20+
} SWIFT_SHARED_REFERENCE(retain, release);
21+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-swift-frontend -typecheck -verify -I %S/Inputs -I %swift_src_root/lib/ClangImporter/SwiftBridging %s -cxx-interoperability-mode=default -disable-availability-checking
2+
3+
import VirtMethodWithRvalRef
4+
5+
func f(_ x: CxxForeignRef, _ y: NonTrivial) {
6+
x.takesRValRef(consuming: y)
7+
}

0 commit comments

Comments
 (0)