@@ -846,8 +846,20 @@ class cppfront
846
846
bool in_parameter_list = false ;
847
847
848
848
std::string function_return_name;
849
- std::vector<parameter_declaration_list_node*> function_returns;
850
- parameter_declaration_list_node single_anon;
849
+ struct function_return {
850
+ parameter_declaration_list_node* param_list;
851
+ passing_style pass;
852
+
853
+ function_return (
854
+ parameter_declaration_list_node* param_list_,
855
+ passing_style pass_ = passing_style::invalid
856
+ )
857
+ : param_list{param_list_}
858
+ , pass{pass_}
859
+ { }
860
+ };
861
+ std::vector<function_return> function_returns;
862
+ parameter_declaration_list_node single_anon;
851
863
// special value - hack for now to note single-anon-return type kind in this function_returns working list
852
864
std::vector<std::string> function_requires_conditions;
853
865
@@ -1858,11 +1870,27 @@ class cppfront
1858
1870
1859
1871
// Return with expression == single anonymous return type
1860
1872
//
1861
- if (n.expression ) {
1873
+ if (n.expression )
1874
+ {
1875
+ auto tok = n.expression ->expr ->get_postfix_expression_node ()->expr ->get_token ();
1876
+ if (
1877
+ tok
1878
+ && sema.get_declaration_of (*tok)
1879
+ && !function_returns.empty ()
1880
+ && function_returns.back ().pass == passing_style::forward
1881
+ )
1882
+ {
1883
+ errors.emplace_back (
1884
+ n.position (),
1885
+ " a 'forward' return type cannot return a local variable"
1886
+ );
1887
+ return ;
1888
+ }
1889
+
1862
1890
emit (*n.expression );
1863
1891
if (
1864
1892
function_returns.empty ()
1865
- || function_returns.back () != &single_anon
1893
+ || function_returns.back (). param_list != &single_anon
1866
1894
)
1867
1895
{
1868
1896
errors.emplace_back (
@@ -1875,7 +1903,7 @@ class cppfront
1875
1903
1876
1904
else if (
1877
1905
!function_returns.empty ()
1878
- && function_returns.back () == &single_anon
1906
+ && function_returns.back (). param_list == &single_anon
1879
1907
)
1880
1908
{
1881
1909
errors.emplace_back (
@@ -1888,12 +1916,12 @@ class cppfront
1888
1916
//
1889
1917
else if (
1890
1918
!function_returns.empty ()
1891
- && function_returns.back ()
1919
+ && function_returns.back (). param_list
1892
1920
)
1893
1921
{
1894
1922
// auto stmt = function_return_name + " { "; // we shouldn't need this with { } init
1895
1923
auto stmt = std::string (" { " );
1896
- auto & parameters = function_returns.back ()->parameters ;
1924
+ auto & parameters = function_returns.back (). param_list ->parameters ;
1897
1925
for (bool first = true ; auto & param : parameters) {
1898
1926
if (!first) {
1899
1927
stmt += " , " ;
@@ -4000,13 +4028,16 @@ class cppfront
4000
4028
4001
4029
if (func->returns .index () == function_type_node::list) {
4002
4030
auto & r = std::get<function_type_node::list>(func->returns );
4003
- function_returns.push_back (r.get ());
4031
+ function_returns.emplace_back (r.get ());
4004
4032
}
4005
4033
else if (func->returns .index () == function_type_node::id) {
4006
- function_returns.push_back (&single_anon); // use special value as a note
4034
+ function_returns.emplace_back (
4035
+ &single_anon, // use special value as a note
4036
+ std::get<function_type_node::id>(func->returns ).pass
4037
+ );
4007
4038
}
4008
4039
else {
4009
- function_returns.push_back (nullptr ); // no return type at all
4040
+ function_returns.emplace_back (nullptr ); // no return type at all
4010
4041
}
4011
4042
4012
4043
// Function body
0 commit comments