@@ -4945,6 +4945,14 @@
// our return address comparison.
bool is_inlinable = !(this->calls_recover_ || this->is_recover_thunk_);
+ // If a function calls __go_set_defer_retaddr, then mark it as
+ // uninlinable. This prevents the GCC backend from splitting
+ // the function; splitting the function is a bad idea because we
+ // want the return address label to be in the same function as
+ // the call.
+ if (this->calls_defer_retaddr_)
+ is_inlinable = false;
+
// If this is a thunk created to call a function which calls
// the predeclared recover function, we need to disable
// stack splitting for the thunk.
@@ -1065,6 +1065,12 @@
set_has_recover_thunk()
{ this->has_recover_thunk_ = true; }
+ // Record that this function is a thunk created for a defer
+ // statement that calls the __go_set_defer_retaddr runtime function.
+ void
+ set_calls_defer_retaddr()
+ { this->calls_defer_retaddr_ = true; }
+
// Mark the function as going into a unique section.
void
set_in_unique_section()
@@ -1190,6 +1196,9 @@
bool is_recover_thunk_ : 1;
// True if this function already has a recover thunk.
bool has_recover_thunk_ : 1;
+ // True if this is a thunk built for a defer statement that calls
+ // the __go_set_defer_retaddr runtime function.
+ bool calls_defer_retaddr_ : 1;
// True if this function should be put in a unique section. This is
// turned on for field tracking.
bool in_unique_section_ : 1;
@@ -2376,6 +2376,8 @@
location);
s->determine_types();
gogo->add_statement(s);
+
+ function->func_value()->set_calls_defer_retaddr();
}
// Get a reference to the parameter.