[Ada] Fix bug in handling of arrays of boolean

Arnaud Charlet charlet@adacore.com
Fri Feb 17 16:13:00 GMT 2006


Test on i686-linux, committed on trunk.

Code has a fall-through rather than a return, and as a result type of
node was assigned an illegal value for the back-end.

Also: boolean operations apply to arrays of booleans. During the first pass of
type resolution, an aggregate must be considered legal in any context
where a composite type may appear; its expected type is only determined
during the second pass. If the immediate context is a boolean operation,
the aggregate may be legal if the other operand is also an aggregate, or
if it has one interpretation that is a boolean array. Previous code treated
an aggregate as always legal, leading to spurious ambiguities.
The following must compile quietly:
--
procedure P is
   type T1 is record
      A : Integer;
   end record;
   type T2 is array (Positive range <>) of T1;
   function "and" (L, R : T2) return T2 is
   begin
      return (1 => (A => 2));
   end "and";
   X : T2 (1 .. 2) := (others => (A => 0));
   Y : T2 := (1 => (A => 3)) and X;
begin
   null;
end;

2006-02-17  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch4.adb (Find_Boolean_Types): If one of the operands is an
	aggregate, check the interpretations of the other operand to find one
	that may be a boolean array.
	(Analyze_Selected_Component): Fix flow-of-control typo in case where
	the prefix is a private extension.

-------------- next part --------------
Index: sem_ch4.adb
===================================================================
--- sem_ch4.adb	(revision 111176)
+++ sem_ch4.adb	(working copy)
@@ -2953,7 +2953,7 @@
                      Set_Entity_With_Style_Check (Sel, Comp);
                      Set_Etype (Sel, Etype (Comp));
                      Set_Etype (N,   Etype (Comp));
-                     exit;
+                     return;
                   end if;
 
                   Next_Component (Comp);
@@ -3841,6 +3841,31 @@
                end loop;
             end if;
 
+         --  If operands are aggregates, we must assume that they may be
+         --  boolean arrays, and leave disambiguation for the second pass.
+         --  If only one is an aggregate, verify that the other one has an
+         --  interpretation as a boolean array
+
+         elsif Nkind (L) = N_Aggregate then
+            if Nkind (R) = N_Aggregate then
+               Add_One_Interp (N, Op_Id, Etype (L));
+
+            elsif not Is_Overloaded (R) then
+               if Valid_Boolean_Arg (Etype (R)) then
+                  Add_One_Interp (N, Op_Id, Etype (R));
+               end if;
+
+            else
+               Get_First_Interp (R, Index, It);
+               while Present (It.Typ) loop
+                  if Valid_Boolean_Arg (It.Typ) then
+                     Add_One_Interp (N, Op_Id, It.Typ);
+                  end if;
+
+                  Get_Next_Interp (Index, It);
+               end loop;
+            end if;
+
          elsif Valid_Boolean_Arg (Etype (L))
            and then Has_Compatible_Type (R, Etype (L))
          then


More information about the Gcc-patches mailing list