[LLVMdev] Casting.h illness

Gabor Greif gabor at mac.com
Wed Jul 21 04:42:37 PDT 2010

Hi all,

at the moment I am trying to fix an unnecessary iterator dereferencing
in Casting.h and am uncovering several ugly things.

For example, look at this code:

> // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
> // value is accepted.
> //
> template <class X, class Y>
> inline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(const Y &Val) {
>   return (Val && isa<X>(Val)) ? cast<X, Y>(Val) : 0;
> }

When Y is a pointer type all works perfectly, but when it is a (structured)
iterator we encounter several problems:

1) Val is cast to bool on the LHS of the &&-operator. This is semantically
   wrong, as we want to dereference (local jargon: simplify) Val to a
   pointer first and compare that. Also Y may have a conversion to bool,
   which may or may not coincide with comparison of the dereferenced pointer
   against NULL. In this case no compile error will occur, but we may get
   some strange behaviour.

2) When Val is an iterator, it will be simplified at least two times, namely
   in isa<> and in cast<>.

My suggestion is to simplify Val to a pointer first and then do the
comparison against NULL, the instance check and the cast.

I tried this (using getSimplifiedValue), but got further problems and had to
add a specialization

+template<typename From> struct simplify_type<From*const> {
+  typedef From* SimpleType;
+  static SimpleType &getSimplifiedValue(From*const &Val) {
+    return const_cast<From*&>(Val);
+  }

Is there a simpler way to accomplish this?



More information about the llvm-dev mailing list