diff mbox

[Ada] Fix missing index check with optimization on

Message ID 20150205112245.GA20558@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Feb. 5, 2015, 11:22 a.m. UTC
In some unusual cases, the index check on a subscript of an
unconstrained array was omitted.

The following test program

     1. package Out_Constraint_Violation is
     2.    type Arr is array (Natural range <>) of Integer;
     3.    procedure Violate
     4.      (Input : Arr; Modifier : Arr; Output: out Arr);
     5. end Out_Constraint_Violation;

     1. package body Out_Constraint_Violation is
     2.    procedure Violate
     3.      (Input : Arr; Modifier : Arr; Output: out Arr) is
     4.    begin
     5.       for J in Input'Range loop
     6.          --  For the error to occur,
     7.          --  we need to have a declare block ...
     8.          declare
     9.             --  ... with at least this level of complexity.
    10.             Product : constant Integer := Modifier (J);
    11.          begin
    12.             Output (J) := Product / 2;
    13.          end;
    14.       end loop;
    15.    end Violate;
    16. end Out_Constraint_Violation;

     1. with Ada.Text_IO; use Ada.Text_IO;
     2. procedure Out_Constraint_Violation.Main is
     3.    Size : constant := 10;
     4.    Input : Arr (1 .. Size) := (others => 128);
     5.    Modifier : Arr (1 .. Size) := (others => 128);
     6.    Output : Arr (1 .. Size + 1) := (others => 42);
     7. begin
     8.    Violate (Input, Modifier, Output (1 .. Size - 1));
     9.    Put_Line ("Size:" & Integer'Image (Size));
    10.    for L in Size - 1 .. Size + 1 loop
    11.       Put_Line ("Output(" & L'Img & "):"  &
    12.                 Output (L)'Img);
    13.    end loop;
    14. end Out_Constraint_Violation.Main;

If compiled with -O should raise CE at run time:

raised CONSTRAINT_ERROR :
 out_constraint_violation.adb:12 index check failed

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

2015-02-05  Robert Dewar  <dewar@adacore.com>

	* checks.adb (Enable_Range_Check): Disconnect attempted
	optimization for the case of range check for subscript of
	unconstrained array.
diff mbox

Patch

Index: checks.adb
===================================================================
--- checks.adb	(revision 220439)
+++ checks.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2014, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -5521,10 +5521,14 @@ 
                   return;
                end if;
 
-            --  Ditto if the prefix is an explicit dereference whose designated
-            --  type is unconstrained.
+            --  Ditto if prefix is simply an unconstrained array. We used
+            --  to think this case was OK, if the prefix was not an explicit
+            --  dereference, but we have now seen a case where this is not
+            --  true, so it is safer to just suppress the optimization in this
+            --  case. The back end is getting better at eliminating redundant
+            --  checks in any case, so the loss won't be important.
 
-            elsif Nkind (Prefix (P)) = N_Explicit_Dereference
+            elsif Is_Array_Type (Atyp)
               and then not Is_Constrained (Atyp)
             then
                Activate_Range_Check (N);