mirror of git://gcc.gnu.org/git/gcc.git
c-parser.c (c_parser_postfix_expression): Handle RID_BUILTIN_COMPLEX.
* c-parser.c (c_parser_postfix_expression): Handle RID_BUILTIN_COMPLEX. * doc/extend.texi (__builtin_complex): Document. c-family: * c-common.c (c_common_reswords): Add __builtin_complex. * c-common.h (RID_BUILTIN_COMPLEX): New. testsuite: * gcc.dg/builtin-complex-err-1.c, gcc.dg/builtin-complex-err-2.c, gcc.dg/dfp/builtin-complex.c, gcc.dg/torture/builtin-complex-1.c: New tests. From-SVN: r177911
This commit is contained in:
parent
a6f969f4cb
commit
d4a83c103c
|
@ -1,3 +1,9 @@
|
|||
2011-08-19 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* c-parser.c (c_parser_postfix_expression): Handle
|
||||
RID_BUILTIN_COMPLEX.
|
||||
* doc/extend.texi (__builtin_complex): Document.
|
||||
|
||||
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
|
||||
|
||||
* tree-ssa-math-opts.c (is_widening_mult_rhs_p): Handle constants
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2011-08-19 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* c-common.c (c_common_reswords): Add __builtin_complex.
|
||||
* c-common.h (RID_BUILTIN_COMPLEX): New.
|
||||
|
||||
2011-08-18 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* c-common.c (c_common_reswords): Add _Noreturn.
|
||||
|
|
|
@ -424,6 +424,7 @@ const struct c_common_resword c_common_reswords[] =
|
|||
{ "__attribute", RID_ATTRIBUTE, 0 },
|
||||
{ "__attribute__", RID_ATTRIBUTE, 0 },
|
||||
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
|
||||
{ "__builtin_complex", RID_BUILTIN_COMPLEX, D_CONLY },
|
||||
{ "__builtin_offsetof", RID_OFFSETOF, 0 },
|
||||
{ "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
|
||||
{ "__builtin_va_arg", RID_VA_ARG, 0 },
|
||||
|
|
|
@ -103,7 +103,7 @@ enum rid
|
|||
/* C extensions */
|
||||
RID_ASM, RID_TYPEOF, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG,
|
||||
RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR,
|
||||
RID_TYPES_COMPATIBLE_P,
|
||||
RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX,
|
||||
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
|
||||
RID_FRACT, RID_ACCUM,
|
||||
|
||||
|
|
|
@ -6026,6 +6026,7 @@ c_parser_alignof_expression (c_parser *parser)
|
|||
assignment-expression ,
|
||||
assignment-expression )
|
||||
__builtin_types_compatible_p ( type-name , type-name )
|
||||
__builtin_complex ( assignment-expression , assignment-expression )
|
||||
|
||||
offsetof-member-designator:
|
||||
identifier
|
||||
|
@ -6408,6 +6409,52 @@ c_parser_postfix_expression (c_parser *parser)
|
|||
= comptypes (e1, e2) ? integer_one_node : integer_zero_node;
|
||||
}
|
||||
break;
|
||||
case RID_BUILTIN_COMPLEX:
|
||||
c_parser_consume_token (parser);
|
||||
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
|
||||
{
|
||||
expr.value = error_mark_node;
|
||||
break;
|
||||
}
|
||||
loc = c_parser_peek_token (parser)->location;
|
||||
e1 = c_parser_expr_no_commas (parser, NULL);
|
||||
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
|
||||
{
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
|
||||
expr.value = error_mark_node;
|
||||
break;
|
||||
}
|
||||
e2 = c_parser_expr_no_commas (parser, NULL);
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
|
||||
"expected %<)%>");
|
||||
mark_exp_read (e1.value);
|
||||
mark_exp_read (e2.value);
|
||||
if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1.value))
|
||||
|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1.value))
|
||||
|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2.value))
|
||||
|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2.value)))
|
||||
{
|
||||
error_at (loc, "%<__builtin_complex%> operand "
|
||||
"not of real binary floating-point type");
|
||||
expr.value = error_mark_node;
|
||||
break;
|
||||
}
|
||||
if (TYPE_MAIN_VARIANT (TREE_TYPE (e1.value))
|
||||
!= TYPE_MAIN_VARIANT (TREE_TYPE (e2.value)))
|
||||
{
|
||||
error_at (loc,
|
||||
"%<__builtin_complex%> operands of different types");
|
||||
expr.value = error_mark_node;
|
||||
break;
|
||||
}
|
||||
if (!flag_isoc99)
|
||||
pedwarn (loc, OPT_pedantic,
|
||||
"ISO C90 does not support complex types");
|
||||
expr.value = build2 (COMPLEX_EXPR,
|
||||
build_complex_type (TYPE_MAIN_VARIANT
|
||||
(TREE_TYPE (e1.value))),
|
||||
e1.value, e2.value);
|
||||
break;
|
||||
case RID_AT_SELECTOR:
|
||||
gcc_assert (c_dialect_objc ());
|
||||
c_parser_consume_token (parser);
|
||||
|
|
|
@ -7511,6 +7511,18 @@ future revisions.
|
|||
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Built-in Function} @var{type} __builtin_complex (@var{real}, @var{imag})
|
||||
|
||||
The built-in function @code{__builtin_complex} is provided for use in
|
||||
implementing the ISO C1X macros @code{CMPLXF}, @code{CMPLX} and
|
||||
@code{CMPLXL}. @var{real} and @var{imag} must have the same type, a
|
||||
real binary floating-point type, and the result has the corresponding
|
||||
complex type with real and imaginary parts @var{real} and @var{imag}.
|
||||
Unlike @samp{@var{real} + I * @var{imag}}, this works even when
|
||||
infinities, NaNs and negative zeros are involved.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Built-in Function} int __builtin_constant_p (@var{exp})
|
||||
You can use the built-in function @code{__builtin_constant_p} to
|
||||
determine if a value is known to be constant at compile-time and hence
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2011-08-19 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* gcc.dg/builtin-complex-err-1.c, gcc.dg/builtin-complex-err-2.c,
|
||||
gcc.dg/dfp/builtin-complex.c, gcc.dg/torture/builtin-complex-1.c:
|
||||
New tests.
|
||||
|
||||
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
|
||||
|
||||
* gcc.target/arm/wmul-11.c: New file.
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/* Test __builtin_complex errors. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c1x -pedantic-errors" } */
|
||||
|
||||
typedef double D;
|
||||
|
||||
double d;
|
||||
|
||||
_Complex double dc = __builtin_complex (1.0, (D) 0.0);
|
||||
|
||||
_Complex double dc2 = __builtin_complex (d, 0.0); /* { dg-error "not constant" } */
|
||||
|
||||
_Complex float fc = __builtin_complex (1.0f, 1); /* { dg-error "not of real binary floating-point type" } */
|
||||
|
||||
_Complex float fc2 = __builtin_complex (1, 1.0f); /* { dg-error "not of real binary floating-point type" } */
|
||||
|
||||
_Complex float fc3 = __builtin_complex (1.0f, 1.0); /* { dg-error "different types" } */
|
||||
|
||||
void
|
||||
f (void)
|
||||
{
|
||||
__builtin_complex (0.0); /* { dg-error "expected" } */
|
||||
__builtin_complex (0.0, 0.0, 0.0); /* { dg-error "expected" } */
|
||||
}
|
||||
|
||||
void (*p) (void) = __builtin_complex; /* { dg-error "expected" } */
|
|
@ -0,0 +1,10 @@
|
|||
/* Test __builtin_complex errors. Verify it does nto allow quiet
|
||||
creation of complex types in C90. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c90 -pedantic-errors" } */
|
||||
|
||||
void
|
||||
f (void)
|
||||
{
|
||||
__builtin_complex (0.0, 0.0); /* { dg-error "ISO C90 does not support complex types" } */
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Test __builtin_complex errors with DFP. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
_Decimal32 a, b;
|
||||
|
||||
void
|
||||
f (void)
|
||||
{
|
||||
__builtin_complex (a, b); /* { dg-error "not of real binary floating-point type" } */
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/* Test __builtin_complex semantics. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=c1x -pedantic-errors" } */
|
||||
|
||||
extern void exit (int);
|
||||
extern void abort (void);
|
||||
|
||||
#define COMPARE_BODY(A, B, TYPE, COPYSIGN) \
|
||||
do { \
|
||||
TYPE s1 = COPYSIGN ((TYPE) 1.0, A); \
|
||||
TYPE s2 = COPYSIGN ((TYPE) 1.0, B); \
|
||||
if (s1 != s2) \
|
||||
abort (); \
|
||||
if ((__builtin_isnan (A) != 0) != (__builtin_isnan (B) != 0)) \
|
||||
abort (); \
|
||||
if ((A != B) != (__builtin_isnan (A) != 0)) \
|
||||
abort (); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
comparef (float a, float b)
|
||||
{
|
||||
COMPARE_BODY (a, b, float, __builtin_copysignf);
|
||||
}
|
||||
|
||||
void
|
||||
compare (double a, double b)
|
||||
{
|
||||
COMPARE_BODY (a, b, double, __builtin_copysign);
|
||||
}
|
||||
|
||||
void
|
||||
comparel (long double a, long double b)
|
||||
{
|
||||
COMPARE_BODY (a, b, long double, __builtin_copysignl);
|
||||
}
|
||||
|
||||
void
|
||||
comparecf (_Complex float a, float r, float i)
|
||||
{
|
||||
comparef (__real__ a, r);
|
||||
comparef (__imag__ a, i);
|
||||
}
|
||||
|
||||
void
|
||||
comparec (_Complex double a, double r, double i)
|
||||
{
|
||||
compare (__real__ a, r);
|
||||
compare (__imag__ a, i);
|
||||
}
|
||||
|
||||
void
|
||||
comparecl (_Complex long double a, long double r, long double i)
|
||||
{
|
||||
comparel (__real__ a, r);
|
||||
comparel (__imag__ a, i);
|
||||
}
|
||||
|
||||
#define VERIFY(A, B, TYPE, COMPARE) \
|
||||
do { \
|
||||
TYPE a = A; \
|
||||
TYPE b = B; \
|
||||
_Complex TYPE cr = __builtin_complex (a, b); \
|
||||
static _Complex TYPE cs = __builtin_complex (A, B); \
|
||||
COMPARE (cr, A, B); \
|
||||
COMPARE (cs, A, B); \
|
||||
} while (0)
|
||||
|
||||
#define ALL_CHECKS(PZ, NZ, NAN, INF, TYPE, COMPARE) \
|
||||
do { \
|
||||
VERIFY (PZ, PZ, TYPE, COMPARE); \
|
||||
VERIFY (PZ, NZ, TYPE, COMPARE); \
|
||||
VERIFY (PZ, NAN, TYPE, COMPARE); \
|
||||
VERIFY (PZ, INF, TYPE, COMPARE); \
|
||||
VERIFY (NZ, PZ, TYPE, COMPARE); \
|
||||
VERIFY (NZ, NZ, TYPE, COMPARE); \
|
||||
VERIFY (NZ, NAN, TYPE, COMPARE); \
|
||||
VERIFY (NZ, INF, TYPE, COMPARE); \
|
||||
VERIFY (NAN, PZ, TYPE, COMPARE); \
|
||||
VERIFY (NAN, NZ, TYPE, COMPARE); \
|
||||
VERIFY (NAN, NAN, TYPE, COMPARE); \
|
||||
VERIFY (NAN, INF, TYPE, COMPARE); \
|
||||
VERIFY (INF, PZ, TYPE, COMPARE); \
|
||||
VERIFY (INF, NZ, TYPE, COMPARE); \
|
||||
VERIFY (INF, NAN, TYPE, COMPARE); \
|
||||
VERIFY (INF, INF, TYPE, COMPARE); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
check_float (void)
|
||||
{
|
||||
ALL_CHECKS (0.0f, -0.0f, __builtin_nanf(""), __builtin_inff(),
|
||||
float, comparecf);
|
||||
}
|
||||
|
||||
void
|
||||
check_double (void)
|
||||
{
|
||||
ALL_CHECKS (0.0, -0.0, __builtin_nan(""), __builtin_inf(),
|
||||
double, comparec);
|
||||
}
|
||||
|
||||
void
|
||||
check_long_double (void)
|
||||
{
|
||||
ALL_CHECKS (0.0l, -0.0l, __builtin_nanl(""), __builtin_infl(),
|
||||
long double, comparecl);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
check_float ();
|
||||
check_double ();
|
||||
check_long_double ();
|
||||
exit (0);
|
||||
}
|
Loading…
Reference in New Issue