Skip to content

Commit fcae807

Browse files
committed
Modification to use enumeration literal position as its value.
Using an enumeration literal position as its value maintains an order relation between literals of an enumeration, whereas using an enumeration literal's representation value does not necessarily. Also updated range checks on enumeration literals.
1 parent d23baa3 commit fcae807

File tree

2 files changed

+63
-23
lines changed

2 files changed

+63
-23
lines changed

gnat2goto/driver/range_check.adb

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ package body Range_Check is
7676
case Kind (Bound_Type) is
7777
when I_Bounded_Signedbv_Type
7878
| I_Bounded_Unsignedbv_Type
79-
| I_Bounded_Floatbv_Type =>
79+
| I_Bounded_Floatbv_Type
80+
| I_C_Enum_Type =>
8081
return Get_Bound_Of_Bounded_Type (Bound_Type, Pos);
8182
when I_Unsignedbv_Type =>
8283
-- this case is probably unnecessary:
@@ -450,14 +451,18 @@ package body Range_Check is
450451
Bounds_Type : Irep)
451452
return Irep
452453
is
453-
Followed_Bound_Type : constant Irep := Follow_Symbol_Type (Bounds_Type,
454-
Global_Symbol_Table);
455-
454+
Followed_Bound_Type : constant Irep :=
455+
Follow_Symbol_Type (Bounds_Type,
456+
Global_Symbol_Table);
457+
Lower_Bound : constant Irep :=
458+
Get_Bound (N, Followed_Bound_Type, Bound_Low);
459+
Upper_Bound : constant Irep :=
460+
Get_Bound (N, Followed_Bound_Type, Bound_High);
456461
begin
457462
return Make_Range_Assert_Expr (N => N,
458463
Value => Value,
459-
Lower_Bound => Get_Bound (N, Followed_Bound_Type, Bound_Low),
460-
Upper_Bound => Get_Bound (N, Followed_Bound_Type, Bound_High),
464+
Lower_Bound => Lower_Bound,
465+
Upper_Bound => Upper_Bound,
461466
Expected_Return_Type => Get_Type (Value),
462467
Check_Name => "__CPROVER_Ada_Range_Check");
463468

@@ -472,11 +477,36 @@ package body Range_Check is
472477
Upper_Bound : Irep)
473478
return Irep
474479
is
475-
Bound_Type : constant Irep :=
480+
-- The bounds and or the value may be enumeration types.
481+
-- If so, they are converted to a bitvector type.
482+
-- When the enumeration is declared each literal s given the
483+
-- value of its position (starting from 0).
484+
Bound_Type_Raw : constant Irep :=
476485
Follow_Symbol_Type (Get_Type (Lower_Bound), Global_Symbol_Table);
477-
Value_Expr_Type : constant Irep :=
486+
Value_Expr_Type_Raw : constant Irep :=
478487
Follow_Symbol_Type (Get_Type (Value_Expr), Global_Symbol_Table);
479488

489+
Bound_Type : constant Irep :=
490+
(if Kind (Bound_Type_Raw) = I_C_Enum_Type then
491+
Int32_T
492+
else
493+
Bound_Type_Raw);
494+
495+
Value_Expr_Type : constant Irep :=
496+
(if Kind (Value_Expr_Type_Raw) = I_C_Enum_Type then
497+
Int32_T
498+
else
499+
Value_Expr_Type_Raw);
500+
501+
Resolved_Value_Expr : constant Irep :=
502+
(if Kind (Value_Expr_Type_Raw) = I_C_Enum_Type then
503+
Typecast_If_Necessary
504+
(Expr => Value_Expr,
505+
New_Type => Int32_T,
506+
A_Symbol_Table => Global_Symbol_Table)
507+
else
508+
Value_Expr);
509+
480510
type Adjusted_Value_And_Bounds_T is
481511
record
482512
Value_Expr : Irep;
@@ -494,17 +524,17 @@ package body Range_Check is
494524
begin
495525
if Greater_Width then
496526
return (
497-
Value_Expr => Typecast_If_Necessary
498-
(Value_Expr, Bound_Type, Global_Symbol_Table),
499-
Upper_Bound => Upper_Bound,
500-
Lower_Bound => Lower_Bound);
527+
Value_Expr => Typecast_If_Necessary
528+
(Resolved_Value_Expr, Bound_Type, Global_Symbol_Table),
529+
Upper_Bound => Upper_Bound,
530+
Lower_Bound => Lower_Bound);
501531
else
502532
return (
503-
Value_Expr => Value_Expr,
504-
Upper_Bound => Typecast_If_Necessary
505-
(Upper_Bound, Value_Expr_Type, Global_Symbol_Table),
506-
Lower_Bound => Typecast_If_Necessary
507-
(Lower_Bound, Value_Expr_Type, Global_Symbol_Table));
533+
Value_Expr => Resolved_Value_Expr,
534+
Upper_Bound => Typecast_If_Necessary
535+
(Upper_Bound, Value_Expr_Type, Global_Symbol_Table),
536+
Lower_Bound => Typecast_If_Necessary
537+
(Lower_Bound, Value_Expr_Type, Global_Symbol_Table));
508538
end if;
509539
end Get_Adjusted_Value_And_Bounds;
510540

gnat2goto/driver/tree_walk.adb

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ package body Tree_Walk is
963963
Intern (Unique_Name (Unique_Defining_Entity (U)));
964964
Unit_Symbol : Symbol;
965965
begin
966-
-- Insert all all specifications of all withed units including the
966+
-- Insert specifications of all withed units including the
967967
-- specification of the given compilation unit into the symbol table.
968968
Do_Withed_Units_Specs;
969969

@@ -1209,12 +1209,14 @@ package body Tree_Walk is
12091209
Enum_Body : constant Irep := Make_C_Enum_Members;
12101210
Enum_Type_Symbol : constant Irep := Make_Symbol_Type
12111211
(Identifier => Unique_Name (Defining_Identifier (Parent (N))));
1212-
Member : Node_Id := First (Literals (N));
1212+
First_Member : constant Node_Id := First (Literals (N));
1213+
Member : Node_Id := First_Member;
1214+
Last_Member : Node_Id := First_Member;
12131215
begin
12141216
loop
12151217
declare
12161218
Val_String : constant String :=
1217-
UI_Image (Enumeration_Rep (Member));
1219+
UI_Image (Enumeration_Pos (Member));
12181220
Val_Name : constant String := Unique_Name (Member);
12191221
Base_Name : constant String := Get_Name_String (Chars (Member));
12201222
Member_Size : constant Int := UI_To_Int (Esize (Etype (Member)));
@@ -1225,7 +1227,7 @@ package body Tree_Walk is
12251227
Member_Symbol_Init : constant Irep := Make_Constant_Expr
12261228
(I_Type => Make_Signedbv_Type (Integer (Member_Size)),
12271229
Value => Convert_Uint_To_Hex
1228-
(Enumeration_Rep (Member), Member_Size),
1230+
(Enumeration_Pos (Member), Member_Size),
12291231
Source_Location => Get_Source_Location (Member));
12301232
Typecast_Expr : constant Irep := Make_Op_Typecast
12311233
(Op0 => Member_Symbol_Init,
@@ -1239,11 +1241,19 @@ package body Tree_Walk is
12391241
Value_Expr => Typecast_Expr,
12401242
A_Symbol_Table => Global_Symbol_Table);
12411243
end;
1244+
Last_Member := Member;
12421245
Next (Member);
12431246
exit when not Present (Member);
12441247
end loop;
1248+
12451249
return Make_C_Enum_Type
1246-
(I_Subtype => Make_Signedbv_Type (32), -- FIXME why 32?
1250+
(I_Subtype =>
1251+
Make_Bounded_Signedbv_Type
1252+
(Width => 32, -- FIXME why 32?
1253+
Lower_Bound => Store_Symbol_Bound
1254+
(Bound_Type_Symbol (Do_Defining_Identifier (First_Member))),
1255+
Upper_Bound => Store_Symbol_Bound
1256+
(Bound_Type_Symbol (Do_Defining_Identifier (Last_Member)))),
12471257
I_Body => Enum_Body);
12481258
end Do_Enumeration_Definition;
12491259

@@ -4266,7 +4276,7 @@ package body Tree_Walk is
42664276
Set_Bound_Value (Upper_Bound, Upper_Bound_Value, Ok);
42674277
if not Ok then
42684278
return Report_Unhandled_Node_Type
4269-
(Lower_Bound,
4279+
(Upper_Bound,
42704280
"Do_Range_Constraint",
42714281
"unsupported upper range kind");
42724282
end if;

0 commit comments

Comments
 (0)