aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/gimple-parser.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-11-30 12:02:55 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-11-30 12:02:55 +0000
commitf44697b78a06bf880ba25e9d4cd721f24282a797 (patch)
tree19934ba62a512bb402f7913a3e91b3e0ad938771 /gcc/c/gimple-parser.c
parenteea34f203816e71f2fe261b9b8593a01eb01ec81 (diff)
downloadgcc-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.c89
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;
}