예제 #1
0
void check(tree t) {
	// We can ignore the procedure and its ident
	check_stmt(t->second);
	check_stmt(t->third);
	
	end_scope();
}
예제 #2
0
int check_do_while(is_do_while* node, is_label* label)
{
	int errors = 0;

	int mylabel = ++label_counter; /* setting label for use with loops and break/continue */

	if (label)
		node->scope = scope_new(symbol_new_loop(label->name, node->line, mylabel), false);
	else
		node->scope = scope_new(symbol_new_loop(NULL, node->line, mylabel), false);
		
	scope_push(node->scope);
		errors += check_stmt(node->body);
		if (errors == 0)
			node->terminates = node->body->terminates;

		errors += check_expr(node->cond);
		if (errors == 0)
		{
			if (!type_native_assign_able(t_type_native_bool, node->cond->s_type))
			{
				errors++;
				pretty_error(node->line, "invalid do..while condition (must be boolean)");
			}
		}
	scope_pop();
	return errors;
}
예제 #3
0
int check_while(is_while* node, is_label* label)
{
	int errors = 0;
	char *string;

	int mylabel = ++label_counter; /* setting label for use with loops and break/continue */
	
	if (label)
		node->scope = scope_new(symbol_new_loop(label->name, node->line, mylabel), false);
	else
		node->scope = scope_new(symbol_new_loop(NULL, node->line, mylabel), false);
		
	scope_push(node->scope);
		errors += check_expr(node->cond);
		if (errors == 0)
		{
			if (!type_native_assign_able(t_type_native_bool, node->cond->s_type))
			{
				errors++;
				pretty_error(node->line, "invalid while condition: expected boolean, got %s", string = string_type_decl(node->cond->s_type));
				free(string);
			}
		}

		errors += check_stmt(node->body);
		node->terminates = node->body->terminates;
	scope_pop();
	
	return errors;
}
예제 #4
0
int check_stmt_list(is_stmt_list* node)
{
	int errors = 0;

	if (node)
	{
		errors += check_stmt(node->node);
		errors += check_stmt_list(node->next);

		if (node->node)
			node->terminated = node->node->terminates;
		else
			node->terminated = false;

		if (node->next)
		{
			node->length = node->next->length+1;
			
			if (node->terminated)
				pretty_error(node->line, "dead code after incoditional jump stmt");
			else
				node->terminated = node->next->terminated;
		} else
			node->length = 1;
	}

	return errors;
}
예제 #5
0
int check_if(is_if* node)
{
	int errors = 0;
	char* typeA;

	errors += check_expr(node->cond);
	if (errors == 0 && !type_native_assign_able(t_type_native_bool, node->cond->s_type))
	{
		errors++;
		pretty_error(node->line, "if conditional is not boolean (is of type %s)", typeA = string_type_decl(node->cond->s_type));
		free(typeA);
	}	

	errors += check_stmt(node->then_body);
	node->terminates = node->then_body->terminates && node->else_body != NULL;
	if (node->else_body)
	{
		errors += check_stmt(node->else_body);
		node->terminates &= node->else_body->terminates;
	}

	return errors;
}
예제 #6
0
파일: ipa-pure-const.c 프로젝트: Xilinx/gcc
static funct_state
analyze_function (struct cgraph_node *fn, bool ipa)
{
  tree decl = fn->decl;
  funct_state l;
  basic_block this_block;

  l = XCNEW (struct funct_state_d);
  l->pure_const_state = IPA_CONST;
  l->state_previously_known = IPA_NEITHER;
  l->looping_previously_known = true;
  l->looping = false;
  l->can_throw = false;
  state_from_flags (&l->state_previously_known, &l->looping_previously_known,
		    flags_from_decl_or_type (fn->decl),
		    fn->cannot_return_p ());

  if (fn->thunk.thunk_p || fn->alias)
    {
      /* Thunk gets propagated through, so nothing interesting happens.  */
      gcc_assert (ipa);
      return l;
    }

  if (dump_file)
    {
      fprintf (dump_file, "\n\n local analysis of %s\n ",
	       fn->name ());
    }

  push_cfun (DECL_STRUCT_FUNCTION (decl));

  FOR_EACH_BB_FN (this_block, cfun)
    {
      gimple_stmt_iterator gsi;
      struct walk_stmt_info wi;

      memset (&wi, 0, sizeof (wi));
      for (gsi = gsi_start_bb (this_block);
	   !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  check_stmt (&gsi, l, ipa);
	  if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
	    goto end;
	}
    }
예제 #7
0
void check_stmt(tree t) {
	for( ; t != NULL; t = t->next ) {
		switch (t->kind) {
			case If:
			case Elseif:
				if( check_expr(t->first) != Boolean ) {
					print_error("Invalid IF statement.", t);
				}
				check_stmt(t->second);
				check_stmt(t->third);
				continue;
			case Else:
				check_stmt(t->first);
				continue;
			case Exit:
				if(check_expr(t->first) != Boolean) {
					print_error("exit when must produce a boolean.", t);
				}
				continue;
			case Assign:
				if(t->first->kind == Obracket | check_expr(t->first) != check_expr(t->second)) {
					print_error("Invalid assignment statement.", t);
				}
				continue;
			case For:
				new_scope();
				declare_var(id_name(t->first->value), Integer);
				if(check_expr(t->second->first) != Integer | check_expr(t->second->second) != Integer)//TODO or add a range check
					print_error("Invalid range.", t->second);
				
				check_stmt(t->third);
				end_scope();
				continue;
			case Declaration:;
				if(t->second->kind == Array) {
					for(tree cur = t->first; cur != NULL; cur = cur->next)
						declare_array(id_name(cur->value), t->second->second->kind);
				} else {
					for(tree cur = t->first; cur != NULL; cur = cur->next)
						declare_var(id_name(cur->value), t->second->kind);
				}
				continue;
			case Declare:
				new_scope();
				check_stmt(t->first);
				check_stmt(t->second);
				end_scope();
				continue;
			default:
				print_error("Token of this type not checked by check_stmt.", t);
				continue;
		}
	}
}
예제 #8
0
int my_stmt_result(const char *buff)
{
 MYSQL_STMT *stmt;
 int        row_count;
 int        rc;

 if (!opt_silent)
 fprintf(stdout, "\n\n %s", buff);
 stmt= mysql_simple_prepare(mysql, buff);
 check_stmt(stmt);

 rc= mysql_stmt_execute(stmt);
 check_execute(stmt, rc);

 row_count= my_process_stmt_result(stmt);
 mysql_stmt_close(stmt);

 return row_count;
}
예제 #9
0
int check_for(is_for* node, is_label* label)
{
	int errors = 0, cond_errors;
	char* typeA;

	int mylabel = ++label_counter; /* setting label for use with loops and break/continue */

	if (label)
		node->scope = scope_new(symbol_new_loop(label->name, node->line, mylabel), false);
	else
		node->scope = scope_new(symbol_new_loop(NULL, node->line, mylabel), false);
		
	scope_push(node->scope);
		if (node->init)
			errors += check_for_init(node->init);

		if (node->cond)
		{
			cond_errors = check_for_cond(node->cond);
			if (cond_errors == 0)
			{
				if (!type_native_assign_able(t_type_native_bool, node->cond->s_type))
				{
					cond_errors++;
					pretty_error(node->line, "for conditional is not boolean (is of type %s)", typeA = string_type_decl(node->cond->s_type));
					free(typeA);
				}
			}
			errors += cond_errors;
		}
	
		if (node->inc)
			errors += check_for_inc(node->inc);

		errors += check_stmt(node->body);

		if (errors == 0)
			node->terminates = (node->body ? node->body->terminates : true);
	scope_pop();
 
	return errors;
}
예제 #10
0
static void execute_prepare_query(const char *query, ulonglong exp_count)
{
 MYSQL_STMT *stmt;
 ulonglong  affected_rows;
 int        rc;

 stmt= mysql_simple_prepare(mysql, query);
 check_stmt(stmt);

 rc= mysql_stmt_execute(stmt);
 myquery(rc);

 affected_rows= mysql_stmt_affected_rows(stmt);
 if (!opt_silent)
 fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)",
 (long) affected_rows, (long) exp_count);

 DIE_UNLESS(affected_rows == exp_count);
 mysql_stmt_close(stmt);
}
예제 #11
0
static funct_state
analyze_function (struct cgraph_node *fn, bool ipa)
{
  tree decl = fn->symbol.decl;
  funct_state l;
  basic_block this_block;

  l = XCNEW (struct funct_state_d);
  l->pure_const_state = IPA_CONST;
  l->state_previously_known = IPA_NEITHER;
  l->looping_previously_known = true;
  l->looping = false;
  l->can_throw = false;
  state_from_flags (&l->state_previously_known, &l->looping_previously_known,
		    flags_from_decl_or_type (fn->symbol.decl),
		    cgraph_node_cannot_return (fn));

  if (fn->thunk.thunk_p || fn->symbol.alias)
    {
      /* Thunk gets propagated through, so nothing interesting happens.  */
      gcc_assert (ipa);
      return l;
    }

  if (dump_file)
    {
      fprintf (dump_file, "\n\n local analysis of %s\n ",
	       cgraph_node_name (fn));
    }

  push_cfun (DECL_STRUCT_FUNCTION (decl));

  FOR_EACH_BB (this_block)
    {
      gimple_stmt_iterator gsi;
      struct walk_stmt_info wi;

      memset (&wi, 0, sizeof(wi));
      for (gsi = gsi_start_bb (this_block);
	   !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  check_stmt (&gsi, l, ipa);
	  if (l->pure_const_state == IPA_NEITHER && l->looping && l->can_throw)
	    goto end;
	}
    }

end:
  if (l->pure_const_state != IPA_NEITHER)
    {
      /* Const functions cannot have back edges (an
	 indication of possible infinite loop side
	 effect.  */
      if (mark_dfs_back_edges ())
        {
	  /* Preheaders are needed for SCEV to work.
	     Simple latches and recorded exits improve chances that loop will
	     proved to be finite in testcases such as in loop-15.c
	     and loop-24.c  */
	  loop_optimizer_init (LOOPS_HAVE_PREHEADERS
			       | LOOPS_HAVE_SIMPLE_LATCHES
			       | LOOPS_HAVE_RECORDED_EXITS);
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    flow_loops_dump (dump_file, NULL, 0);
	  if (mark_irreducible_loops ())
	    {
	      if (dump_file)
	        fprintf (dump_file, "    has irreducible loops\n");
	      l->looping = true;
	    }
	  else
	    {
	      loop_iterator li;
	      struct loop *loop;
	      scev_initialize ();
	      FOR_EACH_LOOP (li, loop, 0)
		if (!finite_loop_p (loop))
		  {
		    if (dump_file)
		      fprintf (dump_file, "    can not prove finiteness of "
			       "loop %i\n", loop->num);
		    l->looping =true;
		    FOR_EACH_LOOP_BREAK (li);
		  }
	      scev_finalize ();
	    }
          loop_optimizer_finalize ();
	}
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "    checking previously known:");

  better_state (&l->pure_const_state, &l->looping,
		l->state_previously_known,
		l->looping_previously_known);
  if (TREE_NOTHROW (decl))
    l->can_throw = false;

  pop_cfun ();
  if (dump_file)
    {
      if (l->looping)
        fprintf (dump_file, "Function is locally looping.\n");
      if (l->can_throw)
        fprintf (dump_file, "Function is locally throwing.\n");
      if (l->pure_const_state == IPA_CONST)
        fprintf (dump_file, "Function is locally const.\n");
      if (l->pure_const_state == IPA_PURE)
        fprintf (dump_file, "Function is locally pure.\n");
    }
  return l;
}
예제 #12
0
static inline stmt_wrap * safe_get_stmtw(char *loc, value v_stmt)
{
  stmt_wrap *stmtw = Sqlite3_stmtw_val(v_stmt);
  check_stmt(stmtw, loc);
  return stmtw;
}