1 /* Parser for GIMPLE.
2    Copyright (C) 2016-2020 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "target.h"
24 #include "function.h"
25 #include "c-tree.h"
26 #include "timevar.h"
27 #include "stringpool.h"
28 #include "cgraph.h"
29 #include "attribs.h"
30 #include "stor-layout.h"
31 #include "varasm.h"
32 #include "trans-mem.h"
33 #include "c-family/c-pragma.h"
34 #include "c-lang.h"
35 #include "c-family/c-objc.h"
36 #include "plugin.h"
37 #include "builtins.h"
38 #include "gomp-constants.h"
39 #include "c-family/c-indentation.h"
40 #include "gimple-expr.h"
41 #include "context.h"
42 #include "gcc-rich-location.h"
43 #include "c-parser.h"
44 #include "tree-vrp.h"
45 #include "tree-pass.h"
46 #include "tree-pretty-print.h"
47 #include "tree.h"
48 #include "basic-block.h"
49 #include "gimple.h"
50 #include "gimple-pretty-print.h"
51 #include "tree-ssa.h"
52 #include "pass_manager.h"
53 #include "tree-ssanames.h"
54 #include "gimple-ssa.h"
55 #include "tree-dfa.h"
56 #include "internal-fn.h"
57 #include "cfg.h"
58 #include "cfghooks.h"
59 #include "cfganal.h"
60 #include "tree-cfg.h"
61 #include "gimple-iterator.h"
62 #include "cfgloop.h"
63 #include "tree-phinodes.h"
64 #include "tree-into-ssa.h"
65 #include "bitmap.h"
66 
67 
68 /* GIMPLE parser state.  */
69 
70 class gimple_parser
71 {
72 public:
gimple_parser(c_parser * p)73   gimple_parser (c_parser *p) : parser (p), edges(), current_bb(NULL) {}
74   /* c_parser is not visible here, use composition and fake inheritance
75      via a conversion operator.  */
76   operator c_parser *() { return parser; }
77   c_parser *parser;
78 
79   /* CFG build state.  */
80   class gimple_parser_edge
81   {
82   public:
83     int src;
84     int dest;
85     int flags;
86     profile_probability probability;
87   };
88   auto_vec<gimple_parser_edge> edges;
89   basic_block current_bb;
90 
91   void push_edge (int, int, int, profile_probability);
92 };
93 
94 void
push_edge(int src,int dest,int flags,profile_probability prob)95 gimple_parser::push_edge (int src, int dest, int flags,
96 			  profile_probability prob)
97 {
98   gimple_parser_edge e;
99   e.src = src;
100   e.dest = dest;
101   e.flags = flags;
102   e.probability = prob;
103   edges.safe_push (e);
104 }
105 
106 
107 /* Gimple parsing functions.  */
108 static bool c_parser_gimple_compound_statement (gimple_parser &, gimple_seq *);
109 static void c_parser_gimple_label (gimple_parser &, gimple_seq *);
110 static void c_parser_gimple_statement (gimple_parser &, gimple_seq *);
111 static struct c_expr c_parser_gimple_binary_expression (gimple_parser &);
112 static struct c_expr c_parser_gimple_unary_expression (gimple_parser &);
113 static struct c_expr c_parser_gimple_postfix_expression (gimple_parser &);
114 static struct c_expr c_parser_gimple_postfix_expression_after_primary
115 			(gimple_parser &, location_t, struct c_expr);
116 static void c_parser_gimple_declaration (gimple_parser &);
117 static void c_parser_gimple_goto_stmt (gimple_parser &, location_t,
118 				       tree, gimple_seq *);
119 static void c_parser_gimple_try_stmt (gimple_parser &, gimple_seq *);
120 static void c_parser_gimple_if_stmt (gimple_parser &, gimple_seq *);
121 static void c_parser_gimple_switch_stmt (gimple_parser &, gimple_seq *);
122 static void c_parser_gimple_return_stmt (gimple_parser &, gimple_seq *);
123 static void c_finish_gimple_return (location_t, tree);
124 static tree c_parser_gimple_paren_condition (gimple_parser &);
125 static void c_parser_gimple_expr_list (gimple_parser &, vec<tree> *);
126 
127 
128 /* See if VAL is an identifier matching __BB<num> and return <num>
129    in *INDEX.  */
130 
131 static bool
c_parser_gimple_parse_bb_spec(tree val,int * index)132 c_parser_gimple_parse_bb_spec (tree val, int *index)
133 {
134   if (strncmp (IDENTIFIER_POINTER (val), "__BB", 4) != 0)
135     return false;
136   for (const char *p = IDENTIFIER_POINTER (val) + 4; *p; ++p)
137     if (!ISDIGIT (*p))
138       return false;
139   *index = atoi (IDENTIFIER_POINTER (val) + 4);
140   return *index > 0;
141 }
142 
143 /* See if VAL is an identifier matching __BB<num> and return <num>
144    in *INDEX.  Return true if so and parse also FREQUENCY of
145    the edge.  */
146 
147 
148 static bool
c_parser_gimple_parse_bb_spec_edge_probability(tree val,gimple_parser & parser,int * index,profile_probability * probability)149 c_parser_gimple_parse_bb_spec_edge_probability (tree val,
150 						gimple_parser &parser,
151 						int *index,
152 						profile_probability
153 						*probability)
154 {
155   bool return_p = c_parser_gimple_parse_bb_spec (val, index);
156   if (return_p)
157     {
158       *probability = profile_probability::uninitialized ();
159       /* Parse frequency if provided.  */
160       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
161 	{
162 	  tree f;
163 	  c_parser_consume_token (parser);
164 	  if (!c_parser_next_token_is (parser, CPP_NAME))
165 	    {
166 	      c_parser_error (parser, "expected frequency quality");
167 	      return false;
168 	    }
169 
170 	  profile_quality quality;
171 	  const char *v
172 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
173 	  if (!parse_profile_quality (v, &quality))
174 	    {
175 	      c_parser_error (parser, "unknown profile quality");
176 	      return false;
177 	    }
178 
179 	  c_parser_consume_token (parser);
180 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
181 	    return false;
182 
183 	  if (!c_parser_next_token_is (parser, CPP_NUMBER)
184 	      || (TREE_CODE (f = c_parser_peek_token (parser)->value)
185 		  != INTEGER_CST))
186 	    {
187 	      c_parser_error (parser, "expected frequency value");
188 	      return false;
189 	    }
190 
191 	  unsigned int value = TREE_INT_CST_LOW (f);
192 	  *probability = profile_probability (value, quality);
193 
194 	  c_parser_consume_token (parser);
195 	  if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
196 	    return false;
197 
198 	  if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
199 	    return false;
200 	}
201 
202       return true;
203     }
204 
205   return false;
206 
207 }
208 
209 /* Parse the body of a function declaration marked with "__GIMPLE".  */
210 
211 void
c_parser_parse_gimple_body(c_parser * cparser,char * gimple_pass,enum c_declspec_il cdil,profile_count entry_bb_count)212 c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
213 			    enum c_declspec_il cdil,
214 			    profile_count entry_bb_count)
215 {
216   gimple_parser parser (cparser);
217   gimple_seq seq = NULL;
218   gimple_seq body = NULL;
219   tree stmt = push_stmt_list ();
220   push_scope ();
221   location_t loc1 = c_parser_peek_token (parser)->location;
222 
223   cfun->pass_startwith = gimple_pass;
224   init_tree_ssa (cfun);
225 
226   if (cdil == cdil_gimple)
227     /* While we have SSA names in the IL we do not have a CFG built yet
228        and PHIs are represented using a PHI internal function.  We do
229        have lowered control flow and exception handling (well, we do not
230        have parser support for EH yet).  But as we still have BINDs
231        we have to go through lowering again.  */
232     cfun->curr_properties = PROP_gimple_any;
233   else
234     {
235       /* We have at least cdil_gimple_cfg.  */
236       gimple_register_cfg_hooks ();
237       init_empty_tree_cfg ();
238       parser.current_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
239       /* Initialize the bare loop structure - we are going to only
240          mark headers and leave the rest to fixup.  */
241       set_loops_for_fn (cfun, ggc_cleared_alloc<struct loops> ());
242       init_loops_structure (cfun, loops_for_fn (cfun), 1);
243       loops_state_set (cfun, LOOPS_NEED_FIXUP|LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
244       cfun->curr_properties
245 	|= PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_loops;
246       if (cdil == cdil_gimple_ssa)
247 	{
248 	  init_ssa_operands (cfun);
249 	  cfun->curr_properties |= PROP_ssa;
250 	}
251     }
252 
253   if (! c_parser_gimple_compound_statement (parser, &seq)
254       && cdil == cdil_gimple)
255     {
256       gimple *ret = gimple_build_return (NULL);
257       gimple_seq_add_stmt_without_update (&seq, ret);
258     }
259 
260   tree block = pop_scope ();
261   stmt = pop_stmt_list (stmt);
262   stmt = c_build_bind_expr (loc1, block, stmt);
263 
264   block = DECL_INITIAL (current_function_decl);
265   BLOCK_SUBBLOCKS (block) = NULL_TREE;
266   BLOCK_CHAIN (block) = NULL_TREE;
267   TREE_ASM_WRITTEN (block) = 1;
268 
269   if (cdil == cdil_gimple)
270     {
271       gbind *bind_stmt = gimple_build_bind (BIND_EXPR_VARS (stmt), NULL,
272 					    BIND_EXPR_BLOCK (stmt));
273       gimple_bind_set_body (bind_stmt, seq);
274       gimple_seq_add_stmt_without_update (&body, bind_stmt);
275       gimple_set_body (current_function_decl, body);
276     }
277   else
278     {
279       /* Control-flow and binds are lowered, record local decls.  */
280       for (tree var = BIND_EXPR_VARS (stmt); var; var = DECL_CHAIN (var))
281 	if (VAR_P (var)
282 	    && !DECL_EXTERNAL (var))
283 	  add_local_decl (cfun, var);
284       /* We have a CFG.  Build the edges.  */
285       for (unsigned i = 0; i < parser.edges.length (); ++i)
286 	{
287 	  edge e = make_edge (BASIC_BLOCK_FOR_FN (cfun, parser.edges[i].src),
288 			      BASIC_BLOCK_FOR_FN (cfun, parser.edges[i].dest),
289 			      parser.edges[i].flags);
290 	  e->probability = parser.edges[i].probability;
291 	}
292       /* Add edges for case labels.  */
293       basic_block bb;
294       FOR_EACH_BB_FN (bb, cfun)
295 	if (EDGE_COUNT (bb->succs) == 0)
296 	  {
297 	    gimple *last = last_stmt (bb);
298 	    if (gswitch *sw = safe_dyn_cast <gswitch *> (last))
299 	      for (unsigned i = 0; i < gimple_switch_num_labels (sw); ++i)
300 		{
301 		  basic_block label_bb = gimple_switch_label_bb (cfun, sw, i);
302 		  make_edge (bb, label_bb, 0);
303 		}
304 	  }
305       /* Need those for loop fixup.  */
306       calculate_dominance_info (CDI_DOMINATORS);
307       /* With SSA lower PHIs parsed as internal function calls and
308 	 update stmts.  */
309       if (cdil == cdil_gimple_ssa)
310 	{
311 	  /* Create PHI nodes, they are parsed into __PHI internal calls.  */
312 	  FOR_EACH_BB_FN (bb, cfun)
313 	    for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
314 		 !gsi_end_p (gsi);)
315 	      {
316 		gimple *stmt = gsi_stmt (gsi);
317 		if (!gimple_call_internal_p (stmt, IFN_PHI))
318 		  break;
319 
320 		gphi *phi = create_phi_node (gimple_call_lhs (stmt), bb);
321 		for (unsigned i = 0; i < gimple_call_num_args (stmt); i += 2)
322 		  {
323 		    int srcidx = TREE_INT_CST_LOW (gimple_call_arg (stmt, i));
324 		    edge e = find_edge (BASIC_BLOCK_FOR_FN (cfun, srcidx), bb);
325 		    if (!e)
326 		      c_parser_error (parser, "edge not found");
327 		    else
328 		      add_phi_arg (phi, gimple_call_arg (stmt, i + 1), e,
329 				   UNKNOWN_LOCATION);
330 		  }
331 		gsi_remove (&gsi, true);
332 	      }
333 	  /* Fill SSA name gaps, putting them on the freelist.  */
334 	  for (unsigned i = 1; i < num_ssa_names; ++i)
335 	    if (!ssa_name (i))
336 	      {
337 		tree name = make_ssa_name_fn (cfun, integer_type_node, NULL, i);
338 		release_ssa_name_fn (cfun, name);
339 	      }
340 	  /* No explicit virtual operands (yet).  */
341 	  bitmap_obstack_initialize (NULL);
342 	  update_ssa (TODO_update_ssa_only_virtuals);
343 	  bitmap_obstack_release (NULL);
344 	  /* ???  By flushing the freelist after virtual operand SSA rewrite
345 	     we keep the gaps available for re-use like needed for the
346 	     PR89595 testcase but then usually virtual operands would have
347 	     taken most of them.  The fix is obviously to make virtual
348 	     operands explicit in the SSA IL.  */
349 	  flush_ssaname_freelist ();
350 	}
351       fix_loop_structure (NULL);
352     }
353 
354   if (cfun->curr_properties & PROP_cfg)
355     {
356       ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb_count;
357       gcov_type t = param_gimple_fe_computed_hot_bb_threshold;
358       set_hot_bb_threshold (t);
359       update_max_bb_count ();
360       cgraph_node::get_create (cfun->decl);
361       cgraph_edge::rebuild_edges ();
362     }
363   dump_function (TDI_gimple, current_function_decl);
364 }
365 
366 /* Parse a compound statement in gimple function body.
367 
368    gimple-statement:
369      gimple-statement
370      gimple-declaration-statement
371      gimple-if-statement
372      gimple-switch-statement
373      gimple-labeled-statement
374      gimple-expression-statement
375      gimple-goto-statement
376      gimple-phi-statement
377      gimple-return-statement
378 */
379 
380 static bool
c_parser_gimple_compound_statement(gimple_parser & parser,gimple_seq * seq)381 c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
382 {
383   bool return_p = false;
384 
385   if (! c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
386     return false;
387 
388   /* A compund statement starts with optional declarations.  */
389   while (c_parser_next_tokens_start_declaration (parser))
390     {
391       c_parser_gimple_declaration (parser);
392       if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
393 	return false;
394     }
395 
396   while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
397     {
398       if (c_parser_error (parser))
399 	{
400 	  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
401 	  return return_p;
402 	}
403       else if (c_parser_next_token_is (parser, CPP_EOF))
404 	{
405 	  c_parser_error (parser, "expected declaration or statement");
406 	  return return_p;
407 	}
408 
409       switch (c_parser_peek_token (parser)->type)
410 	{
411 	case CPP_KEYWORD:
412 	  switch (c_parser_peek_token (parser)->keyword)
413 	    {
414 	    case RID_AT_TRY:
415 	      c_parser_gimple_try_stmt (parser, seq);
416 	      break;
417 	    case RID_IF:
418 	      c_parser_gimple_if_stmt (parser, seq);
419 	      break;
420 	    case RID_SWITCH:
421 	      c_parser_gimple_switch_stmt (parser, seq);
422 	      break;
423 	    case RID_GOTO:
424 	      {
425 		location_t loc = c_parser_peek_token (parser)->location;
426 		c_parser_consume_token (parser);
427 		if (c_parser_next_token_is (parser, CPP_NAME))
428 		  {
429 		    tree label = c_parser_peek_token (parser)->value;
430 		    c_parser_consume_token (parser);
431 		    c_parser_gimple_goto_stmt (parser, loc, label, seq);
432 		    if (! c_parser_require (parser, CPP_SEMICOLON,
433 					    "expected %<;%>"))
434 		      return return_p;
435 		  }
436 		}
437 	      break;
438 	    case RID_RETURN:
439 	      return_p = true;
440 	      c_parser_gimple_return_stmt (parser, seq);
441 	      if (! c_parser_require (parser, CPP_SEMICOLON,
442 				      "expected %<;%>"))
443 		return return_p;
444 	      if (cfun->curr_properties & PROP_cfg)
445 		parser.push_edge (parser.current_bb->index, EXIT_BLOCK, 0,
446 				  profile_probability::uninitialized ());
447 	      break;
448 	    default:
449 	      goto expr_stmt;
450 	    }
451 	  break;
452 	case CPP_NAME:
453 	  if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
454 	    {
455 	      c_parser_gimple_label (parser, seq);
456 	      break;
457 	    }
458 	  if (c_parser_next_token_is (parser, CPP_NAME)
459 	      && c_parser_peek_token (parser)->id_kind == C_ID_ID
460 	      && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
461 			 "try") == 0)
462 	    {
463 	      c_parser_gimple_try_stmt (parser, seq);
464 	      break;
465 	    }
466 	  /* Basic block specification.
467 	     __BB (index, ...)  */
468 	  if ((cfun->curr_properties & PROP_cfg)
469 	      && !strcmp (IDENTIFIER_POINTER
470 			    (c_parser_peek_token (parser)->value), "__BB"))
471 	    {
472 	      c_parser_consume_token (parser);
473 	      if (! c_parser_require (parser, CPP_OPEN_PAREN,
474 				      "expected %<(%>"))
475 		return return_p;
476 	      if (c_parser_next_token_is_not (parser, CPP_NUMBER))
477 		{
478 		  c_parser_error (parser, "expected block index");
479 		  return return_p;
480 		}
481 	      tree tnum = c_parser_peek_token (parser)->value;
482 	      if (TREE_CODE (tnum) != INTEGER_CST)
483 		{
484 		  c_parser_error (parser, "expected block index");
485 		  return return_p;
486 		}
487 	      int index = TREE_INT_CST_LOW (tnum);
488 	      if (index < NUM_FIXED_BLOCKS
489 		  || (index < last_basic_block_for_fn (cfun)
490 		      && BASIC_BLOCK_FOR_FN (cfun, index) != NULL))
491 		{
492 		  c_parser_error (parser, "invalid block index");
493 		  return return_p;
494 		}
495 	      int is_loop_header_of = -1;
496 	      profile_count bb_count = profile_count::uninitialized ();
497 	      c_parser_consume_token (parser);
498 	      while (c_parser_next_token_is (parser, CPP_COMMA))
499 		{
500 		  c_parser_consume_token (parser);
501 		  if (! c_parser_next_token_is (parser, CPP_NAME))
502 		    {
503 		      c_parser_error (parser, "expected block specifier");
504 		      return return_p;
505 		    }
506 		  /* loop_header (NUM)  */
507 		  if (!strcmp (IDENTIFIER_POINTER
508 			         (c_parser_peek_token (parser)->value),
509 			       "loop_header"))
510 		    {
511 		      c_parser_consume_token (parser);
512 		      if (! c_parser_require (parser, CPP_OPEN_PAREN,
513 					      "expected %<(%>"))
514 			return return_p;
515 		      tree loop_num;
516 		      if (! c_parser_next_token_is (parser, CPP_NUMBER)
517 			  || TREE_CODE (loop_num
518 					  = c_parser_peek_token (parser)->value)
519 			       != INTEGER_CST)
520 			{
521 			  c_parser_error (parser, "expected loop number");
522 			  return return_p;
523 			}
524 		      c_parser_consume_token (parser);
525 		      is_loop_header_of = TREE_INT_CST_LOW (loop_num);
526 		      if (! c_parser_require (parser, CPP_CLOSE_PAREN,
527 					      "expected %<)%>"))
528 			return return_p;
529 		    }
530 		  /* Parse profile: quality(value) */
531 		  else
532 		    {
533 		      tree q;
534 		      profile_quality quality;
535 		      tree v = c_parser_peek_token (parser)->value;
536 		      if (!parse_profile_quality (IDENTIFIER_POINTER (v),
537 						  &quality))
538 			{
539 			  c_parser_error (parser, "unknown block specifier");
540 			  return false;
541 			}
542 
543 		      c_parser_consume_token (parser);
544 		      if (!c_parser_require (parser, CPP_OPEN_PAREN,
545 					     "expected %<(%>"))
546 			return false;
547 
548 		      if (!c_parser_next_token_is (parser, CPP_NUMBER)
549 			  || (TREE_CODE (q = c_parser_peek_token (parser)->value)
550 			      != INTEGER_CST))
551 			{
552 			  c_parser_error (parser, "expected count value");
553 			  return false;
554 			}
555 
556 		      bb_count
557 			= profile_count::from_gcov_type (TREE_INT_CST_LOW (q),
558 							 quality);
559 		      c_parser_consume_token (parser);
560 		      if (! c_parser_require (parser, CPP_CLOSE_PAREN,
561 					      "expected %<)%>"))
562 			return return_p;
563 		    }
564 		}
565 	      if (! c_parser_require (parser, CPP_CLOSE_PAREN,
566 				      "expected %<)%>")
567 		  || ! c_parser_require (parser, CPP_COLON,
568 					 "expected %<:%>"))
569 		return return_p;
570 
571 	      /* Put stmts parsed in the current block.  */
572 	      if (!gimple_seq_empty_p (*seq))
573 		{
574 		  if (!parser.current_bb)
575 		    c_parser_error (parser, "stmts without block");
576 		  else
577 		    {
578 		      gimple_stmt_iterator gsi
579 			= gsi_start_bb (parser.current_bb);
580 		      gsi_insert_seq_after (&gsi, *seq, GSI_CONTINUE_LINKING);
581 		    }
582 		  *seq = NULL;
583 		}
584 
585 	      /* Build an empty block with specified index, linking them
586 		 in source order.  */
587 	      basic_block bb = alloc_block ();
588 	      bb->index = index;
589 	      link_block (bb, (parser.current_bb ? parser.current_bb
590 			       : ENTRY_BLOCK_PTR_FOR_FN (cfun)));
591 	      if (basic_block_info_for_fn (cfun)->length () <= (size_t)index)
592 		vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
593 				       index + 1);
594 	      SET_BASIC_BLOCK_FOR_FN (cfun, index, bb);
595 	      if (last_basic_block_for_fn (cfun) <= index)
596 		last_basic_block_for_fn (cfun) = index + 1;
597 	      n_basic_blocks_for_fn (cfun)++;
598 	      if (parser.current_bb->index == ENTRY_BLOCK)
599 		parser.push_edge (ENTRY_BLOCK, bb->index, EDGE_FALLTHRU,
600 				  profile_probability::always ());
601 
602 	      /* We leave the proper setting to fixup.  */
603 	      class loop *loop_father = loops_for_fn (cfun)->tree_root;
604 	      /* If the new block is a loop header, allocate a loop
605 		 struct.  Fixup will take care of proper placement within
606 		 the loop tree.  */
607 	      if (is_loop_header_of != -1)
608 		{
609 		  if (number_of_loops (cfun) > (unsigned)is_loop_header_of
610 		      && get_loop (cfun, is_loop_header_of) != NULL)
611 		    {
612 		      c_parser_error (parser, "duplicate loop header");
613 		    }
614 		  else
615 		    {
616 		      class loop *loop = alloc_loop ();
617 		      loop->num = is_loop_header_of;
618 		      loop->header = bb;
619 		      vec_safe_grow_cleared (loops_for_fn (cfun)->larray,
620 					     is_loop_header_of + 1);
621 		      (*loops_for_fn (cfun)->larray)[is_loop_header_of] = loop;
622 		      flow_loop_tree_node_add (loops_for_fn (cfun)->tree_root,
623 					       loop);
624 		    }
625 		  loop_father = get_loop (cfun, is_loop_header_of);
626 		}
627 	      bb->loop_father = loop_father;
628 	      bb->count = bb_count;
629 
630 	      /* Stmts now go to the new block.  */
631 	      parser.current_bb = bb;
632 	      break;
633 	    }
634 	  goto expr_stmt;
635 
636 	case CPP_SEMICOLON:
637 	  {
638 	    /* Empty stmt.  */
639 	    location_t loc = c_parser_peek_token (parser)->location;
640 	    c_parser_consume_token (parser);
641 	    gimple *nop = gimple_build_nop ();
642 	    gimple_set_location (nop, loc);
643 	    gimple_seq_add_stmt_without_update (seq, nop);
644 	    break;
645 	  }
646 
647 	default:
648 expr_stmt:
649 	  c_parser_gimple_statement (parser, seq);
650 	  if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
651 	    c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
652 	}
653     }
654   c_parser_consume_token (parser);
655 
656   /* Put stmts parsed in the current block.  */
657   if ((cfun->curr_properties & PROP_cfg)
658       && !gimple_seq_empty_p (*seq))
659     {
660       if (!parser.current_bb)
661 	c_parser_error (parser, "stmts without block");
662       else
663 	{
664 	  gimple_stmt_iterator gsi = gsi_start_bb (parser.current_bb);
665 	  gsi_insert_seq_after (&gsi, *seq, GSI_CONTINUE_LINKING);
666 	}
667       *seq = NULL;
668     }
669 
670   return return_p;
671 }
672 
673 /* Parse a gimple statement.
674 
675    gimple-statement:
676      gimple-call-expression
677      gimple-assign-statement
678      gimple-phi-statement
679 
680    gimple-assign-statement:
681      gimple-unary-expression = gimple-assign-rhs
682 
683    gimple-assign-rhs:
684      gimple-cast-expression
685      gimple-unary-expression
686      gimple-binary-expression
687      gimple-call-expression
688 
689    gimple-phi-statement:
690      identifier = __PHI ( label : gimple_primary-expression, ... )
691 
692    gimple-call-expr:
693      gimple-primary-expression ( argument-list )
694 
695    gimple-cast-expression:
696      ( type-name ) gimple-primary-expression
697 
698 */
699 
700 static void
c_parser_gimple_statement(gimple_parser & parser,gimple_seq * seq)701 c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq)
702 {
703   struct c_expr lhs, rhs;
704   gimple *assign = NULL;
705   location_t loc;
706   tree arg = NULL_TREE;
707   auto_vec<tree> vargs;
708 
709   lhs = c_parser_gimple_unary_expression (parser);
710   loc = EXPR_LOCATION (lhs.value);
711   rhs.set_error ();
712 
713   /* GIMPLE call statement without LHS.  */
714   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
715       && TREE_CODE (lhs.value) == CALL_EXPR)
716     {
717       gimple *call;
718       call = gimple_build_call_from_tree (lhs.value, NULL);
719       gimple_seq_add_stmt_without_update (seq, call);
720       gimple_set_location (call, loc);
721       return;
722     }
723 
724   /* All following cases are statements with LHS.  */
725   if (! c_parser_require (parser, CPP_EQ, "expected %<=%>"))
726     return;
727 
728   /* Cast expression.  */
729   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
730       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
731     {
732       c_parser_consume_token (parser);
733       struct c_type_name *type_name = c_parser_type_name (parser);
734       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
735       if (type_name == NULL)
736 	return;
737       /* ???  The actual type used in the cast expression is ignored as
738          in GIMPLE it is encoded by the type of the LHS.  */
739       rhs = c_parser_gimple_postfix_expression (parser);
740       if (lhs.value != error_mark_node
741 	  && rhs.value != error_mark_node)
742 	{
743 	  enum tree_code code = NOP_EXPR;
744 	  if (FLOAT_TYPE_P (TREE_TYPE (lhs.value))
745 	      && ! FLOAT_TYPE_P (TREE_TYPE (rhs.value)))
746 	    code = FLOAT_EXPR;
747 	  else if (! FLOAT_TYPE_P (TREE_TYPE (lhs.value))
748 		   && FLOAT_TYPE_P (TREE_TYPE (rhs.value)))
749 	    code = FIX_TRUNC_EXPR;
750 	  assign = gimple_build_assign (lhs.value, code, rhs.value);
751 	  gimple_seq_add_stmt_without_update (seq, assign);
752 	  gimple_set_location (assign, loc);
753 	  return;
754 	}
755     }
756 
757   /* Unary expression.  */
758   switch (c_parser_peek_token (parser)->type)
759     {
760     case CPP_NAME:
761       {
762 	tree id = c_parser_peek_token (parser)->value;
763 	if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0
764 	    || strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0
765 	    || strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0
766 	    || strcmp (IDENTIFIER_POINTER (id), "__MAX") == 0
767 	    || strcmp (IDENTIFIER_POINTER (id), "__BIT_INSERT") == 0
768 	    || strcmp (IDENTIFIER_POINTER (id), "__VEC_PERM") == 0)
769 	  goto build_unary_expr;
770 	break;
771       }
772     case CPP_KEYWORD:
773       if (c_parser_peek_token (parser)->keyword != RID_REALPART
774 	  && c_parser_peek_token (parser)->keyword != RID_IMAGPART)
775 	break;
776       /* Fallthru.  */
777     case CPP_AND:
778     case CPP_PLUS:
779     case CPP_MINUS:
780     case CPP_COMPL:
781     case CPP_NOT:
782     case CPP_MULT: /* pointer deref */
783     build_unary_expr:
784       rhs = c_parser_gimple_unary_expression (parser);
785       if (rhs.value != error_mark_node)
786 	{
787 	  assign = gimple_build_assign (lhs.value, rhs.value);
788 	  gimple_set_location (assign, loc);
789 	  gimple_seq_add_stmt_without_update (seq, assign);
790 	}
791       return;
792 
793     default:;
794     }
795 
796   /* GIMPLE PHI statement.  */
797   if (c_parser_next_token_is_keyword (parser, RID_PHI))
798     {
799       c_parser_consume_token (parser);
800 
801       if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
802 	return;
803 
804       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
805 	c_parser_consume_token (parser);
806 
807       while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
808 	{
809 	  if (c_parser_next_token_is (parser, CPP_NAME)
810 	      && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
811 	    {
812 	      arg = c_parser_peek_token (parser)->value;
813 	      c_parser_consume_token (parser);
814 	      if (c_parser_next_token_is (parser, CPP_COLON))
815 		c_parser_consume_token (parser);
816 	      int src_index = -1;
817 	      if (!c_parser_gimple_parse_bb_spec (arg, &src_index))
818 		c_parser_error (parser, "invalid source block specification");
819 	      vargs.safe_push (size_int (src_index));
820 	    }
821 	  else if (c_parser_next_token_is (parser, CPP_COMMA))
822 	    c_parser_consume_token (parser);
823 	  else
824 	    {
825 	      arg = c_parser_gimple_unary_expression (parser).value;
826 	      vargs.safe_push (arg);
827 	    }
828 	}
829 
830       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
831 				 "expected %<)%>");
832 
833       /* Build internal function for PHI.  */
834       gcall *call_stmt = gimple_build_call_internal_vec (IFN_PHI, vargs);
835       gimple_call_set_lhs (call_stmt, lhs.value);
836       gimple_set_location (call_stmt, UNKNOWN_LOCATION);
837       gimple_seq_add_stmt_without_update (seq, call_stmt);
838       return;
839     }
840 
841   /* GIMPLE call with lhs.  */
842   if (c_parser_next_token_is (parser, CPP_DOT)
843       || (c_parser_next_token_is (parser, CPP_NAME)
844 	  && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
845 	  && lookup_name (c_parser_peek_token (parser)->value)))
846     {
847       rhs = c_parser_gimple_unary_expression (parser);
848       if (rhs.value != error_mark_node)
849 	{
850 	  gimple *call = gimple_build_call_from_tree (rhs.value, NULL);
851 	  gimple_call_set_lhs (call, lhs.value);
852 	  gimple_seq_add_stmt_without_update (seq, call);
853 	  gimple_set_location (call, loc);
854 	}
855       return;
856     }
857 
858   rhs = c_parser_gimple_binary_expression (parser);
859   if (lhs.value != error_mark_node
860       && rhs.value != error_mark_node)
861     {
862       /* If we parsed a comparison and the next token is a '?' then
863          parse a conditional expression.  */
864       if (COMPARISON_CLASS_P (rhs.value)
865 	  && c_parser_next_token_is (parser, CPP_QUERY))
866 	{
867 	  struct c_expr trueval, falseval;
868 	  c_parser_consume_token (parser);
869 	  trueval = c_parser_gimple_postfix_expression (parser);
870 	  falseval.set_error ();
871 	  if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
872 	    falseval = c_parser_gimple_postfix_expression (parser);
873 	  if (trueval.value == error_mark_node
874 	      || falseval.value == error_mark_node)
875 	    return;
876 	  rhs.value = build3_loc (loc, COND_EXPR, TREE_TYPE (trueval.value),
877 				  rhs.value, trueval.value, falseval.value);
878 	}
879       assign = gimple_build_assign (lhs.value, rhs.value);
880       gimple_seq_add_stmt_without_update (seq, assign);
881       gimple_set_location (assign, loc);
882     }
883   return;
884 }
885 
886 /* Parse gimple binary expr.
887 
888    gimple-binary-expression:
889      gimple-unary-expression * gimple-unary-expression
890      gimple-unary-expression __MULT_HIGHPART gimple-unary-expression
891      gimple-unary-expression / gimple-unary-expression
892      gimple-unary-expression % gimple-unary-expression
893      gimple-unary-expression + gimple-unary-expression
894      gimple-unary-expression - gimple-unary-expression
895      gimple-unary-expression << gimple-unary-expression
896      gimple-unary-expression >> gimple-unary-expression
897      gimple-unary-expression < gimple-unary-expression
898      gimple-unary-expression > gimple-unary-expression
899      gimple-unary-expression <= gimple-unary-expression
900      gimple-unary-expression >= gimple-unary-expression
901      gimple-unary-expression == gimple-unary-expression
902      gimple-unary-expression != gimple-unary-expression
903      gimple-unary-expression & gimple-unary-expression
904      gimple-unary-expression ^ gimple-unary-expression
905      gimple-unary-expression | gimple-unary-expression
906 
907 */
908 
909 static c_expr
c_parser_gimple_binary_expression(gimple_parser & parser)910 c_parser_gimple_binary_expression (gimple_parser &parser)
911 {
912   /* Location of the binary operator.  */
913   struct c_expr ret, lhs, rhs;
914   enum tree_code code = ERROR_MARK;
915   ret.set_error ();
916   lhs = c_parser_gimple_postfix_expression (parser);
917   if (c_parser_error (parser))
918     return ret;
919   tree ret_type = TREE_TYPE (lhs.value);
920   switch (c_parser_peek_token (parser)->type)
921     {
922     case CPP_MULT:
923       code = MULT_EXPR;
924       break;
925     case CPP_DIV:
926       code = TRUNC_DIV_EXPR;
927       break;
928     case CPP_MOD:
929       code = TRUNC_MOD_EXPR;
930       break;
931     case CPP_PLUS:
932       if (POINTER_TYPE_P (TREE_TYPE (lhs.value)))
933 	code = POINTER_PLUS_EXPR;
934       else
935 	code = PLUS_EXPR;
936       break;
937     case CPP_MINUS:
938       code = MINUS_EXPR;
939       break;
940     case CPP_LSHIFT:
941       code = LSHIFT_EXPR;
942       break;
943     case CPP_RSHIFT:
944       code = RSHIFT_EXPR;
945       break;
946     case CPP_LESS:
947       code = LT_EXPR;
948       ret_type = boolean_type_node;
949       break;
950     case CPP_GREATER:
951       code = GT_EXPR;
952       ret_type = boolean_type_node;
953       break;
954     case CPP_LESS_EQ:
955       code = LE_EXPR;
956       ret_type = boolean_type_node;
957       break;
958     case CPP_GREATER_EQ:
959       code = GE_EXPR;
960       ret_type = boolean_type_node;
961       break;
962     case CPP_EQ_EQ:
963       code = EQ_EXPR;
964       ret_type = boolean_type_node;
965       break;
966     case CPP_NOT_EQ:
967       code = NE_EXPR;
968       ret_type = boolean_type_node;
969       break;
970     case CPP_AND:
971       code = BIT_AND_EXPR;
972       break;
973     case CPP_XOR:
974       code = BIT_XOR_EXPR;
975       break;
976     case CPP_OR:
977       code = BIT_IOR_EXPR;
978       break;
979     case CPP_AND_AND:
980       c_parser_error (parser, "%<&&%> not valid in GIMPLE");
981       return ret;
982     case CPP_OR_OR:
983       c_parser_error (parser, "%<||%> not valid in GIMPLE");
984       return ret;
985     case CPP_NAME:
986 	{
987 	  tree id = c_parser_peek_token (parser)->value;
988 	  if (strcmp (IDENTIFIER_POINTER (id), "__MULT_HIGHPART") == 0)
989 	    {
990 	      code = MULT_HIGHPART_EXPR;
991 	      break;
992 	    }
993 	}
994       /* Fallthru.  */
995     default:
996       /* Not a binary expression.  */
997       return lhs;
998     }
999   location_t ret_loc = c_parser_peek_token (parser)->location;
1000   c_parser_consume_token (parser);
1001   rhs = c_parser_gimple_postfix_expression (parser);
1002   if (lhs.value != error_mark_node && rhs.value != error_mark_node)
1003     ret.value = build2_loc (ret_loc, code, ret_type, lhs.value, rhs.value);
1004   return ret;
1005 }
1006 
1007 /* Parse a gimple parentized binary expression.  */
1008 
1009 static c_expr
c_parser_gimple_parentized_binary_expression(gimple_parser & parser,location_t op_loc,tree_code code)1010 c_parser_gimple_parentized_binary_expression (gimple_parser &parser,
1011 					      location_t op_loc,
1012 					      tree_code code)
1013 {
1014   struct c_expr ret;
1015   ret.set_error ();
1016 
1017   c_parser_consume_token (parser);
1018   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1019     return ret;
1020   c_expr op1 = c_parser_gimple_postfix_expression (parser);
1021   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
1022     return ret;
1023   c_expr op2 = c_parser_gimple_postfix_expression (parser);
1024   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1025     return ret;
1026 
1027   if (op1.value != error_mark_node && op2.value != error_mark_node)
1028     ret.value = build2_loc (op_loc,
1029 			    code, TREE_TYPE (op1.value), op1.value, op2.value);
1030   return ret;
1031 }
1032 
1033 /* Parse a gimple parentized binary expression.  */
1034 
1035 static c_expr
c_parser_gimple_parentized_ternary_expression(gimple_parser & parser,location_t op_loc,tree_code code)1036 c_parser_gimple_parentized_ternary_expression (gimple_parser &parser,
1037 					       location_t op_loc,
1038 					       tree_code code)
1039 {
1040   struct c_expr ret;
1041   ret.set_error ();
1042 
1043   c_parser_consume_token (parser);
1044   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1045     return ret;
1046   c_expr op1 = c_parser_gimple_postfix_expression (parser);
1047   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
1048     return ret;
1049   c_expr op2 = c_parser_gimple_postfix_expression (parser);
1050   if (!c_parser_require (parser, CPP_COMMA, "expected %<)%>"))
1051     return ret;
1052   c_expr op3 = c_parser_gimple_postfix_expression (parser);
1053   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1054     return ret;
1055 
1056   if (op1.value != error_mark_node
1057       && op2.value != error_mark_node
1058       && op3.value != error_mark_node)
1059     ret.value = build3_loc (op_loc,
1060 			    code, TREE_TYPE (op1.value),
1061 			    op1.value, op2.value, op3.value);
1062   return ret;
1063 }
1064 
1065 /* Parse gimple unary expression.
1066 
1067    gimple-unary-expression:
1068      gimple-postfix-expression
1069      unary-operator gimple-postfix-expression
1070 
1071    unary-operator: one of
1072      & * + - ~ abs_expr
1073 */
1074 
1075 static c_expr
c_parser_gimple_unary_expression(gimple_parser & parser)1076 c_parser_gimple_unary_expression (gimple_parser &parser)
1077 {
1078   struct c_expr ret, op;
1079   location_t op_loc = c_parser_peek_token (parser)->location;
1080   location_t finish;
1081   ret.set_error ();
1082   switch (c_parser_peek_token (parser)->type)
1083     {
1084     case CPP_AND:
1085       c_parser_consume_token (parser);
1086       op = c_parser_gimple_postfix_expression (parser);
1087       mark_exp_read (op.value);
1088       return parser_build_unary_op (op_loc, ADDR_EXPR, op);
1089     case CPP_MULT:
1090       {
1091 	c_parser_consume_token (parser);
1092 	op = c_parser_gimple_postfix_expression (parser);
1093 	if (op.value == error_mark_node)
1094 	  return ret;
1095 	if (! POINTER_TYPE_P (TREE_TYPE (op.value)))
1096 	  {
1097 	    error_at (op_loc, "expected pointer as argument of unary %<*%>");
1098 	    return ret;
1099 	  }
1100 	finish = op.get_finish ();
1101 	location_t combined_loc = make_location (op_loc, op_loc, finish);
1102 	ret.value = build_simple_mem_ref_loc (combined_loc, op.value);
1103 	TREE_SIDE_EFFECTS (ret.value)
1104 	  = TREE_THIS_VOLATILE (ret.value)
1105 	  = TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (op.value)));
1106 	ret.src_range.m_start = op_loc;
1107 	ret.src_range.m_finish = finish;
1108 	return ret;
1109       }
1110     case CPP_PLUS:
1111       c_parser_consume_token (parser);
1112       op = c_parser_gimple_postfix_expression (parser);
1113       return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
1114     case CPP_MINUS:
1115       c_parser_consume_token (parser);
1116       op = c_parser_gimple_postfix_expression (parser);
1117       return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
1118     case CPP_COMPL:
1119       c_parser_consume_token (parser);
1120       op = c_parser_gimple_postfix_expression (parser);
1121       return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
1122     case CPP_NOT:
1123       c_parser_error (parser, "%<!%> not valid in GIMPLE");
1124       return ret;
1125     case CPP_KEYWORD:
1126       switch (c_parser_peek_token (parser)->keyword)
1127 	{
1128 	case RID_REALPART:
1129 	  c_parser_consume_token (parser);
1130 	  op = c_parser_gimple_postfix_expression (parser);
1131 	  return parser_build_unary_op (op_loc, REALPART_EXPR, op);
1132 	case RID_IMAGPART:
1133 	  c_parser_consume_token (parser);
1134 	  op = c_parser_gimple_postfix_expression (parser);
1135 	  return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
1136 	default:
1137 	  return c_parser_gimple_postfix_expression (parser);
1138 	}
1139     case CPP_NAME:
1140 	{
1141 	  tree id = c_parser_peek_token (parser)->value;
1142 	  if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0)
1143 	    {
1144 	      c_parser_consume_token (parser);
1145 	      op = c_parser_gimple_postfix_expression (parser);
1146 	      return parser_build_unary_op (op_loc, ABS_EXPR, op);
1147 	    }
1148 	  else if (strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0)
1149 	    {
1150 	      c_parser_consume_token (parser);
1151 	      op = c_parser_gimple_postfix_expression (parser);
1152 	      return parser_build_unary_op (op_loc, ABSU_EXPR, op);
1153 	    }
1154 	  else if (strcmp (IDENTIFIER_POINTER (id), "__MIN") == 0)
1155 	    return c_parser_gimple_parentized_binary_expression (parser,
1156 								 op_loc,
1157 								 MIN_EXPR);
1158 	  else if (strcmp (IDENTIFIER_POINTER (id), "__MAX") == 0)
1159 	    return c_parser_gimple_parentized_binary_expression (parser,
1160 								 op_loc,
1161 								 MAX_EXPR);
1162 	  else if (strcmp (IDENTIFIER_POINTER (id), "__VEC_PERM") == 0)
1163 	    return c_parser_gimple_parentized_ternary_expression
1164 			(parser, op_loc, VEC_PERM_EXPR);
1165 	  else if (strcmp (IDENTIFIER_POINTER (id), "__BIT_INSERT") == 0)
1166 	    {
1167 	      /* __BIT_INSERT '(' postfix-expression, postfix-expression,
1168 			          integer ')'  */
1169 	      location_t loc = c_parser_peek_token (parser)->location;
1170 	      c_parser_consume_token (parser);
1171 	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1172 		{
1173 		  c_expr op0 = c_parser_gimple_postfix_expression (parser);
1174 		  c_parser_skip_until_found (parser, CPP_COMMA,
1175 					     "expected %<,%>");
1176 		  c_expr op1 = c_parser_gimple_postfix_expression (parser);
1177 		  c_parser_skip_until_found (parser, CPP_COMMA,
1178 					     "expected %<,%>");
1179 		  c_expr op2 = c_parser_gimple_postfix_expression (parser);
1180 		  if (TREE_CODE (op2.value) != INTEGER_CST
1181 		      || !int_fits_type_p (op2.value, bitsizetype))
1182 		    c_parser_error (parser, "expected constant offset");
1183 		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1184 					     "expected %<)%>");
1185 		  if (op0.value != error_mark_node
1186 		      && op1.value != error_mark_node
1187 		      && TREE_CODE (op2.value) == INTEGER_CST)
1188 		    ret.value = build3_loc (loc, BIT_INSERT_EXPR,
1189 					    TREE_TYPE (op0.value),
1190 					    op0.value, op1.value,
1191 					    fold_convert (bitsizetype,
1192 							  op2.value));
1193 		}
1194 	      return ret;
1195 	    }
1196 	  else
1197 	    return c_parser_gimple_postfix_expression (parser);
1198 	}
1199     default:
1200       return c_parser_gimple_postfix_expression (parser);
1201     }
1202 }
1203 
1204 /* Decompose ID into base name (ID until ver_offset) and VERSION.  Return
1205    true if ID matches a SSA name.  */
1206 
1207 static bool
c_parser_parse_ssa_name_id(tree id,unsigned * version,unsigned * ver_offset)1208 c_parser_parse_ssa_name_id (tree id, unsigned *version, unsigned *ver_offset)
1209 {
1210   const char *token = IDENTIFIER_POINTER (id);
1211   const char *var_version = strrchr (token, '_');
1212   if (! var_version)
1213     return false;
1214 
1215   *ver_offset = var_version - token;
1216   for (const char *p = var_version + 1; *p; ++p)
1217     if (! ISDIGIT (*p))
1218       return false;
1219   *version = atoi (var_version + 1);
1220   return *version > 0;
1221 }
1222 
1223 /* Get at the actual SSA name ID with VERSION starting at VER_OFFSET.
1224    TYPE is the type if the SSA name is being declared.  */
1225 
1226 static tree
c_parser_parse_ssa_name(gimple_parser & parser,tree id,tree type,unsigned version,unsigned ver_offset)1227 c_parser_parse_ssa_name (gimple_parser &parser,
1228 			 tree id, tree type, unsigned version,
1229 			 unsigned ver_offset)
1230 {
1231   tree name = NULL_TREE;
1232   const char *token = IDENTIFIER_POINTER (id);
1233 
1234   if (ver_offset == 0)
1235     {
1236       /* Anonymous unnamed SSA name.  */
1237       if (version < num_ssa_names)
1238 	name = ssa_name (version);
1239       if (! name)
1240 	{
1241 	  if (! type)
1242 	    {
1243 	      c_parser_error (parser, "SSA name undeclared");
1244 	      return error_mark_node;
1245 	    }
1246 	  name = make_ssa_name_fn (cfun, type, NULL, version);
1247 	}
1248     }
1249   else
1250     {
1251       if (version < num_ssa_names)
1252 	name = ssa_name (version);
1253       if (! name)
1254 	{
1255 	  /* Separate var name from version.  */
1256 	  char *var_name = XNEWVEC (char, ver_offset + 1);
1257 	  memcpy (var_name, token, ver_offset);
1258 	  var_name[ver_offset] = '\0';
1259 	  /* lookup for parent decl.  */
1260 	  id = get_identifier (var_name);
1261 	  tree parent = lookup_name (id);
1262 	  XDELETEVEC (var_name);
1263 	  if (! parent || parent == error_mark_node)
1264 	    {
1265 	      c_parser_error (parser, "base variable or SSA name undeclared");
1266 	      return error_mark_node;
1267 	    }
1268 	  if (!(VAR_P (parent)
1269 		|| TREE_CODE (parent) == PARM_DECL
1270 		|| TREE_CODE (parent) == RESULT_DECL))
1271 	    {
1272 	      error ("invalid base %qE for SSA name", parent);
1273 	      return error_mark_node;
1274 	    }
1275 	  if (VECTOR_TYPE_P (TREE_TYPE (parent))
1276 	      || TREE_CODE (TREE_TYPE (parent)) == COMPLEX_TYPE)
1277 	    DECL_GIMPLE_REG_P (parent) = 1;
1278 	  name = make_ssa_name_fn (cfun, parent,
1279 				   gimple_build_nop (), version);
1280 	}
1281     }
1282 
1283   return name;
1284 }
1285 
1286 /* Parse a gimple call to an internal function.
1287 
1288    gimple-call-internal:
1289      . identifier ( gimple-argument-expression-list[opt] )  */
1290 
1291 static struct c_expr
c_parser_gimple_call_internal(gimple_parser & parser)1292 c_parser_gimple_call_internal (gimple_parser &parser)
1293 {
1294   struct c_expr expr;
1295   expr.set_error ();
1296 
1297   gcc_assert (c_parser_next_token_is (parser, CPP_DOT));
1298   c_parser_consume_token (parser);
1299   location_t loc = c_parser_peek_token (parser)->location;
1300   if (!c_parser_next_token_is (parser, CPP_NAME)
1301       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
1302     {
1303       c_parser_error (parser, "expecting internal function name");
1304       return expr;
1305     }
1306   tree id = c_parser_peek_token (parser)->value;
1307   internal_fn ifn = lookup_internal_fn (IDENTIFIER_POINTER (id));
1308   c_parser_consume_token (parser);
1309   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1310     {
1311       auto_vec<tree> exprlist;
1312       if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
1313 	c_parser_gimple_expr_list (parser, &exprlist);
1314       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
1315       if (ifn == IFN_LAST)
1316 	error_at (loc, "unknown internal function %qE", id);
1317       else
1318 	{
1319 	  expr.value = build_call_expr_internal_loc_array
1320 	    (loc, ifn, void_type_node, exprlist.length (),
1321 	     exprlist.address ());
1322 	  expr.original_code = ERROR_MARK;
1323 	  expr.original_type = NULL;
1324 	}
1325     }
1326   return expr;
1327 }
1328 
1329 /* Parse '<' type [',' alignment] '>' and return a type on success
1330    and NULL_TREE on error.  */
1331 
1332 static tree
c_parser_gimple_typespec(gimple_parser & parser)1333 c_parser_gimple_typespec (gimple_parser &parser)
1334 {
1335   struct c_type_name *type_name = NULL;
1336   tree alignment = NULL_TREE;
1337   if (c_parser_require (parser, CPP_LESS, "expected %<<%>"))
1338     {
1339       type_name = c_parser_type_name (parser);
1340       /* Optional alignment.  */
1341       if (c_parser_next_token_is (parser, CPP_COMMA))
1342 	{
1343 	  c_parser_consume_token (parser);
1344 	  alignment
1345 	      = c_parser_gimple_postfix_expression (parser).value;
1346 	}
1347       c_parser_skip_until_found (parser,
1348 				 CPP_GREATER, "expected %<>%>");
1349     }
1350   if (!type_name)
1351     return NULL_TREE;
1352   tree tem;
1353   tree type = groktypename (type_name, &tem, NULL);
1354   if (alignment)
1355     type = build_aligned_type (type, tree_to_uhwi (alignment));
1356   return type;
1357 }
1358 
1359 /* Parse gimple postfix expression.
1360 
1361    gimple-postfix-expression:
1362      gimple-primary-expression
1363      gimple-primary-expression [ gimple-primary-expression ]
1364      gimple-primary-expression ( gimple-argument-expression-list[opt] )
1365      gimple-postfix-expression . identifier
1366      gimple-postfix-expression -> identifier
1367 
1368    gimple-argument-expression-list:
1369      gimple-unary-expression
1370      gimple-argument-expression-list , gimple-unary-expression
1371 
1372    gimple-primary-expression:
1373      identifier
1374      constant
1375      string-literal
1376      constructor
1377      gimple-call-internal
1378 
1379 */
1380 
1381 static struct c_expr
c_parser_gimple_postfix_expression(gimple_parser & parser)1382 c_parser_gimple_postfix_expression (gimple_parser &parser)
1383 {
1384   location_t loc = c_parser_peek_token (parser)->location;
1385   source_range tok_range = c_parser_peek_token (parser)->get_range ();
1386   struct c_expr expr;
1387   expr.set_error ();
1388   switch (c_parser_peek_token (parser)->type)
1389     {
1390     case CPP_NUMBER:
1391       expr.value = c_parser_peek_token (parser)->value;
1392       set_c_expr_source_range (&expr, tok_range);
1393       loc = c_parser_peek_token (parser)->location;
1394       c_parser_consume_token (parser);
1395       break;
1396     case CPP_CHAR:
1397     case CPP_CHAR16:
1398     case CPP_CHAR32:
1399     case CPP_UTF8CHAR:
1400     case CPP_WCHAR:
1401       expr.value = c_parser_peek_token (parser)->value;
1402       set_c_expr_source_range (&expr, tok_range);
1403       c_parser_consume_token (parser);
1404       break;
1405     case CPP_STRING:
1406     case CPP_STRING16:
1407     case CPP_STRING32:
1408     case CPP_WSTRING:
1409     case CPP_UTF8STRING:
1410       expr = c_parser_string_literal (parser, false, true);
1411       break;
1412     case CPP_DOT:
1413       expr = c_parser_gimple_call_internal (parser);
1414       break;
1415     case CPP_NAME:
1416       if (c_parser_peek_token (parser)->id_kind == C_ID_ID)
1417 	{
1418 	  tree id = c_parser_peek_token (parser)->value;
1419 	  if (strcmp (IDENTIFIER_POINTER (id), "__MEM") == 0)
1420 	    {
1421 	      /* __MEM '<' type-name [ ',' number ] '>'
1422 	               '(' [ '(' type-name ')' ] unary-expression
1423 		           [ '+' number ] ')'  */
1424 	      location_t loc = c_parser_peek_token (parser)->location;
1425 	      c_parser_consume_token (parser);
1426 	      tree type = c_parser_gimple_typespec (parser);
1427 	      struct c_expr ptr;
1428 	      ptr.value = error_mark_node;
1429 	      tree alias_off = NULL_TREE;
1430 	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1431 		{
1432 		  tree alias_type = NULL_TREE;
1433 		  /* Optional alias-type cast.  */
1434 		  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
1435 		    {
1436 		      c_parser_consume_token (parser);
1437 		      struct c_type_name *alias_type_name
1438 			= c_parser_type_name (parser);
1439 		      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1440 						 "expected %<)%>");
1441 		      if (alias_type_name)
1442 			{
1443 			  tree tem;
1444 			  alias_type = groktypename (alias_type_name,
1445 						     &tem, NULL);
1446 			}
1447 		    }
1448 		  ptr = c_parser_gimple_unary_expression (parser);
1449 		  if (ptr.value == error_mark_node
1450 		      || ! POINTER_TYPE_P (TREE_TYPE (ptr.value)))
1451 		    {
1452 		      if (ptr.value != error_mark_node)
1453 			error_at (ptr.get_start (),
1454 				  "invalid type of %<__MEM%> operand");
1455 		      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1456 						 "expected %<)%>");
1457 		      return expr;
1458 		    }
1459 		  if (! alias_type)
1460 		    alias_type = TREE_TYPE (ptr.value);
1461 		  /* Optional constant offset.  */
1462 		  if (c_parser_next_token_is (parser, CPP_PLUS))
1463 		    {
1464 		      c_parser_consume_token (parser);
1465 		      alias_off
1466 			= c_parser_gimple_postfix_expression (parser).value;
1467 		      alias_off = fold_convert (alias_type, alias_off);
1468 		    }
1469 		  if (! alias_off)
1470 		    alias_off = build_int_cst (alias_type, 0);
1471 		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1472 					     "expected %<)%>");
1473 		}
1474 	      if (! type || c_parser_error (parser))
1475 		{
1476 		  c_parser_set_error (parser, false);
1477 		  return expr;
1478 		}
1479 	      expr.value = build2_loc (loc, MEM_REF,
1480 				       type, ptr.value, alias_off);
1481 	      break;
1482 	    }
1483 	  else if (strcmp (IDENTIFIER_POINTER (id), "__VIEW_CONVERT") == 0)
1484 	    {
1485 	      /* __VIEW_CONVERT '<' type-name [ ',' number ] '>'
1486 	                        '(' postfix-expression ')'  */
1487 	      location_t loc = c_parser_peek_token (parser)->location;
1488 	      c_parser_consume_token (parser);
1489 	      tree type = c_parser_gimple_typespec (parser);
1490 	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1491 		{
1492 		  c_expr op = c_parser_gimple_postfix_expression (parser);
1493 		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1494 					     "expected %<)%>");
1495 		  if (type && op.value != error_mark_node)
1496 		    expr.value = build1_loc (loc, VIEW_CONVERT_EXPR,
1497 					     type, op.value);
1498 		}
1499 	      break;
1500 	    }
1501 	  else if (strcmp (IDENTIFIER_POINTER (id), "__BIT_FIELD_REF") == 0)
1502 	    {
1503 	      /* __BIT_FIELD_REF '<' type-name [ ',' number ] '>'
1504 	                        '(' postfix-expression, integer, integer ')'  */
1505 	      location_t loc = c_parser_peek_token (parser)->location;
1506 	      c_parser_consume_token (parser);
1507 	      tree type = c_parser_gimple_typespec (parser);
1508 	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1509 		{
1510 		  c_expr op0 = c_parser_gimple_postfix_expression (parser);
1511 		  c_parser_skip_until_found (parser, CPP_COMMA,
1512 					     "expected %<,%>");
1513 		  c_expr op1 = c_parser_gimple_postfix_expression (parser);
1514 		  if (TREE_CODE (op1.value) != INTEGER_CST
1515 		      || !int_fits_type_p (op1.value, bitsizetype))
1516 		    c_parser_error (parser, "expected constant size");
1517 		  c_parser_skip_until_found (parser, CPP_COMMA,
1518 					     "expected %<,%>");
1519 		  c_expr op2 = c_parser_gimple_postfix_expression (parser);
1520 		  if (TREE_CODE (op2.value) != INTEGER_CST
1521 		      || !int_fits_type_p (op2.value, bitsizetype))
1522 		    c_parser_error (parser, "expected constant offset");
1523 		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1524 					     "expected %<)%>");
1525 		  if (type
1526 		      && op0.value != error_mark_node
1527 		      && TREE_CODE (op1.value) == INTEGER_CST
1528 		      && TREE_CODE (op2.value) == INTEGER_CST)
1529 		    expr.value = build3_loc (loc, BIT_FIELD_REF, type,
1530 					     op0.value,
1531 					     fold_convert (bitsizetype,
1532 							   op1.value),
1533 					     fold_convert (bitsizetype,
1534 							   op2.value));
1535 		}
1536 	      break;
1537 	    }
1538 	  else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
1539 	    {
1540 	      /* _Literal '(' type-name ')' ( [ '-' ] constant | constructor ) */
1541 	      c_parser_consume_token (parser);
1542 	      tree type = NULL_TREE;
1543 	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1544 		{
1545 		  struct c_type_name *type_name = c_parser_type_name (parser);
1546 		  tree tem;
1547 		  if (type_name)
1548 		    type = groktypename (type_name, &tem, NULL);
1549 		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1550 					     "expected %<)%>");
1551 		}
1552 	      if (! type)
1553 		{
1554 		  c_parser_error (parser, "invalid _Literal");
1555 		  return expr;
1556 		}
1557 	      if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
1558 		{
1559 		  c_parser_consume_token (parser);
1560 		  if (!AGGREGATE_TYPE_P (type)
1561 		      && !VECTOR_TYPE_P (type))
1562 		    {
1563 		      c_parser_error (parser, "invalid type for _Literal with "
1564 				      "constructor");
1565 		      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
1566 						 "expected %<}%>");
1567 		      return expr;
1568 		    }
1569 		  vec<constructor_elt, va_gc> *v = NULL;
1570 		  bool constant_p = true;
1571 		  if (VECTOR_TYPE_P (type)
1572 		      && !c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
1573 		    {
1574 		      vec_alloc (v, TYPE_VECTOR_SUBPARTS (type).to_constant ());
1575 		      do
1576 			{
1577 			  tree val
1578 			    = c_parser_gimple_postfix_expression (parser).value;
1579 			  if (! val
1580 			      || val == error_mark_node
1581 			      || (! CONSTANT_CLASS_P (val)
1582 				  && ! SSA_VAR_P (val)))
1583 			    {
1584 			      c_parser_error (parser, "invalid _Literal");
1585 			      return expr;
1586 			    }
1587 			  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, val);
1588 			  if (! CONSTANT_CLASS_P (val))
1589 			    constant_p = false;
1590 			  if (c_parser_next_token_is (parser, CPP_COMMA))
1591 			    c_parser_consume_token (parser);
1592 			  else
1593 			    break;
1594 			}
1595 		      while (1);
1596 		    }
1597 		  if (c_parser_require (parser, CPP_CLOSE_BRACE,
1598 					"expected %<}%>"))
1599 		    {
1600 		      if (v && constant_p)
1601 			expr.value = build_vector_from_ctor (type, v);
1602 		      else
1603 			expr.value = build_constructor (type, v);
1604 		    }
1605 		  else
1606 		    {
1607 		      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
1608 						 "expected %<}%>");
1609 		      return expr;
1610 		    }
1611 		}
1612 	      else
1613 		{
1614 		  bool neg_p, addr_p;
1615 		  if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS)))
1616 		    c_parser_consume_token (parser);
1617 		  if ((addr_p = c_parser_next_token_is (parser, CPP_AND)))
1618 		    c_parser_consume_token (parser);
1619 		  tree val = c_parser_gimple_postfix_expression (parser).value;
1620 		  if (! val
1621 		      || val == error_mark_node
1622 		      || (!CONSTANT_CLASS_P (val)
1623 			  && !(addr_p
1624 			       && (TREE_CODE (val) == STRING_CST
1625 				   || DECL_P (val)))))
1626 		    {
1627 		      c_parser_error (parser, "invalid _Literal");
1628 		      return expr;
1629 		    }
1630 		  if (addr_p)
1631 		    val = build1 (ADDR_EXPR, type, val);
1632 		  if (neg_p)
1633 		    {
1634 		      val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val);
1635 		      if (! val)
1636 			{
1637 			  c_parser_error (parser, "invalid _Literal");
1638 			  return expr;
1639 			}
1640 		    }
1641 		  expr.value = fold_convert (type, val);
1642 		}
1643 	      return expr;
1644 	    }
1645 
1646 	  /* SSA name.  */
1647 	  unsigned version, ver_offset;
1648 	  if (! lookup_name (id)
1649 	      && c_parser_parse_ssa_name_id (id, &version, &ver_offset))
1650 	    {
1651 	      c_parser_consume_token (parser);
1652 	      expr.value = c_parser_parse_ssa_name (parser, id, NULL_TREE,
1653 						    version, ver_offset);
1654 	      if (expr.value == error_mark_node)
1655 		return expr;
1656 	      set_c_expr_source_range (&expr, tok_range);
1657 	      /* For default definition SSA names.  */
1658 	      if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
1659 		  && c_parser_peek_2nd_token (parser)->type == CPP_NAME
1660 		  && strcmp ("D",
1661 			     IDENTIFIER_POINTER
1662 			       (c_parser_peek_2nd_token (parser)->value)) == 0
1663 		  && c_parser_peek_nth_token (parser, 3)->type == CPP_CLOSE_PAREN)
1664 		{
1665 		  c_parser_consume_token (parser);
1666 		  c_parser_consume_token (parser);
1667 		  c_parser_consume_token (parser);
1668 		  if (! SSA_NAME_IS_DEFAULT_DEF (expr.value))
1669 		    {
1670 		      if (!SSA_NAME_VAR (expr.value))
1671 			{
1672 			  error_at (loc, "anonymous SSA name cannot have"
1673 				    " default definition");
1674 			  expr.value = error_mark_node;
1675 			  return expr;
1676 			}
1677 		      set_ssa_default_def (cfun, SSA_NAME_VAR (expr.value),
1678 					   expr.value);
1679 		      SSA_NAME_DEF_STMT (expr.value) = gimple_build_nop ();
1680 		    }
1681 		}
1682 	    }
1683 	  else
1684 	    {
1685 	      c_parser_consume_token (parser);
1686 	      expr.value
1687 		= build_external_ref (loc, id,
1688 				      (c_parser_peek_token (parser)->type
1689 				       == CPP_OPEN_PAREN), &expr.original_type);
1690 	      set_c_expr_source_range (&expr, tok_range);
1691 	    }
1692 	  break;
1693 	}
1694       else
1695 	{
1696 	  c_parser_error (parser, "expected expression");
1697 	  expr.set_error ();
1698 	  break;
1699 	}
1700       break;
1701     default:
1702       c_parser_error (parser, "expected expression");
1703       expr.set_error ();
1704       break;
1705     }
1706   return c_parser_gimple_postfix_expression_after_primary
1707     (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
1708 }
1709 
1710 /* Parse a gimple postfix expression after the initial primary or compound
1711    literal.  */
1712 
1713 static struct c_expr
c_parser_gimple_postfix_expression_after_primary(gimple_parser & parser,location_t expr_loc,struct c_expr expr)1714 c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
1715 						  location_t expr_loc,
1716 						  struct c_expr expr)
1717 {
1718   location_t start;
1719   location_t finish;
1720   tree ident;
1721   location_t comp_loc;
1722 
1723   while (true)
1724     {
1725       location_t op_loc = c_parser_peek_token (parser)->location;
1726       switch (c_parser_peek_token (parser)->type)
1727 	{
1728 	case CPP_OPEN_SQUARE:
1729 	  {
1730 	    c_parser_consume_token (parser);
1731 	    tree idx = c_parser_gimple_unary_expression (parser).value;
1732 
1733 	    if (! c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"))
1734 	      {
1735 		c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
1736 		break;
1737 	      }
1738 
1739 	    start = expr.get_start ();
1740 	    finish = c_parser_tokens_buf (parser, 0)->location;
1741 	    expr.value = build_array_ref (op_loc, expr.value, idx);
1742 	    set_c_expr_source_range (&expr, start, finish);
1743 
1744 	    expr.original_code = ERROR_MARK;
1745 	    expr.original_type = NULL;
1746 	    break;
1747 	  }
1748 	case CPP_OPEN_PAREN:
1749 	  {
1750 	    /* Function call.  */
1751 	    c_parser_consume_token (parser);
1752 	    auto_vec<tree> exprlist;
1753 	    if (! c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
1754 	      c_parser_gimple_expr_list (parser, &exprlist);
1755 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
1756 				       "expected %<)%>");
1757 	    expr.value = build_call_array_loc
1758 		(expr_loc, TREE_TYPE (TREE_TYPE (expr.value)),
1759 		 expr.value, exprlist.length (), exprlist.address ());
1760 	    expr.original_code = ERROR_MARK;
1761 	    expr.original_type = NULL;
1762 	    break;
1763 	  }
1764 	case CPP_DOT:
1765 	  {
1766 	    /* Structure element reference.  */
1767 	    c_parser_consume_token (parser);
1768 	    if (c_parser_next_token_is (parser, CPP_NAME))
1769 	      {
1770 		c_token *comp_tok = c_parser_peek_token (parser);
1771 		ident = comp_tok->value;
1772 		comp_loc = comp_tok->location;
1773 	      }
1774 	    else
1775 	      {
1776 		c_parser_error (parser, "expected identifier");
1777 		expr.set_error ();
1778 		expr.original_code = ERROR_MARK;
1779 		expr.original_type = NULL;
1780 		return expr;
1781 	      }
1782 	    start = expr.get_start ();
1783 	    finish = c_parser_peek_token (parser)->get_finish ();
1784 	    c_parser_consume_token (parser);
1785 	    expr.value = build_component_ref (op_loc, expr.value, ident,
1786 					      comp_loc);
1787 	    set_c_expr_source_range (&expr, start, finish);
1788 	    expr.original_code = ERROR_MARK;
1789 	    if (TREE_CODE (expr.value) != COMPONENT_REF)
1790 	      expr.original_type = NULL;
1791 	    else
1792 	      {
1793 		/* Remember the original type of a bitfield.  */
1794 		tree field = TREE_OPERAND (expr.value, 1);
1795 		if (TREE_CODE (field) != FIELD_DECL)
1796 		  expr.original_type = NULL;
1797 		else
1798 		  expr.original_type = DECL_BIT_FIELD_TYPE (field);
1799 	      }
1800 	    break;
1801 	  }
1802 	case CPP_DEREF:
1803 	  {
1804 	    /* Structure element reference.  */
1805 	    c_parser_consume_token (parser);
1806 	    if (c_parser_next_token_is (parser, CPP_NAME))
1807 	      {
1808 		c_token *comp_tok = c_parser_peek_token (parser);
1809 		ident = comp_tok->value;
1810 		comp_loc = comp_tok->location;
1811 	      }
1812 	    else
1813 	      {
1814 		c_parser_error (parser, "expected identifier");
1815 		expr.set_error ();
1816 		expr.original_code = ERROR_MARK;
1817 		expr.original_type = NULL;
1818 		return expr;
1819 	      }
1820 	    start = expr.get_start ();
1821 	    finish = c_parser_peek_token (parser)->get_finish ();
1822 	    c_parser_consume_token (parser);
1823 	    expr.value = build_component_ref (op_loc,
1824 					      build_simple_mem_ref_loc
1825 					        (op_loc, expr.value),
1826 					      ident, comp_loc);
1827 	    set_c_expr_source_range (&expr, start, finish);
1828 	    expr.original_code = ERROR_MARK;
1829 	    if (TREE_CODE (expr.value) != COMPONENT_REF)
1830 	      expr.original_type = NULL;
1831 	    else
1832 	      {
1833 		/* Remember the original type of a bitfield.  */
1834 		tree field = TREE_OPERAND (expr.value, 1);
1835 		if (TREE_CODE (field) != FIELD_DECL)
1836 		  expr.original_type = NULL;
1837 		else
1838 		  expr.original_type = DECL_BIT_FIELD_TYPE (field);
1839 	      }
1840 	    break;
1841 	  }
1842 	default:
1843 	  return expr;
1844 	}
1845     }
1846 }
1847 
1848 /* Parse expression list.
1849 
1850    gimple-expr-list:
1851      gimple-unary-expression
1852      gimple-expr-list , gimple-unary-expression
1853 
1854  */
1855 
1856 static void
c_parser_gimple_expr_list(gimple_parser & parser,vec<tree> * ret)1857 c_parser_gimple_expr_list (gimple_parser &parser, vec<tree> *ret)
1858 {
1859   struct c_expr expr;
1860 
1861   expr = c_parser_gimple_unary_expression (parser);
1862   ret->safe_push (expr.value);
1863   while (c_parser_next_token_is (parser, CPP_COMMA))
1864     {
1865       c_parser_consume_token (parser);
1866       expr = c_parser_gimple_unary_expression (parser);
1867       ret->safe_push (expr.value);
1868     }
1869 }
1870 
1871 /* Parse gimple label.
1872 
1873    gimple-label:
1874      identifier :
1875      case constant-expression :
1876      default :
1877 
1878 */
1879 
1880 static void
c_parser_gimple_label(gimple_parser & parser,gimple_seq * seq)1881 c_parser_gimple_label (gimple_parser &parser, gimple_seq *seq)
1882 {
1883   tree name = c_parser_peek_token (parser)->value;
1884   location_t loc1 = c_parser_peek_token (parser)->location;
1885   gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
1886   c_parser_consume_token (parser);
1887   gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
1888   c_parser_consume_token (parser);
1889   tree label = define_label (loc1, name);
1890   gimple_seq_add_stmt_without_update (seq, gimple_build_label (label));
1891   return;
1892 }
1893 
1894 /* Parse gimple/RTL pass list.
1895 
1896    gimple-or-rtl-pass-list:
1897      startwith("pass-name")[,{cfg,ssa}]
1898  */
1899 
1900 void
c_parser_gimple_or_rtl_pass_list(c_parser * parser,c_declspecs * specs)1901 c_parser_gimple_or_rtl_pass_list (c_parser *parser, c_declspecs *specs)
1902 {
1903   char *pass = NULL;
1904 
1905   /* Accept __GIMPLE/__RTL.  */
1906   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
1907     return;
1908   c_parser_consume_token (parser);
1909 
1910   specs->entry_bb_count = profile_count::uninitialized ();
1911   while (c_parser_next_token_is (parser, CPP_NAME))
1912     {
1913       profile_quality quality;
1914       const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
1915       c_parser_consume_token (parser);
1916       if (! strcmp (op, "startwith"))
1917 	{
1918 	  if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1919 	    return;
1920 	  if (c_parser_next_token_is_not (parser, CPP_STRING))
1921 	    {
1922 	      error_at (c_parser_peek_token (parser)->location,
1923 			"expected pass name");
1924 	      return;
1925 	    }
1926 	  pass = xstrdup (TREE_STRING_POINTER
1927 			  (c_parser_string_literal (parser, false,
1928 						    false).value));
1929 	  if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<(%>"))
1930 	    return;
1931 	}
1932       else if (parse_profile_quality (op, &quality))
1933 	{
1934 	  tree q;
1935 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1936 	    return;
1937 
1938 	  if (!c_parser_next_token_is (parser, CPP_NUMBER)
1939 	      || (TREE_CODE (q = c_parser_peek_token (parser)->value)
1940 		  != INTEGER_CST))
1941 	    {
1942 	      c_parser_error (parser, "expected count value");
1943 	      return;
1944 	    }
1945 
1946 	  specs->entry_bb_count
1947 	    = profile_count::from_gcov_type (TREE_INT_CST_LOW (q), quality);
1948 	  c_parser_consume_token (parser);
1949 	  if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1950 	    return;
1951 	}
1952       else if (specs->declspec_il != cdil_gimple)
1953 	/* Allow only one IL specifier and none on RTL.  */
1954 	;
1955       else if (! strcmp (op, "cfg"))
1956 	specs->declspec_il = cdil_gimple_cfg;
1957       else if (! strcmp (op, "ssa"))
1958 	specs->declspec_il = cdil_gimple_ssa;
1959       else
1960 	{
1961 	  error_at (c_parser_peek_token (parser)->location,
1962 		    "invalid operation");
1963 	  return;
1964 	}
1965      if (c_parser_next_token_is (parser, CPP_COMMA))
1966        c_parser_consume_token (parser);
1967     }
1968 
1969   if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
1970     return;
1971 
1972   specs->gimple_or_rtl_pass = pass;
1973 }
1974 
1975 /* Parse gimple local declaration.
1976 
1977    declaration-specifiers:
1978      storage-class-specifier declaration-specifiers[opt]
1979      type-specifier declaration-specifiers[opt]
1980      type-qualifier declaration-specifiers[opt]
1981      function-specifier declaration-specifiers[opt]
1982      alignment-specifier declaration-specifiers[opt]
1983 
1984    storage-class-specifier:
1985      typedef
1986      extern
1987      static
1988      auto
1989      register
1990 
1991    type-specifier:
1992      void
1993      char
1994      short
1995      int
1996      long
1997      float
1998      double
1999      signed
2000      unsigned
2001      _Bool
2002      _Complex
2003 
2004    type-qualifier:
2005      const
2006      restrict
2007      volatile
2008      address-space-qualifier
2009      _Atomic
2010 
2011  */
2012 
2013 static void
c_parser_gimple_declaration(gimple_parser & parser)2014 c_parser_gimple_declaration (gimple_parser &parser)
2015 {
2016   struct c_declarator *declarator;
2017   struct c_declspecs *specs = build_null_declspecs ();
2018   c_parser_declspecs (parser, specs, true, true, true,
2019 		      true, true, true, true, cla_nonabstract_decl);
2020   finish_declspecs (specs);
2021 
2022   /* Provide better error recovery.  Note that a type name here is usually
2023      better diagnosed as a redeclaration.  */
2024   if (c_parser_next_token_starts_declspecs (parser)
2025       && ! c_parser_next_token_is (parser, CPP_NAME))
2026     {
2027       c_parser_error (parser, "expected %<;%>");
2028       c_parser_set_error (parser, false);
2029       return;
2030     }
2031 
2032   bool dummy = false;
2033   declarator = c_parser_declarator (parser,
2034 				    specs->typespec_kind != ctsk_none,
2035 				    C_DTR_NORMAL, &dummy);
2036 
2037   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2038     {
2039       /* Handle SSA name decls specially, they do not go into the identifier
2040          table but we simply build the SSA name for later lookup.  */
2041       unsigned version, ver_offset;
2042       if (declarator->kind == cdk_id
2043 	  && is_gimple_reg_type (specs->type)
2044 	  && c_parser_parse_ssa_name_id (declarator->u.id.id,
2045 					 &version, &ver_offset)
2046 	  /* The following restricts it to unnamed anonymous SSA names
2047 	     which fails parsing of named ones in dumps (we could
2048 	     decide to not dump their name for -gimple).  */
2049 	  && ver_offset == 0)
2050 	c_parser_parse_ssa_name (parser, declarator->u.id.id, specs->type,
2051 				 version, ver_offset);
2052       else
2053 	{
2054 	  tree postfix_attrs = NULL_TREE;
2055 	  tree all_prefix_attrs = specs->attrs;
2056 	  specs->attrs = NULL;
2057 	  tree decl = start_decl (declarator, specs, false,
2058 				  chainon (postfix_attrs, all_prefix_attrs));
2059 	  if (decl)
2060 	    finish_decl (decl, UNKNOWN_LOCATION, NULL_TREE, NULL_TREE,
2061 			 NULL_TREE);
2062 	}
2063     }
2064   else
2065     {
2066       c_parser_error (parser, "expected %<;%>");
2067       return;
2068     }
2069 }
2070 
2071 /* Parse gimple goto statement.  */
2072 
2073 static void
c_parser_gimple_goto_stmt(gimple_parser & parser,location_t loc,tree label,gimple_seq * seq)2074 c_parser_gimple_goto_stmt (gimple_parser &parser,
2075 			   location_t loc, tree label, gimple_seq *seq)
2076 {
2077   if (cfun->curr_properties & PROP_cfg)
2078     {
2079       int dest_index;
2080       profile_probability prob;
2081       if (c_parser_gimple_parse_bb_spec_edge_probability (label, parser,
2082 							  &dest_index, &prob))
2083 	{
2084 	  parser.push_edge (parser.current_bb->index, dest_index,
2085 			    EDGE_FALLTHRU, prob);
2086 	  return;
2087 	}
2088     }
2089   tree decl = lookup_label_for_goto (loc, label);
2090   gimple_seq_add_stmt_without_update (seq, gimple_build_goto (decl));
2091 }
2092 
2093 /* Parse a parenthesized condition.
2094    gimple-condition:
2095      ( gimple-binary-expression )    */
2096 
2097 static tree
c_parser_gimple_paren_condition(gimple_parser & parser)2098 c_parser_gimple_paren_condition (gimple_parser &parser)
2099 {
2100   if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2101     return error_mark_node;
2102   tree cond = c_parser_gimple_binary_expression (parser).value;
2103   if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
2104     return error_mark_node;
2105   return cond;
2106 }
2107 
2108 /* Parse gimple try statement.
2109 
2110    try-statement:
2111      try { ... } finally { ... }
2112      try { ... } finally { ... } else { ... }
2113 
2114    This could support try/catch as well, but it's not implemented yet.
2115  */
2116 
2117 static void
c_parser_gimple_try_stmt(gimple_parser & parser,gimple_seq * seq)2118 c_parser_gimple_try_stmt (gimple_parser &parser, gimple_seq *seq)
2119 {
2120   gimple_seq tryseq = NULL;
2121   c_parser_consume_token (parser);
2122   c_parser_gimple_compound_statement (parser, &tryseq);
2123 
2124   if ((c_parser_next_token_is (parser, CPP_KEYWORD)
2125        && c_parser_peek_token (parser)->keyword == RID_AT_FINALLY)
2126       || (c_parser_next_token_is (parser, CPP_NAME)
2127 	  && c_parser_peek_token (parser)->id_kind == C_ID_ID
2128 	  && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
2129 		     "finally") == 0))
2130     {
2131       gimple_seq finseq = NULL;
2132       c_parser_consume_token (parser);
2133       c_parser_gimple_compound_statement (parser, &finseq);
2134 
2135       if (c_parser_next_token_is (parser, CPP_KEYWORD)
2136 	  && c_parser_peek_token (parser)->keyword == RID_ELSE)
2137 	{
2138 	  gimple_seq elsseq = NULL;
2139 	  c_parser_consume_token (parser);
2140 	  c_parser_gimple_compound_statement (parser, &elsseq);
2141 
2142 	  geh_else *stmt = gimple_build_eh_else (finseq, elsseq);
2143 	  finseq = NULL;
2144 	  gimple_seq_add_stmt_without_update (&finseq, stmt);
2145 	}
2146 
2147       gtry *stmt = gimple_build_try (tryseq, finseq, GIMPLE_TRY_FINALLY);
2148       gimple_seq_add_stmt_without_update (seq, stmt);
2149     }
2150   else if (c_parser_next_token_is (parser, CPP_KEYWORD)
2151       && c_parser_peek_token (parser)->keyword == RID_AT_CATCH)
2152     c_parser_error (parser, "%<catch%> is not supported");
2153   else
2154     c_parser_error (parser, "expected %<finally%> or %<catch%>");
2155 }
2156 
2157 /* Parse gimple if-else statement.
2158 
2159    if-statement:
2160      if ( gimple-binary-expression ) gimple-goto-statement
2161      if ( gimple-binary-expression ) gimple-goto-statement \
2162 					else gimple-goto-statement
2163  */
2164 
2165 static void
c_parser_gimple_if_stmt(gimple_parser & parser,gimple_seq * seq)2166 c_parser_gimple_if_stmt (gimple_parser &parser, gimple_seq *seq)
2167 {
2168   tree t_label = NULL_TREE, f_label = NULL_TREE, label;
2169   location_t loc;
2170   c_parser_consume_token (parser);
2171   tree cond = c_parser_gimple_paren_condition (parser);
2172 
2173   if (c_parser_next_token_is_keyword (parser, RID_GOTO))
2174     {
2175       loc = c_parser_peek_token (parser)->location;
2176       c_parser_consume_token (parser);
2177       if (! c_parser_next_token_is (parser, CPP_NAME))
2178 	{
2179 	  c_parser_error (parser, "expected label");
2180 	  return;
2181 	}
2182       label = c_parser_peek_token (parser)->value;
2183       c_parser_consume_token (parser);
2184       int dest_index;
2185       profile_probability prob;
2186       if ((cfun->curr_properties & PROP_cfg)
2187 	  && c_parser_gimple_parse_bb_spec_edge_probability (label, parser,
2188 							     &dest_index, &prob))
2189 	parser.push_edge (parser.current_bb->index, dest_index,
2190 			  EDGE_TRUE_VALUE, prob);
2191       else
2192 	t_label = lookup_label_for_goto (loc, label);
2193       if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2194 	return;
2195     }
2196   else
2197     {
2198       c_parser_error (parser, "expected goto expression");
2199       return;
2200     }
2201 
2202   if (c_parser_next_token_is_keyword (parser, RID_ELSE))
2203     c_parser_consume_token (parser);
2204   else
2205     {
2206       c_parser_error (parser, "expected else statement");
2207       return;
2208     }
2209 
2210   if (c_parser_next_token_is_keyword (parser, RID_GOTO))
2211     {
2212       loc = c_parser_peek_token (parser)->location;
2213       c_parser_consume_token (parser);
2214       if (! c_parser_next_token_is (parser, CPP_NAME))
2215 	{
2216 	  c_parser_error (parser, "expected label");
2217 	  return;
2218 	}
2219       label = c_parser_peek_token (parser)->value;
2220       c_parser_consume_token (parser);
2221       int dest_index;
2222       profile_probability prob;
2223       if ((cfun->curr_properties & PROP_cfg)
2224 	  && c_parser_gimple_parse_bb_spec_edge_probability (label, parser,
2225 							     &dest_index, &prob))
2226 	parser.push_edge (parser.current_bb->index, dest_index,
2227 			  EDGE_FALSE_VALUE, prob);
2228       else
2229 	f_label = lookup_label_for_goto (loc, label);
2230       if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2231 	return;
2232     }
2233   else
2234     {
2235       c_parser_error (parser, "expected goto expression");
2236       return;
2237     }
2238 
2239   if (cond != error_mark_node)
2240     gimple_seq_add_stmt_without_update (seq, gimple_build_cond_from_tree (cond, t_label,
2241 							   f_label));
2242 }
2243 
2244 /* Parse gimple switch-statement.
2245 
2246    gimple-switch-statement:
2247      switch (gimple-postfix-expression) gimple-case-statement
2248 
2249    gimple-case-statement:
2250      gimple-case-statement
2251      gimple-label-statement : gimple-goto-statment
2252 */
2253 
2254 static void
c_parser_gimple_switch_stmt(gimple_parser & parser,gimple_seq * seq)2255 c_parser_gimple_switch_stmt (gimple_parser &parser, gimple_seq *seq)
2256 {
2257   c_expr cond_expr;
2258   tree case_label, label;
2259   auto_vec<tree> labels;
2260   tree default_label = NULL_TREE;
2261   c_parser_consume_token (parser);
2262 
2263   if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2264     return;
2265   cond_expr = c_parser_gimple_postfix_expression (parser);
2266   if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
2267     return;
2268 
2269   if (! c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
2270     return;
2271 
2272   while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
2273     {
2274       if (c_parser_next_token_is (parser, CPP_EOF))
2275 	{
2276 	  c_parser_error (parser, "expected statement");
2277 	  return;
2278 	}
2279 
2280       switch (c_parser_peek_token (parser)->keyword)
2281 	{
2282 	case RID_CASE:
2283 	  {
2284 	    c_expr exp1;
2285 	    location_t loc = c_parser_peek_token (parser)->location;
2286 	    c_parser_consume_token (parser);
2287 
2288 	    if (c_parser_next_token_is (parser, CPP_NAME)
2289 		|| c_parser_peek_token (parser)->type == CPP_NUMBER)
2290 	      exp1 = c_parser_gimple_postfix_expression (parser);
2291 	    else
2292 	      {
2293 		c_parser_error (parser, "expected expression");
2294 		return;
2295 	      }
2296 
2297 	    if (c_parser_next_token_is (parser, CPP_COLON))
2298 	      {
2299 		c_parser_consume_token (parser);
2300 		if (c_parser_next_token_is (parser, CPP_NAME))
2301 		  {
2302 		    label = c_parser_peek_token (parser)->value;
2303 		    c_parser_consume_token (parser);
2304 		    tree decl = lookup_label_for_goto (loc, label);
2305 		    case_label = build_case_label (exp1.value, NULL_TREE,
2306 						   decl);
2307 		    labels.safe_push (case_label);
2308 		    if (! c_parser_require (parser, CPP_SEMICOLON,
2309 					    "expected %<;%>"))
2310 		      return;
2311 		  }
2312 		else if (! c_parser_require (parser, CPP_NAME,
2313 					     "expected label"))
2314 		  return;
2315 	      }
2316 	    else if (! c_parser_require (parser, CPP_SEMICOLON,
2317 					 "expected %<:%>"))
2318 	      return;
2319 	    break;
2320 	  }
2321 	case RID_DEFAULT:
2322 	  {
2323 	    location_t loc = c_parser_peek_token (parser)->location;
2324 	    c_parser_consume_token (parser);
2325 	    if (c_parser_next_token_is (parser, CPP_COLON))
2326 	      {
2327 		c_parser_consume_token (parser);
2328 		if (c_parser_next_token_is (parser, CPP_NAME))
2329 		  {
2330 		    label = c_parser_peek_token (parser)->value;
2331 		    c_parser_consume_token (parser);
2332 		    tree decl = lookup_label_for_goto (loc, label);
2333 		    default_label = build_case_label (NULL_TREE, NULL_TREE,
2334 						      decl);
2335 		    if (! c_parser_require (parser, CPP_SEMICOLON,
2336 					    "expected %<;%>"))
2337 		      return;
2338 		  }
2339 		else if (! c_parser_require (parser, CPP_NAME,
2340 					     "expected label"))
2341 		  return;
2342 	      }
2343 	    else if (! c_parser_require (parser, CPP_SEMICOLON,
2344 					 "expected %<:%>"))
2345 	      return;
2346 	    break;
2347 	  }
2348 	default:
2349 	  c_parser_error (parser, "expected case label");
2350 	  return;
2351 	}
2352 
2353     }
2354   if (! c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
2355     return;
2356 
2357   if (cond_expr.value != error_mark_node)
2358     {
2359       gswitch *s = gimple_build_switch (cond_expr.value, default_label, labels);
2360       gimple_seq_add_stmt_without_update (seq, s);
2361     }
2362 }
2363 
2364 /* Parse gimple return statement.  */
2365 
2366 static void
c_parser_gimple_return_stmt(gimple_parser & parser,gimple_seq * seq)2367 c_parser_gimple_return_stmt (gimple_parser &parser, gimple_seq *seq)
2368 {
2369   location_t loc = c_parser_peek_token (parser)->location;
2370   gimple *ret = NULL;
2371   c_parser_consume_token (parser);
2372   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2373     {
2374       c_finish_gimple_return (loc, NULL_TREE);
2375       ret = gimple_build_return (NULL);
2376       gimple_seq_add_stmt_without_update (seq, ret);
2377     }
2378   else
2379     {
2380       location_t xloc = c_parser_peek_token (parser)->location;
2381       c_expr expr = c_parser_gimple_unary_expression (parser);
2382       if (expr.value != error_mark_node)
2383 	{
2384 	  c_finish_gimple_return (xloc, expr.value);
2385 	  ret = gimple_build_return (expr.value);
2386 	  gimple_seq_add_stmt_without_update (seq, ret);
2387 	}
2388     }
2389 }
2390 
2391 /* Support function for c_parser_gimple_return_stmt.  */
2392 
2393 static void
c_finish_gimple_return(location_t loc,tree retval)2394 c_finish_gimple_return (location_t loc, tree retval)
2395 {
2396   tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
2397 
2398   /* Use the expansion point to handle cases such as returning NULL
2399      in a function returning void.  */
2400   location_t xloc = expansion_point_location_if_in_system_header (loc);
2401 
2402   if (TREE_THIS_VOLATILE (current_function_decl))
2403     warning_at (xloc, 0,
2404 		"function declared %<noreturn%> has a %<return%> statement");
2405 
2406   if (! retval)
2407     current_function_returns_null = 1;
2408   else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
2409     {
2410       current_function_returns_null = 1;
2411       if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
2412 	{
2413 	  error_at
2414 	    (xloc, "%<return%> with a value, in function returning void");
2415 	  inform (DECL_SOURCE_LOCATION (current_function_decl),
2416 		  "declared here");
2417 	}
2418     }
2419   else if (TREE_CODE (valtype) != TREE_CODE (TREE_TYPE (retval)))
2420     {
2421       error_at
2422 	(xloc, "invalid conversion in return statement");
2423       inform (DECL_SOURCE_LOCATION (current_function_decl),
2424 	      "declared here");
2425     }
2426   return;
2427 }
2428