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/c/gimple-parser.c | |
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/c/gimple-parser.c')
-rw-r--r-- | gcc/c/gimple-parser.c | 89 |
1 files changed, 76 insertions, 13 deletions
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; } |