On Wed, 20 Jun 2007, Michael Matz wrote: > Hi, > > On Wed, 20 Jun 2007, Richard Guenther wrote: > > > /* If the outer type is (void *), then the conversion is not > > necessary. > > ??? This makes tree_ssa_useless_type_conversion_1 not > > transitive. */ > > Not this line itself makes it not transitive, but the fact that it still > relies on the frontends langhooks makes it so. Document that fact so it's > clear that when the final goal is implemented (langhook removed) this > doesn't violate transitivity.
Done. > > if (TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE) > > return true; > > > > /* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a > > ! useless type conversion, otherwise return false. > > ! This function implicitly defines the middle-end type system. The > > ! following invariants shall be fulfilled: > > ! > > ! 1) tree_ssa_useless_type_conversion_1 is transitive. If > > ! a < b and b < c then a < c. > > ! > > ! 2) tree_ssa_useless_type_conversion_1 is not communtative. > > ! From a < b does not follow a > b. > > ! > > ! 3) Conversions are useless only if with the resulting type > > Something is missing in this sentence. Perhaps "if _values_ with the > resulting type ..."? The whole sentence reads strange, though. > Operations are not applied to types but to values. Types actually _are_ > exactly the set of operations applicable to values. > > Perhaps reformulate the whole thing to something like: > > 3) Types define the available set of operations applicable to values. A > type conversion is useless if the operations for the target type is a > subset of the operations for the source type. For example casts to > void* are useless, casts from void* are not (void* can't be > dereferenced or offsetted, but copied, hence its set of operations is > a strict subset of that of all other data pointer types). Casts to > const T* are useless (can't be written to), casts from const T* to T* > are not. I've copied your rewrite. Thanks, Richard.