aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_spark.adb
diff options
context:
space:
mode:
authorClaire Dross <dross@adacore.com>2019-08-19 08:35:53 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2019-08-19 08:35:53 +0000
commitef1c6c0e5499a83be7f86ccf64e3eb8814137cc9 (patch)
tree81016f920eb043f5bcee222144f2c74e9403211e /gcc/ada/sem_spark.adb
parent123f02156122ea13f3bfabdef2b6385a25527158 (diff)
downloadgcc-ef1c6c0e5499a83be7f86ccf64e3eb8814137cc9.zip
gcc-ef1c6c0e5499a83be7f86ccf64e3eb8814137cc9.tar.gz
gcc-ef1c6c0e5499a83be7f86ccf64e3eb8814137cc9.tar.bz2
[Ada] Allow reading a borrowed object inside a call to a pledge function
No impact on regular compilation. 2019-08-19 Claire Dross <dross@adacore.com> gcc/ada/ * sem_spark.ads, sem_spark.adb (Is_Pledge_Function): New parameter of the generic. Function used to decide whether a function is a pledge function. (Check_Not_Borrowed): Disable check inside the second parameter of a pledge function for the path borrowed by the first parameter. Also disable checks for entities inside a Global contract. From-SVN: r274644
Diffstat (limited to 'gcc/ada/sem_spark.adb')
-rw-r--r--gcc/ada/sem_spark.adb36
1 files changed, 36 insertions, 0 deletions
diff --git a/gcc/ada/sem_spark.adb b/gcc/ada/sem_spark.adb
index b0686b7..30e1426 100644
--- a/gcc/ada/sem_spark.adb
+++ b/gcc/ada/sem_spark.adb
@@ -5008,13 +5008,49 @@ package body Sem_SPARK is
Get_First_Key (Current_Borrowers);
Var : Entity_Id;
Borrowed : Node_Id;
+ B_Pledge : Entity_Id := Empty;
begin
+ -- Search for a call to a pledge function or a global pragma in
+ -- the parents of Expr.
+
+ declare
+ Call : Node_Id := Expr;
+ begin
+ while Present (Call)
+ and then
+ (Nkind (Call) /= N_Function_Call
+ or else not Is_Pledge_Function (Get_Called_Entity (Call)))
+ loop
+ -- Do not check for borrowed objects in global contracts
+ -- ??? However we should keep these objects in the borrowed
+ -- state when verifying the subprogram so that we can make
+ -- sure that they are only read inside pledges.
+ -- ??? There is probably a better way to disable checking of
+ -- borrows inside global contracts.
+
+ if Nkind (Call) = N_Pragma
+ and then Get_Pragma_Id (Pragma_Name (Call)) = Pragma_Global
+ then
+ return;
+ end if;
+
+ Call := Parent (Call);
+ end loop;
+
+ if Present (Call)
+ and then Nkind (First_Actual (Call)) in N_Has_Entity
+ then
+ B_Pledge := Entity (First_Actual (Call));
+ end if;
+ end;
+
while Key.Present loop
Var := Key.K;
Borrowed := Get (Current_Borrowers, Var);
if Is_Prefix_Or_Almost (Pref => Borrowed, Expr => Expr)
+ and then Var /= B_Pledge
and then Emit_Messages
then
Error_Msg_Sloc := Sloc (Borrowed);