diff mbox series

[Ada] Spurious non-variable error on implicitly dereferenced in-mode formal

Message ID 20211004084745.GA1536629@adacore.com
State New
Headers show
Series [Ada] Spurious non-variable error on implicitly dereferenced in-mode formal | expand

Commit Message

Pierre-Marie de Rodat Oct. 4, 2021, 8:47 a.m. UTC
This patch corrects an issue in the compiler whereby taking 'Access of a
protected subprogram based on an implicitly dereferenced protected
object causes a spurious non-variable error when such an object is an
in-mode access type formal.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

	* sem_util.adb (Is_Variable): Add check for implicitly
	dereferenced access types
	(Is_Dependent_Component_Of_Mutable_Object): Set Prefix_Type when
	not specified.
diff mbox series

Patch

diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -16868,6 +16868,15 @@  package body Sem_Util is
             end if;
 
             if Is_Entity_Name (P) then
+               --  The Etype may not be set on P (which is wrong) in certain
+               --  corner cases involving the deprecated front-end inlining of
+               --  subprograms (via -gnatN), so use the Etype set on the
+               --  the entity for these instances since we know it is present.
+
+               if No (Prefix_Type) then
+                  Prefix_Type := Etype (Entity (P));
+               end if;
+
                if Ekind (Entity (P)) = E_Generic_In_Out_Parameter then
                   Prefix_Type := Base_Type (Prefix_Type);
                end if;
@@ -21145,6 +21154,9 @@  package body Sem_Util is
    -- Is_Variable --
    -----------------
 
+   --  Should Is_Variable be refactored to better handle dereferences and
+   --  technical debt ???
+
    function Is_Variable
      (N                 : Node_Id;
       Use_Original_Node : Boolean := True) return Boolean
@@ -21313,6 +21325,10 @@  package body Sem_Util is
                         and then Nkind (Parent (E)) /= N_Exception_Handler)
               or else (K = E_Component
                         and then not In_Protected_Function (E))
+              or else (Present (Etype (E))
+                        and then Is_Access_Object_Type (Etype (E))
+                        and then Is_Access_Variable (Etype (E))
+                        and then Is_Dereferenced (N))
               or else K = E_Out_Parameter
               or else K = E_In_Out_Parameter
               or else K = E_Generic_In_Out_Parameter