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:
parent
eea34f2038
commit
f44697b78a
5 changed files with 117 additions and 13 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
20
gcc/testsuite/gcc.dg/gimplefe-34.c
Normal file
20
gcc/testsuite/gcc.dg/gimplefe-34.c
Normal 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;
|
||||
}
|
||||
|
11
gcc/testsuite/gcc.dg/gimplefe-35.c
Normal file
11
gcc/testsuite/gcc.dg/gimplefe-35.c
Normal 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;
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue