]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-parser.c (c_parser_postfix_expression): Handle RID_BUILTIN_COMPLEX.
authorJoseph Myers <joseph@codesourcery.com>
Fri, 19 Aug 2011 15:53:51 +0000 (16:53 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Fri, 19 Aug 2011 15:53:51 +0000 (16:53 +0100)
* 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

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c-parser.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtin-complex-err-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/builtin-complex-err-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/builtin-complex.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/builtin-complex-1.c [new file with mode: 0644]

index f1b85a428f2377cf48cfb7af4b582dad1228cb46..99986b588d1ef0d27b94ef25541c190bf1c04be7 100644 (file)
@@ -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
index 9a8d953eec8e08051d9f85f476632d394e4344f9..df9cdff40f4825919695ff6f8763c09eaa1e6545 100644 (file)
@@ -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.
index d4dceab30dad92835d4b12754f28588f0f4cac2b..4cace8d3b140e04370e6850ff7b91c576892b6ec 100644 (file)
@@ -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 },
index a771c33033a1740c0ce1c4ac805f7036b2a6156a..7ad82c009c806d437f8976ca0a473ef6e62b459f 100644 (file)
@@ -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,
 
index 8d7bb995beb92606fd5d6b8f0bb82ae15629618f..92821b17261f9b842d0a659910c63d60dc5ab68f 100644 (file)
@@ -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);
index 786c18ddae2c8e0d6a81e91ab230b08bb55f0c58..cf7fdbf70d736c4ff7fe0b7f2c8aa37a2c25e18f 100644 (file)
@@ -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
index ced6263db50d22d5bff33ca399e7b2e956d2a29a..50a971129a546d3907cfab0b329c0f0791d44818 100644 (file)
@@ -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 (file)
index 0000000..b9dab83
--- /dev/null
@@ -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 (file)
index 0000000..c285b2a
--- /dev/null
@@ -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 (file)
index 0000000..6bb2ec7
--- /dev/null
@@ -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 (file)
index 0000000..63df2d2
--- /dev/null
@@ -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);
+}