gimple-parser.c (c_parser_gimple_postfix_expression): Parse _Literal (type) { ...
authorRichard Biener <rguenther@suse.de>
Fri, 30 Nov 2018 12:02:55 +0000 (12:02 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 30 Nov 2018 12:02:55 +0000 (12:02 +0000)
2018-11-30  Richard Biener  <rguenther@suse.de>

c/
* gimple-parser.c (c_parser_gimple_postfix_expression): Parse
_Literal (type) { ... } as empty aggregate or vector constructor.

* gcc.dg/gimplefe-34.c: New testcase.
* gcc.dg/gimplefe-35.c: Likewise.

From-SVN: r266661

gcc/c/ChangeLog
gcc/c/gimple-parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/gimplefe-34.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gimplefe-35.c [new file with mode: 0644]

index c82f47bbab8d29f6ea82626d342afdd92a50dd18..1f1b81fe7ba631f4a649b8f72f76dd0b46bb6977 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-30  Richard Biener  <rguenther@suse.de>
+
+       * gimple-parser.c (c_parser_gimple_postfix_expression): Parse
+       _Literal (type) { ... } as empty aggregate or vector constructor.
+
 2018-11-29  Martin Sebor  <msebor@redhat.com>
 
        PR c/88091
index c80a8bb6c6cda132880ffc280abc5eb08444548b..ab09b2b9a0e9f0d1db0c7f1fc95e5a9eb2c8e914 100644 (file)
@@ -806,6 +806,7 @@ c_parser_gimple_call_internal (c_parser *parser)
      identifier
      constant
      string-literal
+     constructor
      gimple-call-internal
 
 */
@@ -934,7 +935,7 @@ c_parser_gimple_postfix_expression (c_parser *parser)
            }
          else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
            {
-             /* _Literal '(' type-name ')' [ '-' ] constant */
+             /* _Literal '(' type-name ')' ( [ '-' ] constant | constructor ) */
              c_parser_consume_token (parser);
              tree type = NULL_TREE;
              if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
@@ -946,28 +947,90 @@ c_parser_gimple_postfix_expression (c_parser *parser)
                  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
                                             "expected %<)%>");
                }
-             bool neg_p;
-             if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS)))
-               c_parser_consume_token (parser);
-             tree val = c_parser_gimple_postfix_expression (parser).value;
-             if (! type
-                 || ! val
-                 || val == error_mark_node
-                 || ! CONSTANT_CLASS_P (val))
+             if (! type)
                {
                  c_parser_error (parser, "invalid _Literal");
                  return expr;
                }
-             if (neg_p)
+             if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
+               {
+                 c_parser_consume_token (parser);
+                 if (!AGGREGATE_TYPE_P (type)
+                     && !VECTOR_TYPE_P (type))
+                   {
+                     c_parser_error (parser, "invalid type for _Literal with "
+                                     "constructor");
+                     c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
+                                                "expected %<}%>");
+                     return expr;
+                   }
+                 vec<constructor_elt, va_gc> *v = NULL;
+                 bool constant_p = true;
+                 if (VECTOR_TYPE_P (type)
+                     && !c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
+                   {
+                     vec_alloc (v, TYPE_VECTOR_SUBPARTS (type).to_constant ());
+                     do
+                       {
+                         tree val
+                           = c_parser_gimple_postfix_expression (parser).value;
+                         if (! val
+                             || val == error_mark_node
+                             || (! CONSTANT_CLASS_P (val)
+                                 && ! SSA_VAR_P (val)))
+                           {
+                             c_parser_error (parser, "invalid _Literal");
+                             return expr;
+                           }
+                         CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, val);
+                         if (! CONSTANT_CLASS_P (val))
+                           constant_p = false;
+                         if (c_parser_next_token_is (parser, CPP_COMMA))
+                           c_parser_consume_token (parser);
+                         else
+                           break;
+                       }
+                     while (1);
+                   }
+                 if (c_parser_require (parser, CPP_CLOSE_BRACE,
+                                       "expected %<}%>"))
+                   {
+                     if (v && constant_p)
+                       expr.value = build_vector_from_ctor (type, v);
+                     else
+                       expr.value = build_constructor (type, v);
+                   }
+                 else
+                   {
+                     c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
+                                                "expected %<}%>");
+                     return expr;
+                   }
+               }
+             else
                {
-                 val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val);
-                 if (! val)
+                 bool neg_p;
+                 if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS)))
+                   c_parser_consume_token (parser);
+                 tree val = c_parser_gimple_postfix_expression (parser).value;
+                 if (! val
+                     || val == error_mark_node
+                     || ! CONSTANT_CLASS_P (val))
                    {
                      c_parser_error (parser, "invalid _Literal");
                      return expr;
                    }
+                 if (neg_p)
+                   {
+                     val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val);
+                     if (! val)
+                       {
+                         c_parser_error (parser, "invalid _Literal");
+                         return expr;
+                       }
+                   }
+                 expr.value = fold_convert (type, val);
                }
-             expr.value = fold_convert (type, val);
              return expr;
            }
 
index 17de61de796668abdf727269b8f219f5da028e41..b33ed8e6b92c7243a686b54ecd28c6562acd37a5 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-30  Richard Biener  <rguenther@suse.de>
+
+       * gcc.dg/gimplefe-34.c: New testcase.
+       * gcc.dg/gimplefe-35.c: Likewise.
+
 2018-11-30  Martin Liska  <mliska@suse.cz>
 
        PR testsuite/88265
diff --git a/gcc/testsuite/gcc.dg/gimplefe-34.c b/gcc/testsuite/gcc.dg/gimplefe-34.c
new file mode 100644 (file)
index 0000000..3cf28b5
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+typedef unsigned char v16qi __attribute__((vector_size(16)));
+typedef unsigned char v8qi __attribute__((vector_size(8)));
+
+v16qi x;
+
+void __GIMPLE foo (unsigned char *p)
+{
+  v8qi _2;
+  v16qi _3;
+
+bb_2:
+  _2 = __MEM <v8qi, 8> (p_1(D));
+  _3 = _Literal (v16qi) { _2, _Literal (v8qi) { _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0 } };
+  x = _3;
+  return;
+}
+
diff --git a/gcc/testsuite/gcc.dg/gimplefe-35.c b/gcc/testsuite/gcc.dg/gimplefe-35.c
new file mode 100644 (file)
index 0000000..80ee75c
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+struct X { int i; } x;
+void __GIMPLE foo (void)
+{
+bb_2:
+  x = _Literal (struct X) {};
+  return;
+}
+