mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 08:11:04 +01:00
Import non-const rvalue references as var parameters. (#7125)
When importing a C++ function with an rvalue reference parameter, we previously produced a Carbon value parameter. This would lead to the toolchain believing it could pass the address of a non-expiring object to the function, which would lead to a use-after-move. Instead, we now map non-const rvalue reference parameters to Carbon `var` parameters. This forces the object passed into C++ to be unique and owned by the call. While that's not an exact match for C++ rvalue reference parameters, given that it provides "always move" not "conditionally move", it's the closest match we have at the moment.
This commit is contained in:
@@ -185,7 +185,6 @@ fn Call() {
|
||||
// CHECK:STDOUT: %X.B.cpp_overload_set.type: type = cpp_overload_set_type @X.B.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %X.B.cpp_overload_set.value: %X.B.cpp_overload_set.type = cpp_overload_set_value @X.B.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %bound_method.a5d: <bound method> = bound_method %.3af, %X.B.cpp_overload_set.value [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.46b: type = pattern_type %X [concrete]
|
||||
// CHECK:STDOUT: %X.B.type: type = fn_type @X.B [concrete]
|
||||
// CHECK:STDOUT: %X.B: %X.B.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %X.C.cpp_overload_set.type: type = cpp_overload_set_type @X.C.cpp_overload_set [concrete]
|
||||
@@ -226,12 +225,8 @@ fn Call() {
|
||||
// CHECK:STDOUT: %X.decl: type = class_decl @X [concrete = constants.%X] {} {}
|
||||
// CHECK:STDOUT: %X.B.cpp_overload_set.value: %X.B.cpp_overload_set.type = cpp_overload_set_value @X.B.cpp_overload_set [concrete = constants.%X.B.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %X.B.decl: %X.B.type = fn_decl @X.B [concrete = constants.%X.B] {
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.46b = ref_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.46b = at_binding_pattern self, %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
|
||||
// CHECK:STDOUT: %self: ref %X = ref_binding self, %self.param
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %X.C.cpp_overload_set.value: %X.C.cpp_overload_set.type = cpp_overload_set_value @X.C.cpp_overload_set [concrete = constants.%X.C.cpp_overload_set.value]
|
||||
@@ -247,11 +242,9 @@ fn Call() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %X.cpp_destructor.decl: %X.cpp_destructor.type = fn_decl @X.cpp_destructor [concrete = constants.%X.cpp_destructor] {
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.46b = ref_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.46b = at_binding_pattern self, %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
|
||||
// CHECK:STDOUT: %self: ref %X = ref_binding self, %self.param
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -865,7 +858,6 @@ fn Call() {
|
||||
// CHECK:STDOUT: %X.D.cpp_overload_set.type: type = cpp_overload_set_type @X.D.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %X.D.cpp_overload_set.value: %X.D.cpp_overload_set.type = cpp_overload_set_value @X.D.cpp_overload_set [concrete]
|
||||
// CHECK:STDOUT: %bound_method.d5c: <bound method> = bound_method %.3af, %X.D.cpp_overload_set.value [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.46b: type = pattern_type %X [concrete]
|
||||
// CHECK:STDOUT: %X.cpp_destructor.type: type = fn_type @X.cpp_destructor [concrete]
|
||||
// CHECK:STDOUT: %X.cpp_destructor: %X.cpp_destructor.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -884,11 +876,9 @@ fn Call() {
|
||||
// CHECK:STDOUT: %X.C.cpp_overload_set.value: %X.C.cpp_overload_set.type = cpp_overload_set_value @X.C.cpp_overload_set [concrete = constants.%X.C.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %X.D.cpp_overload_set.value: %X.D.cpp_overload_set.type = cpp_overload_set_value @X.D.cpp_overload_set [concrete = constants.%X.D.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %X.cpp_destructor.decl: %X.cpp_destructor.type = fn_decl @X.cpp_destructor [concrete = constants.%X.cpp_destructor] {
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.46b = ref_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.46b = at_binding_pattern self, %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
|
||||
// CHECK:STDOUT: %self: ref %X = ref_binding self, %self.param
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -532,7 +532,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
|
||||
// CHECK:STDOUT: %TakesRValue__carbon_thunk.type: type = fn_type @TakesRValue__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %TakesRValue__carbon_thunk: %TakesRValue__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %.6ef: ref %S = temporary invalid, %S.val [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -557,13 +556,11 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc8_20.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_25: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
|
||||
// CHECK:STDOUT: %.loc8_20.2: ref %S = temporary_storage
|
||||
// CHECK:STDOUT: %.loc8_20.3: init %S to %.loc8_20.2 = class_init () [concrete = constants.%S.val]
|
||||
// CHECK:STDOUT: %.loc8_22.1: init %S = converted %.loc8_20.1, %.loc8_20.3 [concrete = constants.%S.val]
|
||||
// CHECK:STDOUT: %.loc8_22.2: ref %S = temporary %.loc8_20.2, %.loc8_22.1 [concrete = constants.%.6ef]
|
||||
// CHECK:STDOUT: %.loc8_22.3: %S = acquire_value %.loc8_22.2 [concrete = constants.%S.val]
|
||||
// CHECK:STDOUT: %.loc8_22.4: ref %S = value_as_ref %.loc8_22.3
|
||||
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_22.4
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %.loc8_20.2: init %S to %_.var = class_init () [concrete = constants.%S.val]
|
||||
// CHECK:STDOUT: %.loc8_22: init %S = converted %.loc8_20.1, %.loc8_20.2 [concrete = constants.%S.val]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %_.var
|
||||
// CHECK:STDOUT: %TakesRValue__carbon_thunk.call: init %empty_tuple.type = call imports.%TakesRValue__carbon_thunk.decl(%addr)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
Reference in New Issue
Block a user