diff options
author | Joseph Myers <joseph@codesourcery.com> | 2011-08-19 16:53:51 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2011-08-19 16:53:51 +0100 |
commit | d4a83c103c7a266631bc93abcfebc2451a8d5dcd (patch) | |
tree | 6962b481efb1f6dbc36e80864a62800c7cd68b11 /gcc | |
parent | a6f969f4cb4b8363b2f20f942d36dd96906ba253 (diff) | |
download | gcc-d4a83c103c7a266631bc93abcfebc2451a8d5dcd.zip gcc-d4a83c103c7a266631bc93abcfebc2451a8d5dcd.tar.gz gcc-d4a83c103c7a266631bc93abcfebc2451a8d5dcd.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 1 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 2 | ||||
-rw-r--r-- | gcc/c-parser.c | 47 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-complex-err-1.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-complex-err-2.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/dfp/builtin-complex.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/builtin-complex-1.c | 117 |
11 files changed, 241 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f1b85a4..99986b5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 9a8d953..df9cdff 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -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. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index d4dceab..4cace8d 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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 }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index a771c33..7ad82c0 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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, diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 8d7bb99..92821b1 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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); diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 786c18d..cf7fdbf 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ced6263..50a9711 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/gcc.dg/builtin-complex-err-1.c b/gcc/testsuite/gcc.dg/builtin-complex-err-1.c new file mode 100644 index 0000000..b9dab83 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-complex-err-1.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/builtin-complex-err-2.c b/gcc/testsuite/gcc.dg/builtin-complex-err-2.c new file mode 100644 index 0000000..c285b2a --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-complex-err-2.c @@ -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" } */ +} diff --git a/gcc/testsuite/gcc.dg/dfp/builtin-complex.c b/gcc/testsuite/gcc.dg/dfp/builtin-complex.c new file mode 100644 index 0000000..6bb2ec7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/builtin-complex.c @@ -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" } */ +} diff --git a/gcc/testsuite/gcc.dg/torture/builtin-complex-1.c b/gcc/testsuite/gcc.dg/torture/builtin-complex-1.c new file mode 100644 index 0000000..63df2d2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-complex-1.c @@ -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); +} |