Skip to content

Commit

Permalink
Disallow retuning a local for a -> forward return, addresses #248
Browse files Browse the repository at this point in the history
  • Loading branch information
hsutter committed Mar 12, 2023
1 parent 413de0e commit 43cdf3e
Showing 1 changed file with 41 additions and 10 deletions.
51 changes: 41 additions & 10 deletions source/cppfront.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,8 +846,20 @@ class cppfront
bool in_parameter_list = false;

std::string function_return_name;
std::vector<parameter_declaration_list_node*> function_returns;
parameter_declaration_list_node single_anon;
struct function_return {
parameter_declaration_list_node* param_list;
passing_style pass;

function_return(
parameter_declaration_list_node* param_list_,
passing_style pass_ = passing_style::invalid
)
: param_list{param_list_}
, pass{pass_}
{ }
};
std::vector<function_return> function_returns;
parameter_declaration_list_node single_anon;
// special value - hack for now to note single-anon-return type kind in this function_returns working list
std::vector<std::string> function_requires_conditions;

Expand Down Expand Up @@ -1858,11 +1870,27 @@ class cppfront

// Return with expression == single anonymous return type
//
if (n.expression) {
if (n.expression)
{
auto tok = n.expression->expr->get_postfix_expression_node()->expr->get_token();
if (
tok
&& sema.get_declaration_of(*tok)
&& !function_returns.empty()
&& function_returns.back().pass == passing_style::forward
)
{
errors.emplace_back(
n.position(),
"a 'forward' return type cannot return a local variable"
);
return;
}

emit(*n.expression);
if (
function_returns.empty()
|| function_returns.back() != &single_anon
|| function_returns.back().param_list != &single_anon
)
{
errors.emplace_back(
Expand All @@ -1875,7 +1903,7 @@ class cppfront

else if (
!function_returns.empty()
&& function_returns.back() == &single_anon
&& function_returns.back().param_list == &single_anon
)
{
errors.emplace_back(
Expand All @@ -1888,12 +1916,12 @@ class cppfront
//
else if (
!function_returns.empty()
&& function_returns.back()
&& function_returns.back().param_list
)
{
//auto stmt = function_return_name + " { "; // we shouldn't need this with { } init
auto stmt = std::string(" { ");
auto& parameters = function_returns.back()->parameters;
auto& parameters = function_returns.back().param_list->parameters;
for (bool first = true; auto& param : parameters) {
if (!first) {
stmt += ", ";
Expand Down Expand Up @@ -4000,13 +4028,16 @@ class cppfront

if (func->returns.index() == function_type_node::list) {
auto& r = std::get<function_type_node::list>(func->returns);
function_returns.push_back(r.get());
function_returns.emplace_back(r.get());
}
else if (func->returns.index() == function_type_node::id) {
function_returns.push_back(&single_anon); // use special value as a note
function_returns.emplace_back(
&single_anon, // use special value as a note
std::get<function_type_node::id>(func->returns).pass
);
}
else {
function_returns.push_back(nullptr); // no return type at all
function_returns.emplace_back(nullptr); // no return type at all
}

// Function body
Expand Down

0 comments on commit 43cdf3e

Please sign in to comment.