This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
- To: Aldy Hernandez <aldyh at redhat dot com>
- Subject: Re: new __builtin_choose_type (patch) (new builtin_equal_types patch)
- From: "Joseph S. Myers" <jsm28 at cam dot ac dot uk>
- Date: Mon, 8 Oct 2001 11:45:39 +0100 (BST)
- cc: Jakub Jelinek <jakub at redhat dot com>, <gcc at gcc dot gnu dot org>
On 7 Oct 2001, Aldy Hernandez wrote:
> > * An implementation for C++ is also needed.
>
> will wait for new front end like suggested. [when's that?]
I don't know whether it's currently on schedule for 3.1, or not. The new
C++ parser will also help implement RTH's suggestion for C (that errors in
the unused half of __builtin_choose_expr be ignored) through its
diagnostic machinery.
> as a side note... i'm not a big fan of these big huge builtin names.
> it'll make tgmath.h horrendous to write (specially when combining
> __builtin_types_compatible_p and __builtin_choose_expr in one line).
Naturally <tgmath.h> would have appropriate macros:
* one, given a real type, to compute the tgmath type (i.e., to convert
integer types to real types);
* one, given a real or complex type, to compute the tgmath type;
* one, given two types, to compute the tgmath type associated with the
pair (i.e., the type of the sum of values whose types are the tgmath types
of the individual types - (int, float) maps to double);
* one, given a real type and three expressions (calls to float, double,
long double functions) to choose the appropriate one;
* one, given a real or complex type and six expressions, to choose the
appropriate one;
* versions of the existing __TGMATH_* macros that use the previous macros
rather than using sizeof and __builtin_classify_type;
* optionally, to simplify these, you could define __type_float_p and
similar macros to abstract out __builtin_types_compatible_p.
The aim is to create something that is comprehensible and maintainable and
uses well-defined well-documented interfaces rather than the arcana of the
rules for types of conditional expressions, __builtin_classify_type and
statement expressions.
> + @deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1},
> + @var{type2})
> +
> + You can use the builtin function @code{__builtin_types_compatible_p} to
"built-in" not "builtin". See the style notes in gcc.texi.
> + determine whether two types are the same. This builtin ignores top
"built-in function" not "builtin".
> + level qualifiers (e.g. const, static). If the types are the same, this
"e.g., @code{const}, @code{static}".
> + builtin returns the integer constant 1. Otherwise, 0 is returned.
"built-in function".
It should test compatibility, not "same"ness. (For example, "int []" is
compatible with "int [10]".) The types for which this makes a difference
probably aren't that useful with this builtin in practice, but there may
well be a use for e.g. handling enums like the integer type they are
compatible with. Type compatibility is a better-defined concept since the
standard doesn't have to deal with "same"ness.
> + You can use the builtin function @code{__builtin_choose_expr} to
"built-in".
> + evaluate code depending on the value of a constant expression. This
It must be an *integer* constant expression.
> + builtin returns exp1 if the constant expression const_exp is non zero.
@var{exp1}. @var{const_exp}. The spelling "non zero" doesn't seem to be
used in the manual, but both "nonzero" and "non-zero" are widely used.
(Which should be preferred?)
> + Otherwise it returns 0.
No, it returns exp2.
> + If exp1 is returned, the return type is the same as exp1's type. The
@var{exp1}
> + expression returned has its type unaltered by promotion rules.
> + Similarly, if exp2 is returned, its return type is the same as exp2.
@var{exp2}
> + if (__builtin_types_compatible_p (typeof (i), typeof (d)))
> + exit (1);
You should test that this is an integer constant expression. For example,
use __builtin_types_compatible_p in static initializers.
> + if (__builtin_choose_expr (45, 0, 22))
> + exit (1);
> + if (__builtin_choose_expr (0, 12, 0))
> + exit (1);
> + if (!__builtin_choose_expr (45, 3, 0))
> + exit (1);
You need tests where the arguments are of different types, not necessarily
compatible. Also test the type of the result. Look at
gcc.dg/c99-condexpr-1.c for an example of how to test types of expressions
(this may mean using gcc.dg for this testcase).
> + $$ = e1 == e2 ? build_int_2 (1, 0) : build_int_2 (0, 0);
Use comptypes, rather than comparing type pointers. Use the existing
integer_zero_node and integer_one_node.
--
Joseph S. Myers
jsm28@cam.ac.uk