aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2018-01-11 08:51:18 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-01-11 08:51:18 +0000
commit5cb78fb862e7eb963c0c6d0ce2deae5b8112858d (patch)
treed38aa5ce709ef20817faa445aac7be4a27f8c5e6 /gcc
parent94ce49419aef75f3414edcaeba89e63c6c3be320 (diff)
downloadgcc-5cb78fb862e7eb963c0c6d0ce2deae5b8112858d.zip
gcc-5cb78fb862e7eb963c0c6d0ce2deae5b8112858d.tar.gz
gcc-5cb78fb862e7eb963c0c6d0ce2deae5b8112858d.tar.bz2
[Ada] Illegal protected calls in inherited pre/postconditions
AI12-0166 specifies that it is illegal for a pre/postcondition of a protected operation to contain an internal call to a protected function. This patch completes the implementation of this rule in the case the condition is inherited from a classwide condition of an abstract operation of an interface type. Compiling inheritpo.adb must yield: inheritpo.ads:9:04: instantiation error at line 6 inheritpo.ads:9:04: internal call to "F" cannot appear in inherited precondition of protected operation "P" inheritpo.ads:9:04: instantiation error at line 7 inheritpo.ads:9:04: internal call to "F" cannot appear in inherited precondition of protected operation "P" -- package InheritPO is type T is limited interface; function F (X : T) return Boolean is abstract; procedure P (X : in out T) is abstract with Pre'Class => X.F, Post'Class => X.F; protected type PT is new T with overriding function F return Boolean; overriding procedure P; end PT; end InheritPO; ---- package body InheritPO is protected body PT is function F return Boolean is begin return True; end; procedure P is begin null; end; end PT; end InheritPO; 2018-01-11 Ed Schonberg <schonberg@adacore.com> gcc/ada/ * sem_ch3.adb (Add_Internal_Interface_Entities): When checking the legality of an inherited operation that may require overriding, ignore primitive_wrappers that correspond to explicit operations that override an interface primitive. * exp_util.adb (Build_Class_Wide_Expression, Replace_Entity): If the operation to which the class-wide expression applies is a protected op. with a primitive_wrapper, verify that the updated inherited expression does not contain an internal call to a protected function. This completes the implementation of AI12-0166. From-SVN: r256491
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog12
-rw-r--r--gcc/ada/exp_util.adb18
-rw-r--r--gcc/ada/sem_ch3.adb6
3 files changed, 35 insertions, 1 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 550b760..1d19333 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,15 @@
+2018-01-11 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Add_Internal_Interface_Entities): When checking the
+ legality of an inherited operation that may require overriding, ignore
+ primitive_wrappers that correspond to explicit operations that override
+ an interface primitive.
+ * exp_util.adb (Build_Class_Wide_Expression, Replace_Entity): If the
+ operation to which the class-wide expression applies is a protected op.
+ with a primitive_wrapper, verify that the updated inherited expression
+ does not contain an internal call to a protected function. This
+ completes the implementation of AI12-0166.
+
2018-01-11 Hristian Kirtchev <kirtchev@adacore.com>
* ali.adb: Document the remaining letters available for ALI lines.
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 9ccaa78..058bfe4 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -1129,6 +1129,24 @@ package body Exp_Util is
if Present (New_E) then
Rewrite (N, New_Occurrence_Of (New_E, Sloc (N)));
+ -- Implement rule in AI12-0166: a precondition for a
+ -- protected operation cannot include an internal call to
+ -- a protected function of the type. In the case of an
+ -- inherited condition for an overriding operation, both the
+ -- operation and the function are given by primitive wrappers.
+
+ if Ekind (New_E) = E_Function
+ and then Is_Primitive_Wrapper (New_E)
+ and then Is_Primitive_Wrapper (Subp)
+ and then Scope (Subp) = Scope (New_E)
+ then
+ Error_Msg_Node_2 := Wrapped_Entity (Subp);
+ Error_Msg_NE
+ ("internal call to& cannot appear in inherited "
+ & "precondition of protected operation&",
+ N, Wrapped_Entity (New_E));
+ end if;
+
-- If the entity is an overridden primitive and we are not
-- in GNATprove mode, we must build a wrapper for the current
-- inherited operation. If the reference is the prefix of an
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 715e6da..0e89822 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -1732,6 +1732,9 @@ package body Sem_Ch3 is
-- nonconforming preconditions in both an ancestor and
-- a progenitor operation.
+ -- If the operation is a primitive wrapper it is an explicit
+ -- (overriding) operqtion and all is fine.
+
if Present (Anc)
and then Has_Non_Trivial_Precondition (Anc)
and then Has_Non_Trivial_Precondition (Iface_Prim)
@@ -1742,10 +1745,11 @@ package body Sem_Ch3 is
and then Nkind (Parent (Prim)) =
N_Procedure_Specification
and then Null_Present (Parent (Prim)))
+ or else Is_Primitive_Wrapper (Prim)
then
null;
- -- The inherited operation must be overridden
+ -- The operation is inherited and must be overridden.
elsif not Comes_From_Source (Prim) then
Error_Msg_NE