public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Implementation of <tgmath.h>
@ 2000-07-28 12:47 Joseph S. Myers
  2000-07-28 12:54 ` Mark Mitchell
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Joseph S. Myers @ 2000-07-28 12:47 UTC (permalink / raw)
  To: gcc, libc-alpha

glibc implements C99 <tgmath.h> using statement expressions and
__typeof__, and at first glance it appears that these extensions are
necessary and sufficient for the implementation.  However, closer
examination shows they are not sufficient to get the spec right.  Consider
for example the simplest of the definitions,

# define __TGMATH_UNARY_REAL_ONLY(Val, Fct) \
     (__extension__ ({ __typeof__(Val) __tgmres;                   \
                       if (sizeof (Val) == sizeof (double))        \
                         __tgmres = Fct(Val);                      \
                       else if (sizeof (Val) == sizeof (float)     \
                         __tgmres = Fct##f (Val);                  \
                       else                                        \
                         __tgmres = Fct##l (Val);                  \
                       __tgmres; }))

The standard requires the function invoked by the macro to be chosen as
follows: the `long double' function if the argument is long double, the
`double' function if the argument is double or of integer type, or else
the `float' function.  The macro used in glibc will yield the wrong
results for integer arguments; the wrong function may be chosen, depending
on the integer type, and the result will be wrongly converted to the
integer type, instead of remaining a double.  I don't see any way of fully
fixing this within the scope of the present GCC extensions.  (Using
__typeof__((Val) + 0.0F) would be closer to correct, but still wrong since
integer types count as double rather than float.)  The best suggestion I
have for a compiler extension to allow a correct implementation would be a
series of builtin functions corresponding to the glibc macros, so that for
example

#define expm1(Val) __builtin_tgmath_unary_real_only(Val, expm1f, expm1, \
						    expm1l)

would have the compiler create a call to the appropriate one of expm1f,
expm1, expm1l according to the type of Val and the rules of <tgmath.h>
when it sees a call to __builtin_tgmath_unary_real_only.

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Implementation of <tgmath.h>
  2000-07-28 12:47 Implementation of <tgmath.h> Joseph S. Myers
@ 2000-07-28 12:54 ` Mark Mitchell
  2000-07-28 13:43 ` Geoff Keating
  2000-07-31 11:14 ` Richard Henderson
  2 siblings, 0 replies; 9+ messages in thread
From: Mark Mitchell @ 2000-07-28 12:54 UTC (permalink / raw)
  To: jsm28; +Cc: gcc, libc-alpha

  The best suggestion I have for a compiler extension to allow a correct
  implementation would be a series of builtin functions corresponding to
  the glibc macros

I completely agree.  There's no reason to try to do this stuff with
macros in glibc.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Implementation of <tgmath.h>
  2000-07-28 12:47 Implementation of <tgmath.h> Joseph S. Myers
  2000-07-28 12:54 ` Mark Mitchell
@ 2000-07-28 13:43 ` Geoff Keating
  2000-07-28 13:55   ` Ulrich Drepper
  2000-07-31 11:14 ` Richard Henderson
  2 siblings, 1 reply; 9+ messages in thread
From: Geoff Keating @ 2000-07-28 13:43 UTC (permalink / raw)
  To: jsm28; +Cc: gcc, libc-alpha

There is, or used to be, a '__builtin_classify_type' builtin that
might be helpful here.
[IMO, though, it'd be just as easy to implement a magic thing just for
this purpose, as jsm suggests.]

-- 
- Geoffrey Keating <geoffk@cygnus.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Implementation of <tgmath.h>
  2000-07-28 13:43 ` Geoff Keating
@ 2000-07-28 13:55   ` Ulrich Drepper
  2000-07-28 15:12     ` Joern Rennecke
  0 siblings, 1 reply; 9+ messages in thread
From: Ulrich Drepper @ 2000-07-28 13:55 UTC (permalink / raw)
  To: Geoff Keating; +Cc: jsm28, gcc, libc-alpha

Geoff Keating <geoffk@cygnus.com> writes:

> There is, or used to be, a '__builtin_classify_type' builtin that
> might be helpful here.

No, this does not work.

-- 
---------------.                          ,-.   1325 Chesapeake Terrace
Ulrich Drepper  \    ,-------------------'   \  Sunnyvale, CA 94089 USA
Red Hat          `--' drepper at redhat.com   `------------------------

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Implementation of <tgmath.h>
  2000-07-28 13:55   ` Ulrich Drepper
@ 2000-07-28 15:12     ` Joern Rennecke
  2000-07-28 15:36       ` Joseph S. Myers
  2000-07-28 19:04       ` Joseph S. Myers
  0 siblings, 2 replies; 9+ messages in thread
From: Joern Rennecke @ 2000-07-28 15:12 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Geoff Keating, jsm28, gcc, libc-alpha

> Geoff Keating <geoffk@cygnus.com> writes:
> 
> > There is, or used to be, a '__builtin_classify_type' builtin that
> > might be helpful here.
> 
> No, this does not work.

Why not?  You could check for real_type_class, and if it is, you use the
sizeof tests.

Another approach would be to cast 0.25 to the argument type, and test if
that's non-zero.  If so, we are dealing with a floating point type.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Implementation of <tgmath.h>
  2000-07-28 15:12     ` Joern Rennecke
@ 2000-07-28 15:36       ` Joseph S. Myers
  2000-07-28 19:04       ` Joseph S. Myers
  1 sibling, 0 replies; 9+ messages in thread
From: Joseph S. Myers @ 2000-07-28 15:36 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: Ulrich Drepper, Geoff Keating, gcc, libc-alpha

On Fri, 28 Jul 2000, Joern Rennecke wrote:

> > Geoff Keating <geoffk@cygnus.com> writes:
> > 
> > > There is, or used to be, a '__builtin_classify_type' builtin that
> > > might be helpful here.
> > 
> > No, this does not work.
> 
> Why not?  You could check for real_type_class, and if it is, you use the
> sizeof tests.
> 
> Another approach would be to cast 0.25 to the argument type, and test if
> that's non-zero.  If so, we are dealing with a floating point type.

The type of the final expression needs to be right - i.e., float, double
or long double according to the type of the arguments.  The type of a
statement expression is the type of the last expression in it (the one
returned) - which reduces to needing to produce a typeof expression for
that type; even if you can identify the right function, you still need the
right type of return value (e.g. for passing the return direct into printf
or into another tgmath macro).  I don't see how to get that
right.  (Strictly, if a target doesn't distinguish all of the float,
double, long double types in terms of representation, they are still
distinct types, and the right return value must be chosen, and all the
long double functions must exist (even if just as aliases) - though I
can't right now think of how to tell whether the type is correct in such a
case using only the properties of the standard (typeof makes this
easy).)  (If __builtin_classify_type could be used in integer constant
expressions, then it would be possible to convert integer types to double
within a typeof.)

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Implementation of <tgmath.h>
  2000-07-28 15:12     ` Joern Rennecke
  2000-07-28 15:36       ` Joseph S. Myers
@ 2000-07-28 19:04       ` Joseph S. Myers
  1 sibling, 0 replies; 9+ messages in thread
From: Joseph S. Myers @ 2000-07-28 19:04 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: Ulrich Drepper, Geoff Keating, gcc, libc-alpha

On Fri, 28 Jul 2000, Joern Rennecke wrote:

> Another approach would be to cast 0.25 to the argument type, and test if
> that's non-zero.  If so, we are dealing with a floating point type.

This pointed the way to the following implementation.  It won't solve the
technical issue of the wrong functions being called sometimes if double
and long double are the same size, but as long as in such cases they have
the same representation and the return type from the statement expression
is correct the `as if' rule may mean this does not affect conformance.  I
have ignored questions of complex types; the method can probably be
extended.  While it works, it somewhat exceeds the usual standards of
obscurity of glibc macros, and new builtin functions would yield much
clearer results while avoiding problems from the use of typeof and
statement expression extensions.  Test code is included below the macros
so you can compile with -DTEST_EXPR=whatever and see diagnostics telling
you which two of the three floating types are not the tgmath type for the
expression given.

/* 1 if 'type' is a floating type, 0 if 'type' is an integer type.
   Allows for _Bool.  Expands to an integer constant expression.
*/
#define __floating_type(type) (((type)0.25) && ((type)0.25 - 1))

/* The tgmath real type for T, where E is 0 if T is an integer type and
   1 for a floating type.
*/
#define __tgmath_real_type_sub(T, E) __typeof__(*(0 \
		     ? (__typeof__(0 ? (double *)0 : (void *)(E)))0 \
		     : (__typeof__(0 ? (T *)0 : (void *)(!(E))))0 \
		     ))

/* The tgmath real type of EXPR.  */
#define __tgmath_real_type(expr) __tgmath_real_type_sub(__typeof__(expr), \
					__floating_type(__typeof__(expr)))

/* Test compatibility by compiling and seeing which of these assignments
   are with incompatible types.  Define TEST_EXPR to the expression
   to test.
*/

#ifndef TEST_EXPR
#define TEST_EXPR 1
#endif

__tgmath_real_type(TEST_EXPR) *t;
float *f;
double *d;
long double *ld;

void
foo (void)
{
#line 1 "not float"
  f = t;
#line 1 "not double"
  d = t;
#line 1 "not long double"
  ld = t;
}

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Implementation of <tgmath.h>
  2000-07-28 12:47 Implementation of <tgmath.h> Joseph S. Myers
  2000-07-28 12:54 ` Mark Mitchell
  2000-07-28 13:43 ` Geoff Keating
@ 2000-07-31 11:14 ` Richard Henderson
  2000-07-31 12:45   ` Declaration clashing Matt Minnis
  2 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2000-07-31 11:14 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc, libc-alpha

On Fri, Jul 28, 2000 at 08:47:26PM +0100, Joseph S. Myers wrote:
> The best suggestion I have for a compiler extension to allow a correct
> implementation would be a series of builtin functions corresponding to
> the glibc macros, so that for example
> 
> #define expm1(Val) __builtin_tgmath_unary_real_only(Val, expm1f, expm1, \
> 						    expm1l)
> 
> would have the compiler create a call to the appropriate one of expm1f,
> expm1, expm1l according to the type of Val and the rules of <tgmath.h>
> when it sees a call to __builtin_tgmath_unary_real_only.

Ug.  This would seem to need the addition of mini-templates to 
the C front end. 

OTOH, the IA-64 abi has some builtin functions that could benefit
from this.  At present we implement two separate builtins and
play header file tricks to try and make it come out right.


r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Declaration clashing
  2000-07-31 11:14 ` Richard Henderson
@ 2000-07-31 12:45   ` Matt Minnis
  0 siblings, 0 replies; 9+ messages in thread
From: Matt Minnis @ 2000-07-31 12:45 UTC (permalink / raw)
  To: gcc

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1045 bytes --]

I am getting this error now:

/usr/lib/gcc-lib/i686-pc-cygwin/2.95.2/../../../../include/string.h:27:
\
warning: declaration of `void * memcpy(void *, void *, unsigned
int)'

/usr/lib/gcc-lib/i686-pc-cygwin/2.95.2/../../../../include/string.h:27:
\
warning: conflicts with built-in declaration `void * memcpy(void *, const
void *, unsigned int)'

How are the headers conflicting?  I see that one is const and the
other isn't.  

How do I resolve this issue?

Are my headers messed up?

Thanks,

Matt

Cthulhu for President. Why settle for a lesser evil?

=========================================================
Preferred
Resources          (314)
567-7600 phone
701 Emerson
rd.             
(314) 993-6699 fax
Suite
475                        
mminnis@prefres.com
St. Louis,
MO                

63141
=========================================================



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2000-07-31 12:45 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-07-28 12:47 Implementation of <tgmath.h> Joseph S. Myers
2000-07-28 12:54 ` Mark Mitchell
2000-07-28 13:43 ` Geoff Keating
2000-07-28 13:55   ` Ulrich Drepper
2000-07-28 15:12     ` Joern Rennecke
2000-07-28 15:36       ` Joseph S. Myers
2000-07-28 19:04       ` Joseph S. Myers
2000-07-31 11:14 ` Richard Henderson
2000-07-31 12:45   ` Declaration clashing Matt Minnis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).