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
This commit is contained in:
Richard Biener 2018-11-30 12:02:55 +00:00 committed by Richard Biener
parent eea34f2038
commit f44697b78a
5 changed files with 117 additions and 13 deletions

View 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

View 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))
{
val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val);
if (! val)
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
{
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;
}

View 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

View file

@ -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;
}

View file

@ -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;
}