diff options
author | Richard Biener <rguenther@suse.de> | 2018-11-30 12:02:55 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2018-11-30 12:02:55 +0000 |
commit | f44697b78a06bf880ba25e9d4cd721f24282a797 (patch) | |
tree | 19934ba62a512bb402f7913a3e91b3e0ad938771 /gcc | |
parent | eea34f203816e71f2fe261b9b8593a01eb01ec81 (diff) | |
download | gcc-f44697b78a06bf880ba25e9d4cd721f24282a797.zip gcc-f44697b78a06bf880ba25e9d4cd721f24282a797.tar.gz gcc-f44697b78a06bf880ba25e9d4cd721f24282a797.tar.bz2 |
gimple-parser.c (c_parser_gimple_postfix_expression): Parse _Literal (type) { ...
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c/gimple-parser.c | 89 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gimplefe-34.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gimplefe-35.c | 11 |
5 files changed, 117 insertions, 13 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c82f47b..1f1b81f 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -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 diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c index c80a8bb..ab09b2b 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<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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 17de61d..b33ed8e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..3cf28b5 --- /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 <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 index 0000000..80ee75c --- /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; +} + |