From c254e9fd75d9ca9feb3b2480691039a09fe03965 Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Wed, 8 Oct 2025 19:01:11 +0200 Subject: [PATCH] C++ interop: Correctly report the unsupported param type when using explicit object param (#6179) This fixes a bug, which seems to have been introduced in #6108. In the new test, without this change, we will diagnose with ``` error: semantics TODO: `Unsupported: parameter type: ExplicitObjectParam` [SemanticsTodo] ``` --- toolchain/check/cpp/import.cpp | 14 ++++++-------- .../testdata/interop/cpp/class/method.carbon | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/toolchain/check/cpp/import.cpp b/toolchain/check/cpp/import.cpp index c33688393a2c..b50c1fe0c5dd 100644 --- a/toolchain/check/cpp/import.cpp +++ b/toolchain/check/cpp/import.cpp @@ -1365,14 +1365,13 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id, clang_decl.getType()->castAs(); for (int i : llvm::seq(num_params)) { const auto* param = clang_decl.getNonObjectParameter(i); + clang::QualType orig_param_type = function_type->getParamType( + clang_decl.hasCXXExplicitFunctionObjectParameter() + i); + // The parameter type is decayed but hasn't necessarily had its qualifiers // removed. // TODO: The presence of qualifiers here is probably a Clang bug. - clang::QualType param_type = - function_type - ->getParamType(clang_decl.hasCXXExplicitFunctionObjectParameter() + - i) - .getUnqualifiedType(); + clang::QualType param_type = orig_param_type.getUnqualifiedType(); // We map `T&` parameters to `addr param: T*`, and `T&&` parameters to // `param: T`. @@ -1391,9 +1390,8 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id, EndSubpatternAsExpr(context, orig_type_inst_id); if (!type_id.has_value()) { - context.TODO(loc_id, - llvm::formatv("Unsupported: parameter type: {0}", - function_type->getParamType(i).getAsString())); + context.TODO(loc_id, llvm::formatv("Unsupported: parameter type: {0}", + orig_param_type.getAsString())); return SemIR::InstBlockId::None; } diff --git a/toolchain/check/testdata/interop/cpp/class/method.carbon b/toolchain/check/testdata/interop/cpp/class/method.carbon index 30e98c06e100..e8c938447154 100644 --- a/toolchain/check/testdata/interop/cpp/class/method.carbon +++ b/toolchain/check/testdata/interop/cpp/class/method.carbon @@ -176,6 +176,24 @@ fn Call(e: Cpp.ExplicitObjectParam, n: i32, a: Cpp.Another) { //@dump-sem-ir-end } +// --- fail_call_explicit_object_param_with_unsupported_type_param.carbon + +library "[[@TEST_NAME]]"; + +import Cpp inline ''' +struct ExplicitObjectParam { + void F(this ExplicitObjectParam, _BitInt(23) x); +}; +'''; + +fn Call(e: Cpp.ExplicitObjectParam) { + // CHECK:STDERR: fail_call_explicit_object_param_with_unsupported_type_param.carbon:[[@LINE+4]]:3: error: semantics TODO: `Unsupported: parameter type: _BitInt(23)` [SemanticsTodo] + // CHECK:STDERR: e.(Cpp.ExplicitObjectParam.F)(1); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + e.(Cpp.ExplicitObjectParam.F)(1); +} + // --- explicit_object_param_overloaded.h struct Another {