diff mbox series

[Ada] Crash when issuing warning on uninitialized value

Message ID 20170906115238.GA129382@adacore.com
State New
Headers show
Series [Ada] Crash when issuing warning on uninitialized value | expand

Commit Message

Arnaud Charlet Sept. 6, 2017, 11:52 a.m. UTC
When issuing a warning on a read of an uninitialized variable through
reading an attribute such as Loop_Entry, GNAT could crash. Now fixed.

GNAT issues a warning as expected on the following code:

     $ gcc -c s.adb

     1. package S is
     2.
     3.    type Array_Range is range 1 .. 10;
     4.
     5.    type IntArray is array (Array_Range) of Integer;
     6.
     7.    procedure Move (Dest, Src : aliased out IntArray);
     8.
     9. end S;

     1. package body S is
     2.
     3.    procedure Move (Dest, Src : aliased out IntArray) is
     4.    begin
     5.       for Index in Dest'Range loop
     6.          pragma Assert (for all J in Dest'First .. Index - 1 =>
     7.                           Dest (J) = Src'Loop_Entry (J));
                                  1          2
        >>> warning: "Dest" may be referenced before it has a value
        >>> warning: "Src" may be referenced before it has a value

     8.
     9.          Dest (Index) := Src (Index);
    10.          Src (Index) := 0;
    11.       end loop;
    12.    end Move;
    13.
    14. end S;

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

2017-09-06  Yannick Moy  <moy@adacore.com>

	* sem_warn.adb (Check_References): Take into
	account possibility of attribute reference as original node.
diff mbox series

Patch

Index: sem_warn.adb
===================================================================
--- sem_warn.adb	(revision 251773)
+++ sem_warn.adb	(working copy)
@@ -1382,16 +1382,22 @@ 
                   --  deal with case where original unset reference has been
                   --  rewritten during expansion.
 
-                  --  In some cases, the original node may be a type conversion
-                  --  or qualification, and in this case we want the object
-                  --  entity inside.
+                  --  In some cases, the original node may be a type
+                  --  conversion, a qualification or an attribute reference and
+                  --  in this case we want the object entity inside. Same for
+                  --  an expression with actions.
 
                   UR := Original_Node (UR);
                   while Nkind (UR) = N_Type_Conversion
                     or else Nkind (UR) = N_Qualified_Expression
                     or else Nkind (UR) = N_Expression_With_Actions
+                    or else Nkind (UR) = N_Attribute_Reference
                   loop
-                     UR := Expression (UR);
+                     if Nkind (UR) = N_Attribute_Reference then
+                        UR := Prefix (UR);
+                     else
+                        UR := Expression (UR);
+                     end if;
                   end loop;
 
                   --  Don't issue warning if appearing inside Initial_Condition