> Lets go with this patch and hopefully stabilize the tree. I don't think the
> vector conversions represent an important case.
Unfortunately the patch introduces GIMPLE checking failures in Ada so it will
need to be completed/improved. But let's postpone it because we have another
class of GIMPLE checking failures introduced by the useless_type_conversion_p
change itself:
c37213j.adb:21:05: warning: variable "X" is read but never assigned
c37213j.adb: In function 'C37213J.PROC.CONSTPROP':
c37213j.adb:41:4: error: invalid conversion in gimple call
struct c37213j__proc__value___PAD
struct c37213j__proc__value___PAD
# .MEM_38 = VDEF <.MEM_37>
MEM[(struct c37213j__proc__value___PAD *)R.12_25] = c37213j.proc.value ();
[static-chain: &FRAME.39] [return slot optimization]
and:
eric@polaris:~/build/gcc/native> ~/install/gnat-head/bin/gcc -S c37213j.adb -
O2
c37213j.adb:21:05: warning: variable "X" is read but never assigned
c37213j.adb: In function 'C37213J.PROC.VALUE':
c37213j.adb:26:5: error: invalid conversion in return statement
struct c37213j__proc__value___PAD
struct c37213j__proc__value___PAD
# VUSE <.MEM_11>
return _9(D);
What happens here is that GIMPLE statements are remapped through cloning and
we have a variably-modified type returned by a nested function, so the type of
the LHS of a GIMPLE_CALL or that of the RHS of a GIMPLE_RETURN is remapped but
of course not the return type of the function. This used to be OK because
remapping is done by means of copy_node and preserves TYPE_CANONICAL, so the
conversion between remapped and original type was deemed useless; now the
TYPE_CANONICAL check is gone so the conversion is not useless anymore...
I don't think that we want to introduce an artificial VCE to fix this so we
probably need a couple of kludges in the GIMPLE verifier instead.
In any case, the more I look into the fallout of the useless_type_conversion_p
change, the more I find it ill-advised. We used to have a solid type system
in the middle-end by means of the predicate and now we have cases for which it
ought to return false and returns true (e.g. non-structurally equivalent types
with different calling conventions) and cases for which it can return true and
returns false (remapped types or types deemed equivalent by the languages).
I don't really know what it was made for, but there must be a better way...
* gnat.dg/discr45.adb: New test.
--
Eric Botcazou
-- { dg-do run }
-- { dg-options "-O2 -gnatws" }
procedure Discr45 is
function Ident_Int (I : Integer) return Integer is
begin
return I;
end;
procedure Proc (Signal : Boolean) is
subtype Index is Integer range 1..10;
type My_Arr is array (Index range <>) OF Integer;
type Rec (D3 : Integer := Ident_Int(1)) is record
case D3 is
when -5..10 => C1 : My_Arr(D3..Ident_Int(11));
when Others => C2 : Integer := Ident_Int(5);
end case;
end record;
X : Rec;
function Value return Rec;
pragma No_Inline (Value);
function Value return Rec is
begin
return X;
end;
begin
if X /= Value then
raise Constraint_Error;
elsif Signal then
raise Program_Error;
end if;
end;
begin
Proc (True);
end;