From: Richard Biener Date: Fri, 30 Nov 2018 12:02:55 +0000 (+0000) Subject: gimple-parser.c (c_parser_gimple_postfix_expression): Parse _Literal (type) { ... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f44697b78a06bf880ba25e9d4cd721f24282a797;p=gcc.git gimple-parser.c (c_parser_gimple_postfix_expression): Parse _Literal (type) { ... 2018-11-30 Richard Biener 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 --- diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c82f47bbab8..1f1b81fe7ba 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2018-11-30 Richard Biener + + * gimple-parser.c (c_parser_gimple_postfix_expression): Parse + _Literal (type) { ... } as empty aggregate or vector constructor. + 2018-11-29 Martin Sebor PR c/88091 diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c index c80a8bb6c6c..ab09b2b9a0e 100644 --- a/gcc/c/gimple-parser.c +++ b/gcc/c/gimple-parser.c @@ -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 *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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 17de61de796..b33ed8e6b92 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-11-30 Richard Biener + + * gcc.dg/gimplefe-34.c: New testcase. + * gcc.dg/gimplefe-35.c: Likewise. + 2018-11-30 Martin Liska 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 index 00000000000..3cf28b57218 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-34.c @@ -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 (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 index 00000000000..80ee75cf2cd --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-35.c @@ -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; +} +