Unify "needs thunk" logic. (#6277)

Remove duplication between determining whether a parameter needs custom
thunk mapping and whether a function needs a thunk. Now a function needs
a thunk if any parameter or the return type does.

This fixes some inconsistencies; previously:
- We would not require a thunk when passing an `unsigned int`, but if we
  had a thunk we'd pass `unsigned int` indirectly.
- We would always require a thunk for an enum parameter, even though
  we'd actually pass it directly if its underlying type is a 32- or
  64-bit integer.
- We would require a thunk for a nullable pointer, even though
  we arrange for all pointer types to have the same ABI in Carbon and
  C++, including nullable pointers / Optional(T*).

This also causes us to use a thunk for rvalue reference return types,
which we used to miscompile.

Depends on #6276.
This commit is contained in:
Richard Smith
2025-10-27 22:49:29 +00:00
committed by GitHub
parent f022e91e45
commit a1a35c207e
7 changed files with 181 additions and 229 deletions
+9 -8
View File
@@ -1738,14 +1738,15 @@ static auto ImportFunctionDecl(Context& context, SemIR::LocId loc_id,
builder.Note(loc_id, InCppThunk);
});
clang::FunctionDecl* thunk_clang_decl =
BuildCppThunk(context, function_info);
if (thunk_clang_decl) {
SemIR::FunctionId thunk_function_id = *ImportFunction(
context, loc_id, thunk_clang_decl, thunk_clang_decl->getNumParams());
SemIR::InstId thunk_function_decl_id =
context.functions().Get(thunk_function_id).first_owning_decl_id;
function_info.SetHasCppThunk(thunk_function_decl_id);
if (clang::FunctionDecl* thunk_clang_decl =
BuildCppThunk(context, function_info)) {
if (auto thunk_function_id =
ImportFunction(context, loc_id, thunk_clang_decl,
thunk_clang_decl->getNumParams())) {
SemIR::InstId thunk_function_decl_id =
context.functions().Get(*thunk_function_id).first_owning_decl_id;
function_info.SetHasCppThunk(thunk_function_decl_id);
}
}
}