This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: builtins: choose_expr and types_compatible_p


On 8 Dec 2001, Aldy Hernandez wrote:

> > Use @r{} around English text in comments in examples.
> 
> really?  like this:? 
> 
> 	@{/* foobar more foobar }
> 	@{   more and more foo }
> 
> or like:
> 
> 	@{/* foobar more foobar
> 	     more and more foo}
> 
> anyways, fixed like the former.  lemee know.

Around the _English text_ - not the comment delimiters.

	/* @r{Foo bar}
	   @r{and baz.}  */

> + /* Assertion that the type of a conditional expression between E1 and E2
> +   is T.  Checks the expression both ways round.  */
> + #define ASSERT_COND_TYPE(E1, E2, T)                     	\
> +         do {                                            	\
> +           typedef T type;                               	\
> +           typedef type **typepp;                        	\
> +           typedef __typeof(choose (0, (E1), (E2))) ctype;	\
> +           typedef __typeof(choose (0, (E2),  (E1))) ctype2;     \
> +           typedef ctype **ctypepp;                      	\
> +           typedef ctype2 **ctype2pp;                    	\
> +           typepp x = 0;                                 	\
> +           ctypepp y = 0;                                	\
> +           ctype2pp z = 0;                               	\
> +           x = y;                                        	\
> +           x = z;                                        	\
> +         } while (0)

This is still wrong.  You're calling this below with __builtin_choose_expr 
as one argument and something else as another; what you want would be more 
like (untested)

/* Check the type of __builtin_choose_expr between E1 and E2, both ways
   round and with both 0 and 1 as the condition.  */
#define ASSERT_COND_TYPE(E1, E2)
	do {
	  typedef __typeof(E1) T1;
	  typedef __typeof(E2) T2;
	  typedef T1 **T1pp;
	  typedef T2 **T2pp;
	  typedef __typeof(choose (1, (E1), (E2))) T1a;
	  typedef __typeof(choose (0, (E2), (E1))) T1b;
	  typedef __typeof(choose (1, (E2), (E1))) T2a;
	  typedef __typeof(choose (0, (E1), (E2))) T2b;
	  typedef T1a **T1app;
	  typedef T1b **T1bpp;
	  typedef T2a **T2app;
	  typedef T2b **T2bpp;
	  T1pp t1 = 0;
	  T2pp t2 = 0;
	  T1app t1a = 0;
	  T1bpp t1b = 0;
	  T2app t2a = 0;
	  T2bpp t2b = 0;
	  t1 = t1a;
	  t1 = t1b;
	  t2 = t2a;
	  t2 = t2b;
	} while (0)

and then use this to check the types are correct in various cases, with
types that do and don't get promoted on each side, are the same or
different, are or are not compatible.  __builtin_choose_expr would then be
called below to check it has the right value, but not within the arguments
to ASSERT_COND_TYPE since that macro itself checks the type is correct and
itself calls __builtin_choose_expr.

> +   if (__builtin_types_compatible_p (char *, int)
> +       || __builtin_types_compatible_p (long double, double)
> +       || __builtin_types_compatible_p (typeof (i), typeof (d))
> +       || __builtin_types_compatible_p (char, int)
> +       || __builtin_types_compatible_p (char *, char **))
> +     abort ();

Might as well also verify that char * and const char * are not compatible.  
Also verify that this is a constant expression (by initialising a variable
of static storage duration with one of the calls, for example).

-- 
Joseph S. Myers
jsm28@cam.ac.uk


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]