aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2011-08-19 16:53:51 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2011-08-19 16:53:51 +0100
commitd4a83c103c7a266631bc93abcfebc2451a8d5dcd (patch)
tree6962b481efb1f6dbc36e80864a62800c7cd68b11
parenta6f969f4cb4b8363b2f20f942d36dd96906ba253 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-common.c1
-rw-r--r--gcc/c-family/c-common.h2
-rw-r--r--gcc/c-parser.c47
-rw-r--r--gcc/doc/extend.texi12
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/builtin-complex-err-1.c26
-rw-r--r--gcc/testsuite/gcc.dg/builtin-complex-err-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/dfp/builtin-complex.c10
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-complex-1.c117
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);
+}