Commit d4a83c10 by Joseph Myers Committed by Joseph Myers

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
parent a6f969f4
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
......
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
......
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.
......
/* 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" } */
/* 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" } */
}
/* 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" } */
}
/* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment