Skip to content

Commit dce84f2

Browse files
authored
Merge pull request #221 from xbauch/feature/modular-subtype
Modular subtype
2 parents 4f65a89 + 708484e commit dce84f2

14 files changed

+169
-31
lines changed

experiments/golden-results/StratoX-summary.txt

+14-14
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ Calling function: Process_Pragma_Declaration
33
Error message: Unsupported pragma: Postcondition
44
Nkind: N_Pragma
55
--
6-
Occurs: 168 times
6+
Occurs: 134 times
77
Calling function: Process_Declaration
88
Error message: Unknown declaration kind
99
Nkind: N_Freeze_Generic_Entity
1010
--
11-
Occurs: 147 times
11+
Occurs: 102 times
1212
Calling function: Do_Function_Call
1313
Error message: func name not in symbol table
1414
Nkind: N_Function_Call
@@ -19,26 +19,26 @@ Error message: Generic declaration
1919
Nkind: N_Generic_Subprogram_Declaration
2020
--
2121
Occurs: 50 times
22-
Calling function: Do_Expression
23-
Error message: Unknown attribute
24-
Nkind: N_Attribute_Reference
25-
--
26-
Occurs: 50 times
2722
Calling function: Do_Type_Definition
2823
Error message: Access type unsupported
2924
Nkind: N_Access_To_Object_Definition
3025
--
26+
Occurs: 42 times
27+
Calling function: Do_Expression
28+
Error message: Unknown attribute
29+
Nkind: N_Attribute_Reference
30+
--
3131
Occurs: 35 times
3232
Calling function: Process_Pragma_Declaration
3333
Error message: Unsupported pragma: No strict aliasing
3434
Nkind: N_Pragma
3535
--
36-
Occurs: 32 times
36+
Occurs: 31 times
3737
Calling function: Process_Declaration
3838
Error message: Package declaration
3939
Nkind: N_Package_Declaration
4040
--
41-
Occurs: 24 times
41+
Occurs: 23 times
4242
Calling function: Process_Pragma_Declaration
4343
Error message: Unsupported pragma: Check
4444
Nkind: N_Pragma
@@ -78,11 +78,6 @@ Calling function: Process_Declaration
7878
Error message: Generic instantiation declaration
7979
Nkind: N_Function_Instantiation
8080
--
81-
Occurs: 12 times
82-
Calling function: Do_Constant
83-
Error message: Constant Type not in symbol table
84-
Nkind: N_Integer_Literal
85-
--
8681
Occurs: 11 times
8782
Calling function: Do_Expression
8883
Error message: In
@@ -139,6 +134,11 @@ Error message: Unsupported pragma: Suppress initialization
139134
Nkind: N_Pragma
140135
--
141136
Occurs: 6 times
137+
Calling function: Do_Constant
138+
Error message: Constant Type not in symbol table
139+
Nkind: N_Integer_Literal
140+
--
141+
Occurs: 6 times
142142
Calling function: Process_Declaration
143143
Error message: Generic instantiation declaration
144144
Nkind: N_Procedure_Instantiation

experiments/golden-results/UKNI-Information-Barrier-summary.txt

+10-5
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ Error message: Unknown expression kind
1919
Nkind: N_Expanded_Name
2020
--
2121
Occurs: 5 times
22-
Calling function: Do_Itype_Definition
23-
Error message: Unknown Ekind
24-
Nkind: N_Defining_Identifier
25-
--
26-
Occurs: 5 times
2722
Calling function: Do_Procedure_Call_Statement
2823
Error message: sym id not in symbol table
2924
Nkind: N_Procedure_Call_Statement
@@ -34,6 +29,16 @@ Error message: Wrong Nkind spec
3429
Nkind: N_Loop_Statement
3530
--
3631
Occurs: 1 times
32+
Calling function: Do_Base_Range_Constraint
33+
Error message: unsupported lower range kind
34+
Nkind: N_Attribute_Reference
35+
--
36+
Occurs: 1 times
37+
Calling function: Do_Base_Range_Constraint
38+
Error message: unsupported upper range kind
39+
Nkind: N_Attribute_Reference
40+
--
41+
Occurs: 1 times
3742
Calling function: Do_Operator_General
3843
Error message: Mod of unsupported type
3944
Nkind: N_Op_Not

experiments/golden-results/muen-summary.txt

+5-5
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,6 @@ Calling function: Process_Pragma_Declaration
5353
Error message: Unsupported pragma: Initializes
5454
Nkind: N_Pragma
5555
--
56-
Occurs: 10 times
57-
Calling function: Do_Constant
58-
Error message: Constant Type not in symbol table
59-
Nkind: N_Integer_Literal
60-
--
6156
Occurs: 8 times
6257
Calling function: Process_Declaration
6358
Error message: Use type clause declaration
@@ -79,6 +74,11 @@ Error message: Unsupported pragma: Precondition
7974
Nkind: N_Pragma
8075
--
8176
Occurs: 7 times
77+
Calling function: Do_Constant
78+
Error message: Constant Type not in symbol table
79+
Nkind: N_Integer_Literal
80+
--
81+
Occurs: 7 times
8282
Calling function: Do_Function_Call
8383
Error message: func name not in symbol table
8484
Nkind: N_Function_Call

gnat2goto/driver/gnat2goto_itypes.adb

+57-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ with GOTO_Utils; use GOTO_Utils;
66
with Range_Check; use Range_Check;
77
with Symbol_Table_Info; use Symbol_Table_Info;
88
with Tree_Walk; use Tree_Walk;
9+
with Follow; use Follow;
910

1011
package body Gnat2goto_Itypes is
1112

@@ -89,7 +90,8 @@ package body Gnat2goto_Itypes is
8990
when E_Signed_Integer_Type => Do_Itype_Integer_Type (N),
9091
when E_Floating_Point_Type => Create_Dummy_Irep,
9192
when E_Anonymous_Access_Type => Make_Pointer_Type
92-
(Base => Do_Type_Reference (Designated_Type (Etype (N)))),
93+
(Base => Do_Type_Reference (Designated_Type (Etype (N)))),
94+
when E_Modular_Integer_Subtype => Do_Modular_Integer_Subtype (N),
9395
when others => Report_Unhandled_Node_Irep (N, "Do_Itype_Definition",
9496
"Unknown Ekind"));
9597
end Do_Itype_Definition;
@@ -171,4 +173,58 @@ package body Gnat2goto_Itypes is
171173
return Do_Type_Reference (Etype (N));
172174
end Do_Itype_Record_Subtype;
173175

176+
function Do_Modular_Integer_Subtype (N : Entity_Id) return Irep is
177+
Modular_Type : constant Irep := Do_Type_Reference (Etype (N));
178+
Followed_Mod_Type : constant Irep :=
179+
Follow_Symbol_Type (Modular_Type, Global_Symbol_Table);
180+
181+
S_Range : constant Node_Id := Scalar_Range (N);
182+
Lower_Bound : constant Node_Id := Low_Bound (S_Range);
183+
Upper_Bound : constant Node_Id := High_Bound (S_Range);
184+
185+
Lower_Bound_Value : Integer;
186+
Upper_Bound_Value : Integer;
187+
begin
188+
pragma Assert (Kind (Followed_Mod_Type) in I_Unsignedbv_Type
189+
| I_Ada_Mod_Type);
190+
191+
case Nkind (Lower_Bound) is
192+
when N_Integer_Literal => Lower_Bound_Value :=
193+
Store_Nat_Bound (Bound_Type_Nat (Intval (Lower_Bound)));
194+
when N_Identifier => Lower_Bound_Value :=
195+
Store_Symbol_Bound (Bound_Type_Symbol (Lower_Bound));
196+
when others =>
197+
Report_Unhandled_Node_Empty (Lower_Bound,
198+
"Do_Base_Range_Constraint",
199+
"unsupported lower range kind");
200+
end case;
201+
202+
case Nkind (Upper_Bound) is
203+
when N_Integer_Literal => Upper_Bound_Value :=
204+
Store_Nat_Bound (Bound_Type_Nat (Intval (Upper_Bound)));
205+
when N_Identifier => Upper_Bound_Value :=
206+
Store_Symbol_Bound (Bound_Type_Symbol (Upper_Bound));
207+
when others =>
208+
Report_Unhandled_Node_Empty (Upper_Bound,
209+
"Do_Base_Range_Constraint",
210+
"unsupported upper range kind");
211+
end case;
212+
213+
if Kind (Followed_Mod_Type) = I_Ada_Mod_Type then
214+
return Make_Bounded_Mod_Type (I_Subtype => Make_Nil_Type,
215+
Width =>
216+
Get_Width (Followed_Mod_Type),
217+
Lower_Bound => Lower_Bound_Value,
218+
Ada_Mod_Max =>
219+
Get_Ada_Mod_Max (Followed_Mod_Type),
220+
Upper_Bound => Upper_Bound_Value);
221+
else
222+
return Make_Bounded_Unsignedbv_Type (I_Subtype => Make_Nil_Type,
223+
Width =>
224+
Get_Width (Followed_Mod_Type),
225+
Lower_Bound => Lower_Bound_Value,
226+
Upper_Bound => Upper_Bound_Value);
227+
end if;
228+
end Do_Modular_Integer_Subtype;
229+
174230
end Gnat2goto_Itypes;

gnat2goto/driver/gnat2goto_itypes.ads

+3
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ private
3030
function Do_Itype_Record_Subtype (N : Entity_Id) return Irep
3131
with Pre => Is_Itype (N) and then Ekind (N) = E_Record_Subtype;
3232

33+
function Do_Modular_Integer_Subtype (N : Entity_Id) return Irep
34+
with Pre => Is_Itype (N) and then Ekind (N) = E_Modular_Integer_Subtype;
35+
3336
end Gnat2goto_Itypes;

gnat2goto/driver/range_check.adb

+3-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ package body Range_Check is
228228
(Value_Expr);
229229
begin
230230
pragma Assert (Kind (Bound_Type) in
231-
I_Bounded_Signedbv_Type | I_Bounded_Floatbv_Type);
231+
I_Bounded_Unsignedbv_Type
232+
| I_Bounded_Signedbv_Type
233+
| I_Bounded_Floatbv_Type);
232234
-- The compared expressions (value and bound) have to be of the
233235
-- same type
234236
if Get_Width (Bound_Type) > Get_Width (Value_Expr_Type)

gnat2goto/driver/range_check.ads

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ package Range_Check is
2121

2222
function Get_Bound (Bound_Type : Irep; Pos : Bound_Low_Or_High) return Irep
2323
with Pre => Kind (Bound_Type) in
24-
I_Bounded_Signedbv_Type | I_Bounded_Floatbv_Type,
24+
I_Bounded_Unsignedbv_Type | I_Bounded_Signedbv_Type
25+
| I_Bounded_Floatbv_Type,
2526
Post => Kind (Get_Bound'Result) in Class_Expr;
2627

2728
function Make_Range_Assert_Expr (N : Node_Id; Value : Irep;

gnat2goto/driver/tree_walk.adb

+10-4
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,10 @@ package body Tree_Walk is
754754
Lower_Bound_Value : Integer;
755755
Upper_Bound_Value : Integer;
756756

757-
Result_Type : constant Irep := New_Irep (I_Bounded_Signedbv_Type);
757+
Result_Type : constant Irep :=
758+
New_Irep (if Kind (Resolved_Underlying) = I_Ada_Mod_Type
759+
then I_Bounded_Unsignedbv_Type
760+
else I_Bounded_Signedbv_Type);
758761
begin
759762
if not (Kind (Resolved_Underlying) in Class_Bitvector_Type or
760763
Kind (Resolved_Underlying) = I_C_Enum_Type)
@@ -771,7 +774,8 @@ package body Tree_Walk is
771774
Store_Symbol_Bound (Get_Array_Attr_Bound_Symbol (Lower_Bound));
772775
when N_Identifier =>
773776
Lower_Bound_Value :=
774-
Store_Symbol_Bound (Bound_Type_Symbol (Lower_Bound));
777+
Store_Symbol_Bound (Bound_Type_Symbol (
778+
Do_Identifier (Lower_Bound)));
775779
when others =>
776780
Report_Unhandled_Node_Empty (Lower_Bound,
777781
"Do_Base_Range_Constraint",
@@ -785,7 +789,8 @@ package body Tree_Walk is
785789
Store_Symbol_Bound (Get_Array_Attr_Bound_Symbol (Upper_Bound));
786790
when N_Identifier =>
787791
Upper_Bound_Value :=
788-
Store_Symbol_Bound (Bound_Type_Symbol (Upper_Bound));
792+
Store_Symbol_Bound (Bound_Type_Symbol (
793+
Do_Identifier (Upper_Bound)));
789794
when others =>
790795
Report_Unhandled_Node_Empty (Upper_Bound,
791796
"Do_Base_Range_Constraint",
@@ -2961,7 +2966,8 @@ package body Tree_Walk is
29612966

29622967
if Init_Expr /= Ireps.Empty then
29632968
Append_Op (Block, Make_Code_Assign (Lhs => Id,
2964-
Rhs => Init_Expr,
2969+
Rhs => Typecast_If_Necessary (Init_Expr, Get_Type (Id),
2970+
Global_Symbol_Table),
29652971
Source_Location => Sloc (N)));
29662972
end if;
29672973

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"parent": "bitvector_type",
3+
"id": "bounded_mod_type",
4+
"namedSub": {
5+
"lower_bound": {"type": "integer"},
6+
"upper_bound": {"type": "integer"},
7+
"ada_mod_max": {"type": "string"}
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"parent": "bitvector_type",
3+
"namedSub": {
4+
"lower_bound": {"type": "integer"},
5+
"upper_bound": {"type": "integer"}
6+
}
7+
}

gnat2goto/ireps/ireps_generator.py

+10
Original file line numberDiff line numberDiff line change
@@ -2055,6 +2055,16 @@ def generate_code(self, optimize, schema_file_names):
20552055
with indent(b):
20562056
write(b, "return Make_Floatbv_Type (Get_Subtype (I), Get_Width (I), Get_F (I));")
20572057
write(b, "end if;")
2058+
write(b, "")
2059+
write(b, "if Kind (I) = I_Bounded_Unsignedbv_Type then")
2060+
with indent(b):
2061+
write(b, "return Make_Unsignedbv_Type (Get_Subtype (I), Get_Width (I));")
2062+
write(b, "end if;")
2063+
write(b, "")
2064+
write(b, "if Kind (I) = I_Bounded_Mod_Type then")
2065+
with indent(b):
2066+
write(b, "return Make_Unsignedbv_Type (Get_Subtype (I), Get_Width (I));")
2067+
write(b, "end if;")
20582068
write(b, "if Kind (I) = I_Ada_Mod_Type then")
20592069
with indent(b):
20602070
write(b, "return Make_Unsignedbv_Type (Make_Nil_Type, Get_Width (I));")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
procedure Test is
2+
type Unsigned_16 is mod 2 ** 4;
3+
RAM_Start : constant Unsigned_16 := 5;
4+
RAM_End : constant Unsigned_16 := 12;
5+
Sum : Unsigned_16 := 0;
6+
7+
Test_Passed : Boolean := True;
8+
9+
subtype Sub16 is Unsigned_16 range RAM_Start .. RAM_End;
10+
SubVar : Sub16 := RAM_Start;
11+
12+
function Address_OK
13+
(Address : in Unsigned_16) return Boolean;
14+
function Address_OK
15+
(Address : in Unsigned_16)
16+
return Boolean
17+
is
18+
begin
19+
Sum := Sum + 1;
20+
return Test_Passed;
21+
end Address_OK;
22+
begin
23+
SubVar := SubVar + 1; -- invokes range check
24+
for I in Unsigned_16 range RAM_Start .. RAM_End loop
25+
if Address_OK (Address => I)
26+
then
27+
Test_Passed := False;
28+
end if;
29+
30+
end loop;
31+
pragma Assert (Sum = RAM_End - RAM_Start + 1);
32+
33+
end Test;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[assertion.1] Range Check: SUCCESS
2+
[1] file test.adb line 31 assertion: SUCCESS
3+
VERIFICATION SUCCESSFUL
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)