aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJavier Miranda <miranda@adacore.com>2022-03-18 19:28:52 +0000
committerPierre-Marie de Rodat <derodat@adacore.com>2022-05-17 08:25:41 +0000
commitc30e5ab027a59a2ffcf7fb2d093ce2b64de712eb (patch)
tree538497cb00998337b189efcfa00a810dbda7b7b1 /gcc
parentd4090614041c7803373a5064dfb82fdf6017971d (diff)
downloadgcc-c30e5ab027a59a2ffcf7fb2d093ce2b64de712eb.zip
gcc-c30e5ab027a59a2ffcf7fb2d093ce2b64de712eb.tar.gz
gcc-c30e5ab027a59a2ffcf7fb2d093ce2b64de712eb.tar.bz2
[Ada] Spurious error on subprogram with class-wide preconditions
gcc/ada/ * freeze.adb (Build_DTW_Spec): Do not inherit the not-overriding indicator because the DTW wrapper overrides its wrapped subprogram. * contracts.ads (Make_Class_Precondition_Subps): Adding documentation.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/contracts.ads33
-rw-r--r--gcc/ada/freeze.adb7
2 files changed, 40 insertions, 0 deletions
diff --git a/gcc/ada/contracts.ads b/gcc/ada/contracts.ads
index adbb0e6..5178373 100644
--- a/gcc/ada/contracts.ads
+++ b/gcc/ada/contracts.ads
@@ -226,6 +226,39 @@ package Contracts is
-- overrides an inherited class-wide precondition (see AI12-0195-1).
-- Late_Overriding enables special handling required for late-overriding
-- subprograms.
+ --
+ -- For example, if we have a subprogram with the following profile:
+ --
+ -- procedure Prim (Obj : TagTyp; <additional formals>)
+ -- with Pre'Class => F1 (Obj) and F2(Obj)
+ --
+ -- We build the following helper that evaluates statically the class-wide
+ -- precondition:
+ --
+ -- function PrimSP (Obj : TagTyp) return Boolean is
+ -- begin
+ -- return F1 (Obj) and F2(Obj);
+ -- end PrimSP;
+ --
+ -- ... and the following helper that evaluates dynamically the class-wide
+ -- precondition:
+ --
+ -- function PrimDP (Obj : TagTyp'Class; ...) return Boolean is
+ -- begin
+ -- return F1 (Obj) and F2(Obj);
+ -- end PrimSP;
+ --
+ -- ... and the following indirect-call wrapper (ICW) that is used by the
+ -- code generated by the compiler for indirect calls:
+ --
+ -- procedure PrimICW (Obj : TagTyp; <additional formals> is
+ -- begin
+ -- if not PrimSP (Obj) then
+ -- $raise_assert_failure ("failed precondition in call at ...");
+ -- end if;
+ --
+ -- Prim (Obj, ...);
+ -- end Prim;
procedure Merge_Class_Conditions (Spec_Id : Entity_Id);
-- Merge and preanalyze all class-wide conditions of Spec_Id (class-wide
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 7d90f51..ca0ffe3 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -1619,6 +1619,13 @@ package body Freeze is
DTW_Spec := Build_Overriding_Spec (Par_Prim, R);
DTW_Id := Defining_Entity (DTW_Spec);
+ -- Clear the not-overriding indicator since the DTW wrapper overrides
+ -- its wrapped subprogram; required because if present in the parent
+ -- primitive, given that Build_Overriding_Spec inherits it, we report
+ -- spurious errors.
+
+ Set_Must_Not_Override (DTW_Spec, False);
+
-- Add minimal decoration of fields
Mutate_Ekind (DTW_Id, Ekind (Par_Prim));