aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Squirek <squirek@adacore.com>2021-09-23 11:04:25 -0400
committerPierre-Marie de Rodat <derodat@adacore.com>2021-10-20 10:17:05 +0000
commit50cdd660b2ac54abb2659c7a88200d4c2fd1f195 (patch)
tree5ec9621b4e1d70c4339b83d15b50d50d39449526
parent9267014b351edf5aa0d0951545ec405edec5e3f5 (diff)
downloadgcc-50cdd660b2ac54abb2659c7a88200d4c2fd1f195.zip
gcc-50cdd660b2ac54abb2659c7a88200d4c2fd1f195.tar.gz
gcc-50cdd660b2ac54abb2659c7a88200d4c2fd1f195.tar.bz2
[Ada] Missing accessibility check when returning discriminated types
gcc/ada/ * sem_ch6.adb (Check_Return_Construct_Accessibility): Modify generation of accessibility checks to be more consolidated and get triggered properly in required cases. * sem_util.adb (Accessibility_Level): Add extra check within condition to handle aliased formals properly in more cases.
-rw-r--r--gcc/ada/sem_ch6.adb54
-rw-r--r--gcc/ada/sem_util.adb6
2 files changed, 32 insertions, 28 deletions
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index a316214..1486918 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -807,6 +807,7 @@ package body Sem_Ch6 is
Assoc_Expr : Node_Id;
Assoc_Present : Boolean := False;
+ Check_Cond : Node_Id;
Unseen_Disc_Count : Nat := 0;
Seen_Discs : Elist_Id;
Disc : Entity_Id;
@@ -1180,36 +1181,39 @@ package body Sem_Ch6 is
and then Present (Disc)
and then Ekind (Etype (Disc)) = E_Anonymous_Access_Type
then
- -- Perform a static check first, if possible
+ -- Generate a dynamic check based on the extra accessibility of
+ -- the result or the scope.
+
+ Check_Cond :=
+ Make_Op_Gt (Loc,
+ Left_Opnd => Accessibility_Level
+ (Expr => Assoc_Expr,
+ Level => Dynamic_Level,
+ In_Return_Context => True),
+ Right_Opnd => (if Present
+ (Extra_Accessibility_Of_Result
+ (Scope_Id))
+ then
+ Extra_Accessibility_Of_Result (Scope_Id)
+ else
+ Make_Integer_Literal
+ (Loc, Scope_Depth (Scope (Scope_Id)))));
+
+ Insert_Before_And_Analyze (Return_Stmt,
+ Make_Raise_Program_Error (Loc,
+ Condition => Check_Cond,
+ Reason => PE_Accessibility_Check_Failed));
+
+ -- If constant folding has happened on the condition for the
+ -- generated error, then warn about it being unconditional when
+ -- we know an error will be raised.
- if Static_Accessibility_Level
- (Expr => Assoc_Expr,
- Level => Zero_On_Dynamic_Level,
- In_Return_Context => True)
- > Scope_Depth (Scope (Scope_Id))
+ if Nkind (Check_Cond) = N_Identifier
+ and then Entity (Check_Cond) = Standard_True
then
Error_Msg_N
("access discriminant in return object would be a dangling"
& " reference", Return_Stmt);
-
- exit;
- end if;
-
- -- Otherwise, generate a dynamic check based on the extra
- -- accessibility of the result.
-
- if Present (Extra_Accessibility_Of_Result (Scope_Id)) then
- Insert_Before_And_Analyze (Return_Stmt,
- Make_Raise_Program_Error (Loc,
- Condition =>
- Make_Op_Gt (Loc,
- Left_Opnd => Accessibility_Level
- (Expr => Assoc_Expr,
- Level => Dynamic_Level,
- In_Return_Context => True),
- Right_Opnd => Extra_Accessibility_Of_Result
- (Scope_Id)),
- Reason => PE_Accessibility_Check_Failed));
end if;
end if;
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index b8ed8a4..db4d55a 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -628,9 +628,9 @@ package body Sem_Util is
-- caller.
if Is_Explicitly_Aliased (E)
- and then Level /= Dynamic_Level
- and then (In_Return_Value (Expr)
- or else In_Return_Context)
+ and then (In_Return_Context
+ or else (Level /= Dynamic_Level
+ and then In_Return_Value (Expr)))
then
return Make_Level_Literal (Scope_Depth (Standard_Standard));