Skip to content

Commit 164f2ae

Browse files
compiler: only build thunk struct type when it is needed
Instead of building the thunk struct type in the determine_types pass, build it when we need it. That ensures that we are consistent in determining whether an argument is constant. We no longer need to add a field for a call to recover, as the simplify_thunk_statements pass runs after the build_recover_thunks pass, so the additional argument will already have been added to the call. The test case is https://go.dev/cl/440297. Fixes golang/go#56109 Change-Id: I7e2271cf8dc2ed523a4e9cb22728daa773daaa90 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/440298 Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Than McIntosh <[email protected]>
1 parent 50707b4 commit 164f2ae

File tree

2 files changed

+10
-29
lines changed

2 files changed

+10
-29
lines changed

go/statements.cc

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2349,7 +2349,7 @@ Thunk_statement::Thunk_statement(Statement_classification classification,
23492349
Call_expression* call,
23502350
Location location)
23512351
: Statement(classification, location),
2352-
call_(call), struct_type_(NULL)
2352+
call_(call)
23532353
{
23542354
}
23552355

@@ -2430,15 +2430,6 @@ void
24302430
Thunk_statement::do_determine_types()
24312431
{
24322432
this->call_->determine_type_no_context();
2433-
2434-
// Now that we know the types of the call, build the struct used to
2435-
// pass parameters.
2436-
Call_expression* ce = this->call_->call_expression();
2437-
if (ce == NULL)
2438-
return;
2439-
Function_type* fntype = ce->get_function_type();
2440-
if (fntype != NULL && !this->is_simple(fntype))
2441-
this->struct_type_ = this->build_struct(fntype);
24422433
}
24432434

24442435
// Check types in a thunk statement.
@@ -2581,6 +2572,8 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function,
25812572
if (this->is_simple(fntype))
25822573
return false;
25832574

2575+
Struct_type* struct_type = this->build_struct(fntype);
2576+
25842577
Expression* fn = ce->fn();
25852578
Interface_field_reference_expression* interface_method =
25862579
fn->interface_field_reference_expression();
@@ -2600,7 +2593,7 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function,
26002593
std::string thunk_name = gogo->thunk_name();
26012594

26022595
// Build the thunk.
2603-
this->build_thunk(gogo, thunk_name);
2596+
this->build_thunk(gogo, thunk_name, struct_type);
26042597

26052598
// Generate code to call the thunk.
26062599

@@ -2630,8 +2623,7 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function,
26302623

26312624
// Build the struct.
26322625
Expression* constructor =
2633-
Expression::make_struct_composite_literal(this->struct_type_, vals,
2634-
location);
2626+
Expression::make_struct_composite_literal(struct_type, vals, location);
26352627

26362628
// Allocate the initialized struct on the heap.
26372629
constructor = Expression::make_heap_expression(constructor, location);
@@ -2745,15 +2737,6 @@ Thunk_statement::build_struct(Function_type* fntype)
27452737
fields->push_back(Struct_field(tid));
27462738
}
27472739

2748-
// The predeclared recover function has no argument. However, we
2749-
// add an argument when building recover thunks. Handle that here.
2750-
if (ce->is_recover_call())
2751-
{
2752-
fields->push_back(Struct_field(Typed_identifier("can_recover",
2753-
Type::lookup_bool_type(),
2754-
location)));
2755-
}
2756-
27572740
const Expression_list* args = ce->args();
27582741
if (args != NULL)
27592742
{
@@ -2781,7 +2764,8 @@ Thunk_statement::build_struct(Function_type* fntype)
27812764
// artificial, function.
27822765

27832766
void
2784-
Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
2767+
Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
2768+
Struct_type* struct_type)
27852769
{
27862770
Location location = this->location();
27872771

@@ -2807,7 +2791,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
28072791
// which is a pointer to the special structure we build.
28082792
const char* const parameter_name = "__go_thunk_parameter";
28092793
Typed_identifier_list* thunk_parameters = new Typed_identifier_list();
2810-
Type* pointer_to_struct_type = Type::make_pointer_type(this->struct_type_);
2794+
Type* pointer_to_struct_type = Type::make_pointer_type(struct_type);
28112795
thunk_parameters->push_back(Typed_identifier(parameter_name,
28122796
pointer_to_struct_type,
28132797
location));
@@ -2914,7 +2898,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
29142898
}
29152899

29162900
Expression_list* call_params = new Expression_list();
2917-
const Struct_field_list* fields = this->struct_type_->fields();
2901+
const Struct_field_list* fields = struct_type->fields();
29182902
Struct_field_list::const_iterator p = fields->begin();
29192903
for (unsigned int i = 0; i < next_index; ++i)
29202904
++p;

go/statements.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,7 +1411,7 @@ class Thunk_statement : public Statement
14111411

14121412
// Build the thunk.
14131413
void
1414-
build_thunk(Gogo*, const std::string&);
1414+
build_thunk(Gogo*, const std::string&, Struct_type*);
14151415

14161416
// Set the name to use for thunk field N.
14171417
void
@@ -1420,9 +1420,6 @@ class Thunk_statement : public Statement
14201420
// The function call to be executed in a separate thread (go) or
14211421
// later (defer).
14221422
Expression* call_;
1423-
// The type used for a struct to pass to a thunk, if this is not a
1424-
// simple call.
1425-
Struct_type* struct_type_;
14261423
};
14271424

14281425
// A go statement.

0 commit comments

Comments
 (0)