aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Squirek <squirek@adacore.com>2021-05-07 14:49:57 -0400
committerPierre-Marie de Rodat <derodat@adacore.com>2021-07-06 14:46:56 +0000
commit6dff0d21e56d15dafc683dd69c6a9fbf3f1e7dfc (patch)
treeccaef8ea28f85081b7dfbddd33800b3ad61d29de
parente11a24513632e2b2a3842bfd3ef226565f523778 (diff)
downloadgcc-6dff0d21e56d15dafc683dd69c6a9fbf3f1e7dfc.zip
gcc-6dff0d21e56d15dafc683dd69c6a9fbf3f1e7dfc.tar.gz
gcc-6dff0d21e56d15dafc683dd69c6a9fbf3f1e7dfc.tar.bz2
[Ada] Return_when_statement not working for non identifier return values
gcc/ada/ * par-ch6.adb (Get_Return_Kind): Removed. (Is_Extended): Created to identify simple and "when" return statements from extended return statements. (P_Return_Statement): Merged simple and "when" return statement processing.
-rw-r--r--gcc/ada/par-ch6.adb134
1 files changed, 61 insertions, 73 deletions
diff --git a/gcc/ada/par-ch6.adb b/gcc/ada/par-ch6.adb
index 2337175..e3b3155 100644
--- a/gcc/ada/par-ch6.adb
+++ b/gcc/ada/par-ch6.adb
@@ -1874,48 +1874,38 @@ package body Ch6 is
function P_Return_Statement return Node_Id is
-- The caller has checked that the initial token is RETURN
- type Return_Kind is (Simple_Return, Extended_Return, Return_When);
-
- function Get_Return_Kind return Return_Kind;
+ function Is_Extended return Boolean;
-- Scan state is just after RETURN (and is left that way). Determine
-- whether this is a simple or extended return statement by looking
-- ahead for "identifier :", which implies extended.
- ---------------------
- -- Get_Return_Kind --
- ---------------------
+ -----------------
+ -- Is_Extended --
+ -----------------
- function Get_Return_Kind return Return_Kind is
- Scan_State : Saved_Scan_State;
- Result : Return_Kind := Simple_Return;
+ function Is_Extended return Boolean is
+ Scan_State : Saved_Scan_State;
+ Is_Extended : Boolean := False;
begin
+
if Token = Tok_Identifier then
Save_Scan_State (Scan_State); -- at identifier
Scan; -- past identifier
if Token = Tok_Colon then
- Result := Extended_Return; -- It's an extended_return_statement
- elsif Token = Tok_When then
- Error_Msg_GNAT_Extension ("return when statement");
-
- Result := Return_When;
+ Is_Extended := True;
end if;
Restore_Scan_State (Scan_State); -- to identifier
-
- elsif Token = Tok_When then
- Error_Msg_GNAT_Extension ("return when statement");
-
- Result := Return_When;
end if;
- return Result;
- end Get_Return_Kind;
+ return Is_Extended;
+ end Is_Extended;
Ret_Sloc : constant Source_Ptr := Token_Ptr;
Ret_Strt : constant Column_Number := Start_Column;
- Ret_Node : Node_Id := New_Node (N_Simple_Return_Statement, Ret_Sloc);
+ Ret_Node : Node_Id;
Decl : Node_Id;
-- Start of processing for P_Return_Statement
@@ -1928,75 +1918,73 @@ package body Ch6 is
if Token = Tok_Semicolon then
Scan; -- past ;
+ Ret_Node := New_Node (N_Simple_Return_Statement, Ret_Sloc);
-- Nontrivial case
else
- -- Simple_return_statement with expression
+ -- Extended_return_statement (Ada 2005 only -- AI-318):
- -- We avoid trying to scan an expression if we are at an
- -- expression terminator since in that case the best error
- -- message is probably that we have a missing semicolon.
+ if Is_Extended then
+ Error_Msg_Ada_2005_Extension ("extended return statement");
- case Get_Return_Kind is
- -- Return_when_statement (Experimental only)
+ Ret_Node := New_Node (N_Extended_Return_Statement, Ret_Sloc);
+ Decl := P_Return_Object_Declaration;
+ Set_Return_Object_Declarations (Ret_Node, New_List (Decl));
- when Return_When =>
- Ret_Node := New_Node (N_Return_When_Statement, Ret_Sloc);
-
- if Token not in Token_Class_Eterm then
- Set_Expression (Ret_Node, P_Expression_No_Right_Paren);
- end if;
-
- if Token = Tok_When and then not Missing_Semicolon_On_When then
- Scan; -- past WHEN
- Set_Condition (Ret_Node, P_Condition);
-
- -- Allow IF instead of WHEN, giving error message
+ if Token = Tok_With then
+ P_Aspect_Specifications (Decl, False);
+ end if;
- elsif Token = Tok_If then
- T_When;
- Scan; -- past IF used in place of WHEN
- Set_Condition (Ret_Node, P_Expression_No_Right_Paren);
- end if;
+ if Token = Tok_Do then
+ Push_Scope_Stack;
+ Scopes (Scope.Last).Ecol := Ret_Strt;
+ Scopes (Scope.Last).Etyp := E_Return;
+ Scopes (Scope.Last).Labl := Error;
+ Scopes (Scope.Last).Sloc := Ret_Sloc;
+ Scan; -- past DO
+ Set_Handled_Statement_Sequence
+ (Ret_Node, P_Handled_Sequence_Of_Statements);
+ End_Statements;
+
+ -- Do we need to handle Error_Resync here???
+ end if;
- -- Simple_return_statement
+ -- Simple_return_statement or Return_when_Statement
+ -- with expression.
- when Simple_Return =>
- Ret_Node := New_Node (N_Simple_Return_Statement, Ret_Sloc);
+ -- We avoid trying to scan an expression if we are at an
+ -- expression terminator since in that case the best error
+ -- message is probably that we have a missing semicolon.
- if Token not in Token_Class_Eterm then
- Set_Expression (Ret_Node, P_Expression_No_Right_Paren);
- end if;
+ else
+ Ret_Node := New_Node (N_Simple_Return_Statement, Ret_Sloc);
- -- Extended_return_statement (Ada 2005 only -- AI-318):
+ if Token not in Token_Class_Eterm then
+ Set_Expression (Ret_Node, P_Expression_No_Right_Paren);
+ end if;
- when Extended_Return =>
- Error_Msg_Ada_2005_Extension ("extended return statement");
+ -- When the next token is WHEN or IF we know that we are looking
+ -- at a Return_when_statement
- Ret_Node := New_Node (N_Extended_Return_Statement, Ret_Sloc);
- Decl := P_Return_Object_Declaration;
- Set_Return_Object_Declarations (Ret_Node, New_List (Decl));
+ if Token = Tok_When and then not Missing_Semicolon_On_When then
+ Error_Msg_GNAT_Extension ("return when statement");
+ Mutate_Nkind (Ret_Node, N_Return_When_Statement);
- if Token = Tok_With then
- P_Aspect_Specifications (Decl, False);
- end if;
+ Scan; -- past WHEN
+ Set_Condition (Ret_Node, P_Condition);
- if Token = Tok_Do then
- Push_Scope_Stack;
- Scopes (Scope.Last).Ecol := Ret_Strt;
- Scopes (Scope.Last).Etyp := E_Return;
- Scopes (Scope.Last).Labl := Error;
- Scopes (Scope.Last).Sloc := Ret_Sloc;
+ -- Allow IF instead of WHEN, giving error message
- Scan; -- past DO
- Set_Handled_Statement_Sequence
- (Ret_Node, P_Handled_Sequence_Of_Statements);
- End_Statements;
+ elsif Token = Tok_If then
+ Error_Msg_GNAT_Extension ("return when statement");
+ Mutate_Nkind (Ret_Node, N_Return_When_Statement);
- -- Do we need to handle Error_Resync here???
- end if;
- end case;
+ T_When;
+ Scan; -- past IF used in place of WHEN
+ Set_Condition (Ret_Node, P_Condition);
+ end if;
+ end if;
TF_Semicolon;
end if;