Skip to content

Commit 7af1121

Browse files
authored
Merge pull request #347 from tjj2017/access_parameters
Access parameters
2 parents 6ca0e61 + 272516c commit 7af1121

File tree

5 files changed

+77
-30
lines changed

5 files changed

+77
-30
lines changed

experiments/golden-results/StratoX-summary.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1745,7 +1745,7 @@ Error detected at REDACTED
17451745
--
17461746
Occurs: 3 times
17471747
+===========================GNAT BUG DETECTED==============================+
1748-
| GNU Ada (ada2goto) Assert_Failure tree_walk.adb:992 |
1748+
| GNU Ada (ada2goto) Assert_Failure tree_walk.adb:999 |
17491749
Error detected at REDACTED
17501750
--
17511751
Occurs: 2 times

gnat2goto/driver/tree_walk.adb

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,13 @@ package body Tree_Walk is
771771
is
772772
Args : constant Irep := Make_Argument_List;
773773

774+
-- A formal access parameter cannot be mode out (an Ada rule) and
775+
-- an actual corresponding to the formal access parameter must be an
776+
-- access type (again an Ada rule and checked by the front end).
777+
-- Therefore, the actual parameter will be a goto pointer type and
778+
-- does not need wrapping into a pointer. Since the mode of a formal
779+
-- access parameter cannot be out or in out the Wrap_Argument function
780+
-- will not wrap the corresponding actual parameter.
774781
function Wrap_Argument (Base : Irep; Is_Out : Boolean) return Irep is
775782
(if Is_Out
776783
then Make_Address_Of (Base)
@@ -4977,38 +4984,60 @@ package body Tree_Walk is
49774984
Param_Iter : Node_Id := First (Parameter_Specifications (N));
49784985
begin
49794986
while Present (Param_Iter) loop
4980-
if not (Nkind (Parameter_Type (Param_Iter)) in N_Has_Etype) then
4981-
return Report_Unhandled_Node_Type
4982-
(N,
4983-
"Do_Subprogram_Specification",
4984-
"Param iter type not have etype");
4985-
end if;
49864987
declare
4987-
Is_Out : constant Boolean := Out_Present (Param_Iter);
4988+
Param_Sort : constant Node_Id := Parameter_Type (Param_Iter);
4989+
begin
4990+
if not (Nkind (Param_Sort)
4991+
in N_Has_Etype | N_Access_Definition)
4992+
then
4993+
return Report_Unhandled_Node_Type
4994+
(N,
4995+
"Do_Subprogram_Specification",
4996+
"Param iter is not an access parameter or has no etype");
4997+
end if;
4998+
declare
4999+
Is_Out : constant Boolean := Out_Present (Param_Iter);
49885000

4989-
Param_Name : constant String :=
4990-
Unique_Name (Defining_Identifier (Param_Iter));
5001+
-- A subprogram can have a formal access parameter of the form
5002+
-- procedure P (Ptr_To_ObjectOf_Type_T : access T);
5003+
Is_Access_Param : constant Boolean :=
5004+
Nkind (Param_Sort) = N_Access_Definition;
49915005

4992-
Param_Type_Base : constant Irep :=
4993-
Do_Type_Reference (Etype (Parameter_Type (Param_Iter)));
4994-
Param_Type : constant Irep :=
4995-
(if Is_Out
4996-
then Make_Pointer_Type (Param_Type_Base)
4997-
else Param_Type_Base);
4998-
Param_Irep : constant Irep := Make_Code_Parameter
4999-
(Source_Location => Get_Source_Location (Param_Iter),
5000-
I_Type => Param_Type,
5001-
Identifier => Param_Name,
5002-
Base_Name => Param_Name,
5003-
This => False,
5004-
Default_Value => Ireps.Empty);
5005-
begin
5006-
Append_Parameter (Param_List, Param_Irep);
5007-
New_Parameter_Symbol_Entry (Name_Id => Intern (Param_Name),
5008-
BaseName => Param_Name,
5009-
Symbol_Type => Param_Type,
5010-
A_Symbol_Table => Global_Symbol_Table);
5011-
Next (Param_Iter);
5006+
Param_Name : constant String :=
5007+
Unique_Name (Defining_Identifier (Param_Iter));
5008+
5009+
Param_Ada_Type : constant Node_Id :=
5010+
(if Is_Access_Param then
5011+
Etype (Subtype_Mark (Param_Sort))
5012+
else
5013+
Etype (Parameter_Type (Param_Iter)));
5014+
5015+
Param_Type_Base : constant Irep :=
5016+
Do_Type_Reference (Param_Ada_Type);
5017+
5018+
-- If the formal parameter is mode out or in out,
5019+
-- or is an access parameter, it is made into a pointer
5020+
Param_Type : constant Irep :=
5021+
(if Is_Out or Is_Access_Param then
5022+
Make_Pointer_Type (Param_Type_Base)
5023+
else Param_Type_Base);
5024+
Param_Irep : constant Irep := Make_Code_Parameter
5025+
(Source_Location => Get_Source_Location (Param_Iter),
5026+
I_Type => Param_Type,
5027+
Identifier => Param_Name,
5028+
Base_Name => Param_Name,
5029+
This => False,
5030+
Default_Value => Ireps.Empty);
5031+
begin
5032+
Append_Parameter (Param_List, Param_Irep);
5033+
New_Parameter_Symbol_Entry
5034+
(Name_Id => Intern (Param_Name),
5035+
BaseName => Param_Name,
5036+
Symbol_Type => Param_Type,
5037+
A_Symbol_Table => Global_Symbol_Table);
5038+
5039+
Next (Param_Iter);
5040+
end;
50125041
end;
50135042
end loop;
50145043
return Make_Code_Type
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
procedure Access_Parameter is
2+
3+
procedure P (A : access Integer) is
4+
begin
5+
A.all := A.all + 1;
6+
end P;
7+
8+
I : aliased Integer := 1;
9+
begin
10+
P (I 'Access);
11+
pragma Assert (I = 2);
12+
end Access_Parameter;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[access_parameter.assertion.1] line 11 assertion I = 2: SUCCESS
2+
[p.assertion.1] line 5 Ada Check assertion: SUCCESS
3+
VERIFICATION SUCCESSFUL
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from test_support import *
2+
3+
prove()

0 commit comments

Comments
 (0)