--- /dev/null
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Opt106_Pkg1; use Opt106_Pkg1;
+
+procedure Opt106 is
+ Obj : T := (False, 0, 0, 0, True);
+
+begin
+ Proc (Obj, 0, False, True);
+end;
--- /dev/null
+with Opt106_Pkg2; use Opt106_Pkg2;
+
+package body Opt106_Pkg1 is
+
+ procedure Proc (Obj : in out T;
+ Data : Integer;
+ Last : Boolean;
+ Stretch : Boolean) is
+
+ begin
+ if Stretch and then (Obj.Delayed /= 0 or else not Obj.Attach_Last) then
+ raise Program_Error;
+ end if;
+
+ if Obj.Delayed /= 0 then
+ Stop (Obj.Delayed, Obj.Before, Data, False);
+ end if;
+
+ if Last or (Obj.Delayed = 0 and not Stretch) then
+ Stop (Data, Obj.Before, 0, Last);
+
+ if Last then
+ Obj.Initialized := False;
+ else
+ Obj.Next := 0;
+ Obj.Before := Data;
+ end if;
+
+ else
+ if Stretch then
+ Obj.Next := 1;
+ else
+ Obj.Before := Obj.Delayed;
+ end if;
+ Obj.Delayed := Data;
+ end if;
+ end;
+
+end Opt106_Pkg1;
--- /dev/null
+package Opt106_Pkg1 is
+
+ type T is record
+ Initialized : Boolean;
+ Before : Integer;
+ Delayed : Integer;
+ Next : Integer;
+ Attach_Last : Boolean;
+ end record;
+
+ procedure Proc (Obj : in out T;
+ Data : Integer;
+ Last : Boolean;
+ Stretch : Boolean);
+
+end Opt106_Pkg1;
--- /dev/null
+package body Opt106_Pkg2 is
+
+ procedure Stop (Delayed : Integer;
+ Before : Integer;
+ After : Integer;
+ Last : Boolean) is
+ begin
+ raise Program_Error;
+ end;
+
+end Opt106_Pkg2;
--- /dev/null
+package Opt106_Pkg2 is
+
+ procedure Stop (Delayed : Integer;
+ Before : Integer;
+ After : Integer;
+ Last : Boolean);
+
+end Opt106_Pkg2;
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
- /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
- if all the bits being cleared are already cleared or
- all the bits being set are already set. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
+ /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR if all the bits
+ being cleared are already cleared or all the bits being set
+ are already set. Beware that boolean types must be handled
+ logically (see range-op.cc) unless they have precision 1. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+ && (TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE
+ || TYPE_PRECISION (TREE_TYPE (rhs1)) == 1))
return simplify_bit_ops_using_ranges (gsi, stmt);
break;