Beispiel #1
0
static void write_const(CTX *ctx, struct ir_const_val v)
{
    char *s = const_unparse(NULL, v);
    if (TEST_UNION(IR_TYPE, tarray, &v.type)) {
        fprintf(ctx->f, "{%s}", s);
    } else if (type_is_integer(v.type)) {
        // Get rid of annoying-but-correct gcc warning. This happens because we
        // negate a value not representable in intmax_t, even though the result
        // is representable, i.e. the only case is INT64_MIN.
        if (type_equals(v.type, type_integer(true, 64))
            && *GET_UNION(VALUE, vuint64, &v.value) == INT64_MIN)
        {
            fprintf(ctx->f, "INT64_MIN");
        } else {
            fprintf(ctx->f, "%s(%s)", int_const(v.type), s);
        }
    } else if (TEST_UNION(IR_TYPE, tslice, &v.type)) {
        if (TEST_UNION0(VALUE, vempty, &v.value)) {
            fprintf(ctx->f, "{0}");
        } else if (type_equals(v.type, TYPE_STRING)) {
            char *raw = *GET_UNION(VALUE, vstring, &v.value);
            fprintf(ctx->f, "{ %s, %zd }", s, raw ? strlen(raw) : 0);
        } else {
            assert(false);
        }
    } else {
        fprintf(ctx->f, "%s", s);
    }
    talloc_free(s);
}
Beispiel #2
0
static bool pointerint_conditional(type t1, type t2, expression e2)
{
  if (type_pointer(t1) && type_integer(t2))
    {
      if (!definite_zero(e2))
	pedwarn("pointer/integer type mismatch in conditional expression");
      return TRUE;
    }
  return FALSE;
}
Beispiel #3
0
static void dump_type(type t)
{
  if (type_complex(t))
    {
      printf("C");
      t = make_base_type(t);
    }

  if (type_network_base_type(t))
    printf("N%s", type_networkdef(t)->name);
  /* Enums treated as ints for now */
  else if (type_integer(t))
    if (type_unsigned(t))
      printf("U");
    else
      printf("I");
  else if (type_float(t))
    printf("F");
  else if (type_double(t))
    printf("D");
  else if (type_long_double(t))
    printf("LD");
  else if (type_union(t))
    if (type_network(t))
      printf("ANU");
    else
      printf("AU");
  else if (type_struct(t))
    if (type_network(t))
      printf("ANS");
    else
      printf("AS");
  else if (type_pointer(t))
    printf("U");
  else
    assert(0);
}
Beispiel #4
0
type check_binary(int binop, expression e1, expression e2)
{
  type t1 = default_conversion(e1), t2 = default_conversion(e2);
  type rtype = NULL;
  bool common = FALSE;

  /* XXX: Misc warnings (see build_binary_op) */
  if (t1 == error_type || t2 == error_type)
    rtype = error_type;
  else switch(binop)
    {
    case kind_plus:
      if (type_pointer(t1) && type_integer(t2))
	rtype = pointer_int_sum(t1, t2);
      else if (type_pointer(t2) && type_integer(t1))
	rtype = pointer_int_sum(t2, t1);
      else
	common = TRUE;
      break;

    case kind_minus: 
      if (type_pointer(t1) && type_integer(t2))
	rtype = pointer_int_sum(t1, t2);
      else if (type_pointer(t1) && type_pointer(t2) &&
	       compatible_pointer_types(t1, t2))
	rtype = ptrdiff_t_type;
      else
	common = TRUE;
      break;

    case kind_plus_assign: case kind_minus_assign:
      if (type_pointer(t1) && type_integer(t2))
	rtype = pointer_int_sum(t1, t2);
      else
	common = TRUE;
      break;

    case kind_times: case kind_divide:
    case kind_times_assign: case kind_divide_assign:
      common = TRUE;
      break;

    case kind_modulo: case kind_bitand: case kind_bitor: case kind_bitxor:
    case kind_lshift: case kind_rshift:
    case kind_modulo_assign: case kind_bitand_assign: case kind_bitor_assign:
    case kind_bitxor_assign: case kind_lshift_assign: case kind_rshift_assign:
      if (type_integer(t1) && type_integer(t2))
	rtype = common_type(t1, t2);
      break;

    case kind_leq: case kind_geq: case kind_lt: case kind_gt:
      rtype = int_type; /* Default to assuming success */
      if (type_real(t1) && type_real(t2))
	;
      else if (type_pointer(t1) && type_pointer(t2))
	{
	  if (compatible_pointer_types(t1, t2))
	    {
	      /* XXX: how can this happen ? */
	      if (type_incomplete(t1) != type_incomplete(t2))
		pedwarn("comparison of complete and incomplete pointers");
	      else if (pedantic && type_function(type_points_to(t1)))
		pedwarn("ANSI C forbids ordered comparisons of pointers to functions");
	    }
	  else
	    pedwarn("comparison of distinct pointer types lacks a cast");
	}
      /* XXX: Use of definite_zero may lead to extra warnings when !extra_warnings */
      else if ((type_pointer(t1) && definite_zero(e2)) ||
	       (type_pointer(t2) && definite_zero(e1)))
	{
	  if (pedantic || extra_warnings)
	    pedwarn("ordered comparison of pointer with integer zero");
	}
      else if ((type_pointer(t1) && type_integer(t2)) ||
	       (type_pointer(t2) && type_integer(t1)))
	{
	  if (!flag_traditional)
	    pedwarn("comparison between pointer and integer");
	}
      else
	rtype = NULL; /* Force error */
      break;

    case kind_eq: case kind_ne:
      rtype = int_type; /* Default to assuming success */
      if (type_arithmetic(t1) && type_arithmetic(t2))
	;
      else if (type_pointer(t1) && type_pointer(t2))
	{
	  if (!compatible_pointer_types(t1, t2) &&
	      !valid_compare(t1, t2, e1) &&
	      !valid_compare(t2, t1, e2))
	    pedwarn("comparison of distinct pointer types lacks a cast");
	}
      else if ((type_pointer(t1) && definite_null(e2)) ||
	       (type_pointer(t2) && definite_null(e1)))
	;
      else if ((type_pointer(t1) && type_integer(t2)) ||
	       (type_pointer(t2) && type_integer(t1)))
	{
	  if (!flag_traditional)
	    pedwarn("comparison between pointer and integer");
	}
      else
	rtype = NULL; /* Force error */
      break;

    case kind_andand: case kind_oror:
      if (type_scalar(t1) && type_scalar(t2))
	rtype = int_type;
      break;

    default: assert(0); break;
    }

  if (common && type_arithmetic(t1) && type_arithmetic(t2))
    rtype = common_type(t1, t2);

  if (!rtype)
    {
      error("invalid operands to binary %s", binary_op_name(binop));
      rtype = error_type;
    }

  return rtype;
}
Beispiel #5
0
expression make_unary(location loc, int unop, expression e)
{
  switch (unop)
    {
    case kind_address_of:
      return make_address_of(loc, e);
    case kind_preincrement:
      return make_preincrement(loc, e);
    case kind_predecrement:
      return make_predecrement(loc, e);
    default:
      {
	expression result = CAST(expression, newkind_unary(parse_region, unop, loc, e));
	type etype = default_conversion(e);
	const char *errstring = NULL;

	if (etype == error_type)
	  result->type = error_type;
	else
	  {
	    switch (unop)
	      {
	      case kind_unary_plus:
		if (!type_arithmetic(etype))
		  errstring = "wrong type argument to unary plus";
		break;
	      case kind_unary_minus:
		if (!type_arithmetic(etype))
		  errstring = "wrong type argument to unary minus";
		break;
	      case kind_bitnot:
		if (type_complex(etype))
		  result->kind = kind_conjugate;
		else if (!type_integer(etype))
		  errstring = "wrong type argument to bit-complement";
		break;
	      case kind_not:
		if (!type_scalar(etype))
		  errstring = "wrong type argument to unary exclamation mark";
		else
		  etype = int_type;
		break;
	      case kind_realpart: case kind_imagpart:
		if (!type_arithmetic(etype))
		  if (unop == kind_realpart)
		    errstring = "wrong type argument to __real__";
		  else
		    errstring = "wrong type argument to __imag__";
		else
		  etype = type_complex(etype) ? make_base_type(etype) : etype;
	      default:
		assert(0);
	      }
	    if (errstring)
	      {
		error(errstring);
		result->type = error_type;
	      }
	    else
	      {
		result->type = etype;
		result->cst = fold_unary(result);
	      }
	  }
	return result;
      }
    }
}
Beispiel #6
0
bool check_conversion(type to, type from)
{
  if (type_equal_unqualified(to, from))
    return TRUE;

  if (to == error_type || from == error_type)
    return FALSE;

  if (type_void(from))
    {
      error("void value not ignored as it ought to be");
      return FALSE;
    }

  if (type_void(to))
    return TRUE;

  if (type_integer(to))
    {
      if (!type_scalar(from))
	{
	  error("aggregate value used where an integer was expected");
	  return FALSE;
	}
    }
  else if (type_pointer(to))
    {
      if (!(type_integer(from) || type_pointer(from)))
	{
	  error("cannot convert to a pointer type");
	  return FALSE;
	}
    }
  else if (type_floating(to))
    {
      if (type_pointer(from))
	{
	  error("pointer value used where a floating point value was expected");
	  return FALSE;
	}
      else if (!type_arithmetic(from))
	{
	  error("aggregate value used where a float was expected");
	  return FALSE;
	}
    }
  else if (type_complex(to))
    {
      if (type_pointer(from))
	{
	  error("pointer value used where a complex was expected");
	  return FALSE;
	}
      else if (!type_arithmetic(from))
	{
	  error("aggregate value used where a complex was expected");
	  return FALSE;
	}
    }
  else
    {
      error("conversion to non-scalar type requested");
      return FALSE;
    }
  return TRUE;
}
Beispiel #7
0
void check_switch(expression e)
{
  if (e->type != error_type && !type_integer(e->type))
    error("switch quantity not an integer");
}