if (empty_range_varying (r, type, lh, rh))
return true;
- if (lh.varying_p () || lh.undefined_p ())
- r = lh;
- else
- {
- r = lh;
- r.invert ();
- }
- gcc_checking_assert (lh.type() == type);
+ r = lh;
+ if (!lh.varying_p () && !lh.undefined_p ())
+ r.invert ();
+
return true;
}
bool
operator_logical_not::op1_range (irange &r,
- tree type ATTRIBUTE_UNUSED,
+ tree type,
const irange &lhs,
- const irange &op2 ATTRIBUTE_UNUSED) const
+ const irange &op2) const
{
- r = lhs;
- if (!lhs.varying_p () && !lhs.undefined_p ())
- r.invert ();
- return true;
+ // Logical NOT is involutary...do it again.
+ return fold_range (r, type, lhs, op2);
}
if (empty_range_varying (r, type, lh, rh))
return true;
+ if (types_compatible_p (type, boolean_type_node))
+ return op_logical_not.fold_range (r, type, lh, rh);
+
// ~X is simply -1 - X.
int_range<1> minusone (type, wi::minus_one (TYPE_PRECISION (type)),
wi::minus_one (TYPE_PRECISION (type)));
const irange &lhs,
const irange &op2) const
{
+ if (types_compatible_p (type, boolean_type_node))
+ return op_logical_not.op1_range (r, type, lhs, op2);
+
// ~X is -1 - X and since bitwise NOT is involutary...do it again.
return fold_range (r, type, lhs, op2);
}
--- /dev/null
+-- { dg-do run }
+-- { dg-options "-O -ftree-vrp -fno-inline" }
+
+procedure Opt88 is
+
+ Val : Integer := 1;
+
+ procedure Dummy (B : out Boolean) is
+ begin
+ B := True;
+ end;
+
+ function Test return Boolean is
+ begin
+ return False;
+ end;
+
+ procedure Do_It (OK : out Boolean) is
+
+ Blue : Boolean := False;
+ Red : Boolean := False;
+
+ begin
+ OK := True;
+ Blue := True;
+ Dummy (Red);
+
+ if Red then
+ Red := False;
+
+ if Test then
+ Dummy (Red);
+ end if;
+ end if;
+
+ if Blue and not Red then
+ Val := 0;
+ end if;
+
+ if Red then
+ OK := False;
+ end if;
+ end;
+
+ OK : Boolean;
+
+begin
+ Do_It (OK);
+ if not OK then
+ raise Program_Error;
+ end if;
+end;