This patch fixes a spurious error on a dynamic predicate of a record
subtype when the expression for the predicate includes a selected
component that denotes a component of the subtype.
Tested on x86_64-pc-linux-gnu, committed on trunk
2019-07-03 Ed Schonberg <schonb...@adacore.com>
gcc/ada/
* sem_ch8.adb (Find_Selected_Component): If the prefix is the
current instance of a type or subtype, complete the resolution
of the name by finding the component of the type denoted by the
selector name.
gcc/testsuite/
* gnat.dg/predicate4.adb, gnat.dg/predicate4_pkg.ads: New
testcase.
--- gcc/ada/sem_ch8.adb
+++ gcc/ada/sem_ch8.adb
@@ -7418,10 +7418,28 @@ package body Sem_Ch8 is
-- It is not an error if the prefix is the current instance of
-- type name, e.g. the expression of a type aspect, when it is
- -- analyzed for ASIS use.
+ -- analyzed for ASIS use, or within a generic unit. We still
+ -- have to verify that a component of that name exists, and
+ -- decorate the node accordingly.
elsif Is_Entity_Name (P) and then Is_Current_Instance (P) then
- null;
+ declare
+ Comp : Entity_Id;
+
+ begin
+ Comp := First_Entity (Entity (P));
+ while Present (Comp) loop
+ if Chars (Comp) = Chars (Selector_Name (N)) then
+ Set_Entity (N, Comp);
+ Set_Etype (N, Etype (Comp));
+ Set_Entity (Selector_Name (N), Comp);
+ Set_Etype (Selector_Name (N), Etype (Comp));
+ return;
+ end if;
+
+ Next_Entity (Comp);
+ end loop;
+ end;
elsif Ekind (P_Name) = E_Void then
Premature_Usage (P);
--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/predicate4.adb
@@ -0,0 +1,19 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+with System.Assertions; use System.Assertions;
+with Predicate4_Pkg;
+procedure Predicate4 is
+ type V is new Float;
+ package MXI2 is new Predicate4_Pkg (V);
+ use MXI2;
+ OK : Lt := (Has => False);
+begin
+ declare
+ Wrong : Lt := (Has => True, MX => 3.14);
+ begin
+ raise Program_Error;
+ end;
+exception
+ when Assert_Failure => null;
+end;
--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/predicate4_pkg.ads
@@ -0,0 +1,16 @@
+generic
+ type Value_Type is private;
+package Predicate4_Pkg is
+ type MT (Has : Boolean := False) is record
+ case Has is
+ when False =>
+ null;
+ when True =>
+ MX : Value_Type;
+ end case;
+ end record;
+
+ function Foo (M : MT) return Boolean is (not M.Has);
+ subtype LT is MT with Dynamic_Predicate => not LT.Has;
+ function Bar (M : MT) return Boolean is (Foo (M));
+end;