[patch, spu] Fix overloaded builtin resolution with C++

Ulrich Weigand uweigand@de.ibm.com
Thu Feb 18 18:27:00 GMT 2010


Hello,

in certain cases, compiling the following code:

int main (void)
{
  __vector double vec = __builtin_spu_splats (0.5);
}

as *C++* code (using spu-g++) for spu-elf, we get invalid error
messages like:

test.cc:3: error: cannot convert `float __vector__' to `double 
 __vector__' in initialization

This is because overload resolution of the spu_splats builtin selects
(incorrectly) the "float" variant instead of "double" one.
This is supposed to be prevented by this piece of code in
spu-c.c:spu_resolve_overloaded_builtin:

          /* The intrinsics spec does not specify precisely how to
             resolve generic intrinsics.  We require an exact match
             for vector types and let C do it's usual parameter type
             checking/promotions for scalar arguments, except for the
             first argument of intrinsics which don't have a vector
             parameter. */
          if ((!SCALAR_TYPE_P (param_type)
               || !SCALAR_TYPE_P (arg_type)
               || (all_scalar && p == 0))
              && !comptypes (TYPE_MAIN_VARIANT (param_type),
                             TYPE_MAIN_VARIANT (arg_type)))

For spu_splats, "all_scalar" will be true, and thus "comptypes"
will be used to check whether the actual argument type is
compatible with the formal parameter type. "float" should not
be compatible with "double", and thus this choice ought to
be rejected.

However, there are actually *two* different versions of "comptypes":
one defined in c-typeck.c, which is used for the C compiler build (cc1),
and a *different* version in cp/cp-typeck.c, which is used for the C++
compiler build (cc1plus).

Unfortunately, the C++ version has *three* arguments.  The SPU back-
end always calls the function with two arguments ...  This means that
this call actually invokes undefined behaviour.  Depending on the
platform and the host compiler used, this might indeed cause wrong
code to be generated.

The following patch fixes this by using the appropriate language-
specific callback to perform type comparison instead.

Tested with no regressions on spu-elf.
OK for mainline and branches?


ChangeLog:

	* config/spu/spu-c.c (spu_resolve_overloaded_builtin): Call
	lang_hooks.types_compatible_p instead of comptypes.


Index: gcc/config/spu/spu-c.c
===================================================================
*** gcc/config/spu/spu-c.c	(revision 154991)
--- gcc/config/spu/spu-c.c	(working copy)
*************** spu_resolve_overloaded_builtin (tree fnd
*** 161,168 ****
  	  if ((!SCALAR_TYPE_P (param_type)
  	       || !SCALAR_TYPE_P (arg_type)
  	       || (all_scalar && p == 0))
! 	      && !comptypes (TYPE_MAIN_VARIANT (param_type),
! 			     TYPE_MAIN_VARIANT (arg_type)))
  	    break;
  	}
        if (param == void_list_node)
--- 161,167 ----
  	  if ((!SCALAR_TYPE_P (param_type)
  	       || !SCALAR_TYPE_P (arg_type)
  	       || (all_scalar && p == 0))
! 	      && !lang_hooks.types_compatible_p (param_type, arg_type))
  	    break;
  	}
        if (param == void_list_node)
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com



More information about the Gcc-patches mailing list