Remove vestiges of top down widening.

This commit is contained in:
Christoffer Lerno
2023-09-19 09:27:09 +02:00
committed by Christoffer Lerno
parent e91cb85a66
commit 9eef34049d
16 changed files with 266 additions and 341 deletions

View File

@@ -193,7 +193,7 @@ fn usz! Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv
is_neg = true; is_neg = true;
y = -y; y = -y;
} }
int pl = is_neg || self.flags.plus ? 1 : 0; isz pl = is_neg || self.flags.plus ? 1 : 0;
// Print inf/nan // Print inf/nan
if (!math::is_finite(y)) if (!math::is_finite(y))
{ {

View File

@@ -46,7 +46,7 @@ fn int main(int argc, char **argv)
byte_acc = 0; byte_acc = 0;
bit_num = 0; bit_num = 0;
} }
else if (x == w - 1) else if (x == (double)w - 1)
{ {
byte_acc <<= (8 - w % 8); byte_acc <<= (8 - w % 8);
putchar(byte_acc); putchar(byte_acc);

View File

@@ -6,7 +6,7 @@ double[] temparr;
fn double eval_A(int i, int j) fn double eval_A(int i, int j)
{ {
return 1.0 / ((i + j) * (i + j + 1) / 2 + i + 1); return 1.0 / (double)((i + j) * (i + j + 1) / 2 + i + 1);
} }
fn void eval_A_times_u(double[] u, double[] au, double[] x) fn void eval_A_times_u(double[] u, double[] au, double[] x)

View File

@@ -755,14 +755,12 @@ typedef struct
ExprId left; ExprId left;
ExprId right; ExprId right;
BinaryOp operator : 8; BinaryOp operator : 8;
bool widen : 1;
} ExprBinary; } ExprBinary;
typedef struct typedef struct
{ {
Expr* expr; Expr* expr;
UnaryOp operator : 8; UnaryOp operator : 8;
bool widen : 1;
} ExprUnary; } ExprUnary;
@@ -2186,7 +2184,7 @@ Expr *expr_new(ExprKind kind, SourceSpan start);
Expr *expr_new_const_int(SourceSpan span, Type *type, uint64_t v); Expr *expr_new_const_int(SourceSpan span, Type *type, uint64_t v);
Expr *expr_new_const_bool(SourceSpan span, Type *type, bool value); Expr *expr_new_const_bool(SourceSpan span, Type *type, bool value);
Expr *expr_new_const_typeid(SourceSpan span, Type *type); Expr *expr_new_const_typeid(SourceSpan span, Type *type);
bool expr_is_simple(Expr *expr); bool expr_is_simple(Expr *expr, bool to_float);
bool expr_is_pure(Expr *expr); bool expr_is_pure(Expr *expr);
bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind); bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind);
bool expr_is_compile_time(Expr *ast); bool expr_is_compile_time(Expr *ast);
@@ -2203,7 +2201,7 @@ bool expr_may_splat_as_vararg(Expr *expr, Type *variadic_base_type);
INLINE Expr *expr_new_expr(ExprKind kind, Expr *expr); INLINE Expr *expr_new_expr(ExprKind kind, Expr *expr);
INLINE bool expr_ok(Expr *expr); INLINE bool expr_ok(Expr *expr);
INLINE void expr_resolve_ident(Expr *expr, Decl *decl); INLINE void expr_resolve_ident(Expr *expr, Decl *decl);
INLINE bool exprid_is_simple(ExprId expr_id); INLINE bool exprid_is_simple(ExprId expr_id, bool to_float);
INLINE bool exprid_is_pure(ExprId expr_id); INLINE bool exprid_is_pure(ExprId expr_id);
INLINE Type *exprtype(ExprId expr_id); INLINE Type *exprtype(ExprId expr_id);
INLINE void expr_replace(Expr *expr, Expr *replacement); INLINE void expr_replace(Expr *expr, Expr *replacement);
@@ -3152,7 +3150,7 @@ INLINE void expr_replace(Expr *expr, Expr *replacement)
INLINE bool expr_ok(Expr *expr) { return expr == NULL || expr->expr_kind != EXPR_POISONED; } INLINE bool expr_ok(Expr *expr) { return expr == NULL || expr->expr_kind != EXPR_POISONED; }
INLINE bool exprid_is_simple(ExprId expr_id) { return expr_is_simple(exprptr(expr_id)); } INLINE bool exprid_is_simple(ExprId expr_id, bool to_float) { return expr_is_simple(exprptr(expr_id), to_float); }
INLINE void expr_resolve_ident(Expr *expr, Decl *decl) INLINE void expr_resolve_ident(Expr *expr, Decl *decl)
{ {

View File

@@ -768,7 +768,7 @@ bool expr_is_pure(Expr *expr)
} }
bool expr_is_simple(Expr *expr) bool expr_is_simple(Expr *expr, bool to_float)
{ {
RETRY: RETRY:
switch (expr->expr_kind) switch (expr->expr_kind)
@@ -777,7 +777,7 @@ bool expr_is_simple(Expr *expr)
expr = expr->inner_expr; expr = expr->inner_expr;
goto RETRY; goto RETRY;
case EXPR_TERNARY: case EXPR_TERNARY:
return expr_is_simple(exprptr(expr->ternary_expr.else_expr)) && expr_is_simple(exprptr(expr->ternary_expr.then_expr)); return exprid_is_simple(expr->ternary_expr.else_expr, to_float) && exprid_is_simple(expr->ternary_expr.then_expr, to_float);
case EXPR_RETHROW: case EXPR_RETHROW:
expr = expr->rethrow_expr.inner; expr = expr->rethrow_expr.inner;
goto RETRY; goto RETRY;
@@ -786,6 +786,12 @@ bool expr_is_simple(Expr *expr)
case EXPR_BINARY: case EXPR_BINARY:
switch (expr->binary_expr.operator) switch (expr->binary_expr.operator)
{ {
case BINARYOP_DIV:
if (to_float) return false;
FALLTHROUGH;
case BINARYOP_MOD:
case BINARYOP_ELSE:
return exprid_is_simple(expr->binary_expr.left, to_float) && exprid_is_simple(expr->binary_expr.right, to_float);
case BINARYOP_AND: case BINARYOP_AND:
case BINARYOP_OR: case BINARYOP_OR:
case BINARYOP_GT: case BINARYOP_GT:
@@ -806,6 +812,9 @@ bool expr_is_simple(Expr *expr)
case BINARYOP_SHL_ASSIGN: case BINARYOP_SHL_ASSIGN:
case BINARYOP_SUB_ASSIGN: case BINARYOP_SUB_ASSIGN:
return true; return true;
case BINARYOP_SHL:
case BINARYOP_SHR:
return to_float;
default: default:
return false; return false;
} }
@@ -813,8 +822,9 @@ bool expr_is_simple(Expr *expr)
case EXPR_UNARY: case EXPR_UNARY:
switch (expr->unary_expr.operator) switch (expr->unary_expr.operator)
{ {
case UNARYOP_NEG:
case UNARYOP_BITNEG: case UNARYOP_BITNEG:
return to_float;
case UNARYOP_NEG:
return false; return false;
default: default:
return true; return true;

View File

@@ -622,27 +622,6 @@ bool cast_to_index(SemaContext *context, Expr *index)
} }
} }
bool cast_widen_top_down(SemaContext *context, Expr *expr, Type *type)
{
Type *to = type_no_optional(type);
Type *from = type_no_optional(expr->type);
RETRY:
if (type_is_integer(from) && type_is_integer(to)) goto CONVERT_IF_BIGGER;
if (type_is_float(from) && type_is_float(to)) goto CONVERT_IF_BIGGER;
if (type_is_integer(from) && type_is_float(to)) goto CONVERT;
if (type_flat_is_vector(from) && type_flat_is_vector(to))
{
to = type_vector_type(to);
from = type_vector_type(from);
goto RETRY;
}
return true;
CONVERT_IF_BIGGER:
if (type_size(to) <= type_size(from)) return true;
CONVERT:
return cast_implicit(context, expr, type);
}
Type *cast_numeric_arithmetic_promotion(Type *type) Type *cast_numeric_arithmetic_promotion(Type *type)
{ {
if (!type) return NULL; if (!type) return NULL;
@@ -995,6 +974,21 @@ static bool rule_explicit_ok(CastContext *cc, bool is_explicit, bool silent)
} }
static bool rule_int_to_float(CastContext *cc, bool is_explicit, bool is_silent)
{
if (is_explicit) return true;
Expr *expr = cc->expr;
if (!expr_is_simple(expr, true))
{
if (is_silent) return false;
RETURN_SEMA_ERROR(expr, "This conversion requires an explicit cast to %s, because the widening of the expression may be done in more than one way.",
type_quoted_error_string(cc->to_type));
}
return true;
}
static bool rule_widen_narrow(CastContext *cc, bool is_explicit, bool is_silent) static bool rule_widen_narrow(CastContext *cc, bool is_explicit, bool is_silent)
{ {
if (is_explicit) return true; if (is_explicit) return true;
@@ -1006,11 +1000,11 @@ static bool rule_widen_narrow(CastContext *cc, bool is_explicit, bool is_silent)
// If widening, require simple. // If widening, require simple.
if (to_size > from_size) if (to_size > from_size)
{ {
if (expr_is_simple(cc->expr)) return true; if (expr_is_simple(cc->expr, type_is_float(cc->to))) return true;
if (is_silent) return false; if (is_silent) return false;
{ {
SEMA_ERROR(expr, "This conversion requires an explicit cast to %s, because the widening of the expression may be done in more than one way.", SEMA_ERROR(expr, "This conversion requires an explicit cast to %s, because the widening of the expression may be done in more than one way.",
type_quoted_error_string(cc->to_type)); type_quoted_error_string(cc->to_type));
} }
return false; return false;
} }
@@ -1023,7 +1017,7 @@ static bool rule_widen_narrow(CastContext *cc, bool is_explicit, bool is_silent)
if (cc->to_group != CONV_INT) if (cc->to_group != CONV_INT)
{ {
RETURN_SEMA_ERROR(expr, "The value '%s' is out of range for %s, so you need an explicit cast to truncate the value.", expr_const_to_error_string(&expr->const_expr), RETURN_SEMA_ERROR(expr, "The value '%s' is out of range for %s, so you need an explicit cast to truncate the value.", expr_const_to_error_string(&expr->const_expr),
type_quoted_error_string(cc->to_type)); type_quoted_error_string(cc->to_type));
} }
sema_error_const_int_out_of_range(expr, expr, cc->to_type); sema_error_const_int_out_of_range(expr, expr, cc->to_type);
} }
@@ -1042,7 +1036,7 @@ static bool rule_widen_narrow(CastContext *cc, bool is_explicit, bool is_silent)
if (type_is_integer(type_flatten(problem->type))) expr = problem; if (type_is_integer(type_flatten(problem->type))) expr = problem;
// Otherwise require a cast. // Otherwise require a cast.
SEMA_ERROR(expr, "%s cannot implicitly be converted to %s, but you may use a cast.", SEMA_ERROR(expr, "%s cannot implicitly be converted to %s, but you may use a cast.",
type_quoted_error_string(expr->type), type_quoted_error_string(cc->to_type)); type_quoted_error_string(expr->type), type_quoted_error_string(cc->to_type));
return false; return false;
} }
return true; return true;
@@ -1868,6 +1862,7 @@ static void cast_typeid_to_bool(Expr *expr, Type *to_type)
#define REXPL &rule_explicit_ok /* Is explicit */ #define REXPL &rule_explicit_ok /* Is explicit */
#define _NA__ &rule_not_applicable /* "Not applicable" - should not be seen. */ #define _NA__ &rule_not_applicable /* "Not applicable" - should not be seen. */
#define RIFIF &rule_widen_narrow /* Widen / narrow conversion of int/float */ #define RIFIF &rule_widen_narrow /* Widen / narrow conversion of int/float */
#define RINFL &rule_int_to_float /* Simple expressions, check sizes */
#define ROKOK &rule_all_ok /* Always works */ #define ROKOK &rule_all_ok /* Always works */
#define RINPT &rule_int_to_ptr /* Int -> ptr (explicit + size match) */ #define RINPT &rule_int_to_ptr /* Int -> ptr (explicit + size match) */
#define RPTIN &rule_ptr_to_int /* Ptr -> int (explicit + size match) */ #define RPTIN &rule_ptr_to_int /* Ptr -> int (explicit + size match) */
@@ -1897,7 +1892,7 @@ CastRule cast_rules[CONV_LAST + 1][CONV_LAST + 1] = {
{_NA__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // VOID (from) {_NA__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // VOID (from)
{ROKOK, _NA__, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, _NO__}, // WILDCARD {ROKOK, _NA__, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, _NO__}, // WILDCARD
{REXPL, _NO__, _NA__, REXPL, REXPL, _NO__, _NO__, ROKOK, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // BOOL {REXPL, _NO__, _NA__, REXPL, REXPL, _NO__, _NO__, ROKOK, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // BOOL
{REXPL, _NO__, REXPL, RIFIF, ROKOK, RINPT, _NO__, ROKOK, RINBS, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, RINEN, _NO__, _NO__, RINPT, RINPT, _NO__}, // INT {REXPL, _NO__, REXPL, RIFIF, RINFL, RINPT, _NO__, ROKOK, RINBS, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, RINEN, _NO__, _NO__, RINPT, RINPT, _NO__}, // INT
{REXPL, _NO__, REXPL, REXPL, RIFIF, _NO__, _NO__, ROKOK, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // FLOAT {REXPL, _NO__, REXPL, REXPL, RIFIF, _NO__, _NO__, ROKOK, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // FLOAT
{REXPL, _NO__, REXPL, RPTIN, _NO__, RPTPT, _NO__, ROKOK, _NO__, RXXDI, _NO__, _NO__, _NO__, ROKOK, _NO__, _NO__, _NO__, _NO__, ROKOK, RPTPT, RPTFE}, // PTR {REXPL, _NO__, REXPL, RPTIN, _NO__, RPTPT, _NO__, ROKOK, _NO__, RXXDI, _NO__, _NO__, _NO__, ROKOK, _NO__, _NO__, _NO__, _NO__, ROKOK, RPTPT, RPTFE}, // PTR
{REXPL, _NO__, REXPL, _NO__, _NO__, RSAPT, RSASA, RSAVA, _NO__, RXXDI, RSAVA, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, RSAPT, RSAFE}, // SARRAY {REXPL, _NO__, REXPL, _NO__, _NO__, RSAPT, RSASA, RSAVA, _NO__, RXXDI, RSAVA, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, RSAPT, RSAFE}, // SARRAY

View File

@@ -113,7 +113,7 @@ static Type *sema_subscript_find_indexable_type_recursively(Type **type, Expr **
// -- binary helper functions // -- binary helper functions
static void expr_binary_unify_failability(Expr *expr, Expr *left, Expr *right); static void expr_binary_unify_failability(Expr *expr, Expr *left, Expr *right);
static inline bool sema_binary_promote_top_down(SemaContext *context, Expr *binary, Expr *left, Expr *right);
static inline bool sema_binary_analyse_subexpr(SemaContext *context, Expr *binary, Expr *left, Expr *right); static inline bool sema_binary_analyse_subexpr(SemaContext *context, Expr *binary, Expr *left, Expr *right);
static inline bool sema_binary_analyse_arithmetic_subexpr(SemaContext *context, Expr *expr, const char *error, bool bool_and_bitstruct_is_allowed); static inline bool sema_binary_analyse_arithmetic_subexpr(SemaContext *context, Expr *expr, const char *error, bool bool_and_bitstruct_is_allowed);
static inline bool sema_binary_analyse_ct_identifier_lvalue(SemaContext *context, Expr *expr); static inline bool sema_binary_analyse_ct_identifier_lvalue(SemaContext *context, Expr *expr);
@@ -174,7 +174,7 @@ static inline bool sema_create_const_max(SemaContext *context, Expr *expr, Type
static inline bool sema_create_const_params(SemaContext *context, Expr *expr, Type *type); static inline bool sema_create_const_params(SemaContext *context, Expr *expr, Type *type);
static inline void sema_create_const_membersof(SemaContext *context, Expr *expr, Type *type, AlignSize alignment, static inline void sema_create_const_membersof(SemaContext *context, Expr *expr, Type *type, AlignSize alignment,
AlignSize offset); AlignSize offset);
void expr_insert_widening_type(Expr *expr, Type *infer_type);
static inline int64_t expr_get_index_max(Expr *expr); static inline int64_t expr_get_index_max(Expr *expr);
static inline bool expr_both_any_integer_or_integer_vector(Expr *left, Expr *right); static inline bool expr_both_any_integer_or_integer_vector(Expr *left, Expr *right);
static inline bool expr_both_any_integer_or_integer_bool_vector(Expr *left, Expr *right); static inline bool expr_both_any_integer_or_integer_bool_vector(Expr *left, Expr *right);
@@ -1023,13 +1023,6 @@ static inline bool sema_expr_analyse_hash_identifier(SemaContext *context, Expr
} }
static inline bool sema_binary_promote_top_down(SemaContext *context, Expr *binary, Expr *left, Expr *right)
{
if (!binary->binary_expr.widen) return true;
Type *to = binary->type;
return cast_widen_top_down(context, left, to) && cast_widen_top_down(context, right, to);
}
static inline bool sema_binary_analyse_subexpr(SemaContext *context, Expr *binary, Expr *left, Expr *right) static inline bool sema_binary_analyse_subexpr(SemaContext *context, Expr *binary, Expr *left, Expr *right)
{ {
// Special handling of f = FOO_BAR // Special handling of f = FOO_BAR
@@ -1079,7 +1072,7 @@ static inline bool sema_binary_analyse_arithmetic_subexpr(SemaContext *context,
// 1. Analyse both sides. // 1. Analyse both sides.
if (!sema_binary_analyse_subexpr(context, expr, left, right)) return false; if (!sema_binary_analyse_subexpr(context, expr, left, right)) return false;
if (!sema_binary_promote_top_down(context, expr, left, right)) return false; //if (!sema_binary_promote_top_down(context, expr, left, right)) return false;
Type *left_type = type_no_optional(left->type)->canonical; Type *left_type = type_no_optional(left->type)->canonical;
Type *right_type = type_no_optional(right->type)->canonical; Type *right_type = type_no_optional(right->type)->canonical;
@@ -5090,8 +5083,6 @@ static bool sema_expr_analyse_sub(SemaContext *context, Expr *expr, Expr *left,
return sema_expr_analyse_enum_add_sub(context, expr, left, right); return sema_expr_analyse_enum_add_sub(context, expr, left, right);
} }
if (!sema_binary_promote_top_down(context, expr, left, right)) return false;
left_type = type_no_optional(left->type)->canonical; left_type = type_no_optional(left->type)->canonical;
right_type = type_no_optional(right->type)->canonical; right_type = type_no_optional(right->type)->canonical;
@@ -5270,8 +5261,6 @@ static bool sema_expr_analyse_add(SemaContext *context, Expr *expr, Expr *left,
return sema_expr_analyse_enum_add_sub(context, expr, left, right); return sema_expr_analyse_enum_add_sub(context, expr, left, right);
} }
if (!sema_binary_promote_top_down(context, expr, left, right)) return false;
left_type = type_no_optional(left->type)->canonical; left_type = type_no_optional(left->type)->canonical;
right_type = type_no_optional(right->type)->canonical; right_type = type_no_optional(right->type)->canonical;
@@ -5513,8 +5502,6 @@ static bool sema_expr_analyse_shift(SemaContext *context, Expr *expr, Expr *left
return sema_type_error_on_binop(expr); return sema_type_error_on_binop(expr);
} }
if (expr->binary_expr.widen && !cast_widen_top_down(context, left, expr->type)) return false;
// 3. Promote lhs using the usual numeric promotion. // 3. Promote lhs using the usual numeric promotion.
if (!cast_implicit(context, left, cast_numeric_arithmetic_promotion(type_no_optional(left->type)))) return false; if (!cast_implicit(context, left, cast_numeric_arithmetic_promotion(type_no_optional(left->type)))) return false;
@@ -6011,7 +5998,6 @@ static inline bool sema_expr_analyse_neg_plus(SemaContext *context, Expr *expr)
Expr *inner = expr->unary_expr.expr; Expr *inner = expr->unary_expr.expr;
bool is_plus = expr->unary_expr.operator == UNARYOP_PLUS; bool is_plus = expr->unary_expr.operator == UNARYOP_PLUS;
if (!sema_analyse_expr(context, inner)) return false; if (!sema_analyse_expr(context, inner)) return false;
if (expr->unary_expr.widen && !cast_widen_top_down(context, inner, expr->type)) return false;
// 2. Check if it's possible to negate this (i.e. is it an int, float or vector) // 2. Check if it's possible to negate this (i.e. is it an int, float or vector)
Type *no_fail = type_no_optional(inner->type); Type *no_fail = type_no_optional(inner->type);
@@ -6069,8 +6055,6 @@ static inline bool sema_expr_analyse_bit_not(SemaContext *context, Expr *expr)
Expr *inner = expr->unary_expr.expr; Expr *inner = expr->unary_expr.expr;
if (!sema_analyse_expr(context, inner)) return false; if (!sema_analyse_expr(context, inner)) return false;
if (expr->unary_expr.widen && !cast_widen_top_down(context, inner, expr->type)) return false;
// 2. Check that it's a vector, bool // 2. Check that it's a vector, bool
Type *canonical = type_no_optional(inner->type)->canonical; Type *canonical = type_no_optional(inner->type)->canonical;
Type *flat = type_flatten(canonical); Type *flat = type_flatten(canonical);
@@ -6319,8 +6303,6 @@ static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr)
if (!sema_analyse_expr(context, lhs)) return false; if (!sema_analyse_expr(context, lhs)) return false;
} }
if (expr->binary_expr.widen && !cast_widen_top_down(context, lhs, expr->type)) return false;
Type *type = lhs->type; Type *type = lhs->type;
if (!type_is_optional(type)) if (!type_is_optional(type))
{ {
@@ -6335,7 +6317,6 @@ static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr)
// First we analyse the "else" and try to implictly cast. // First we analyse the "else" and try to implictly cast.
if (!sema_analyse_expr(context, rhs)) return false; if (!sema_analyse_expr(context, rhs)) return false;
if (expr->binary_expr.widen && !cast_widen_top_down(context, rhs, expr->type)) return false;
if (lhs->expr_kind == EXPR_OPTIONAL) if (lhs->expr_kind == EXPR_OPTIONAL)
{ {
@@ -8350,58 +8331,6 @@ RETRY:
UNREACHABLE UNREACHABLE
} }
void expr_insert_widening_type(Expr *expr, Type *infer_type)
{
if (!infer_type) return;
switch (expr->expr_kind)
{
case EXPR_BINARY:
switch (expr->binary_expr.operator)
{
case BINARYOP_MULT:
case BINARYOP_SUB:
case BINARYOP_ADD:
case BINARYOP_DIV:
case BINARYOP_MOD:
case BINARYOP_SHR:
case BINARYOP_SHL:
case BINARYOP_BIT_OR:
case BINARYOP_BIT_XOR:
case BINARYOP_BIT_AND:
case BINARYOP_ELSE:
if (!expr_is_simple(exprptr(expr->binary_expr.left)) || !expr_is_simple(exprptr(expr->binary_expr.right))) return;
expr->type = infer_type;
expr->binary_expr.widen = true;
return;
default:
return;
}
case EXPR_GROUP:
expr_insert_widening_type(expr->inner_expr, infer_type);
return;
case EXPR_TERNARY:
if (!exprid_is_simple(expr->ternary_expr.else_expr)) return;
if (expr->ternary_expr.then_expr && !exprid_is_simple(expr->ternary_expr.else_expr)) return;
expr->type = infer_type;
expr->ternary_expr.widen = true;
return;
case EXPR_UNARY:
switch (expr->unary_expr.operator)
{
case UNARYOP_NEG:
case UNARYOP_BITNEG:
if (!expr_is_simple(expr->unary_expr.expr)) return;
expr->type = infer_type;
expr->unary_expr.widen = true;
return;
default:
return;
}
default:
return;
}
UNREACHABLE
}
bool sema_analyse_inferred_expr(SemaContext *context, Type *infer_type, Expr *expr) bool sema_analyse_inferred_expr(SemaContext *context, Type *infer_type, Expr *expr)
{ {
infer_type = type_no_optional(infer_type); infer_type = type_no_optional(infer_type);
@@ -8436,7 +8365,6 @@ bool sema_analyse_inferred_expr(SemaContext *context, Type *infer_type, Expr *ex
if (!sema_expr_analyse_lambda(context, infer_type, expr)) return expr_poison(expr); if (!sema_expr_analyse_lambda(context, infer_type, expr)) return expr_poison(expr);
break; break;
default: default:
expr_insert_widening_type(expr, infer_type);
if (!sema_analyse_expr_dispatch(context, expr)) return expr_poison(expr); if (!sema_analyse_expr_dispatch(context, expr)) return expr_poison(expr);
break; break;
} }

View File

@@ -80,7 +80,7 @@ bool sema_bit_assignment_check(Expr *right, Decl *member);
int sema_check_comp_time_bool(SemaContext *context, Expr *expr); int sema_check_comp_time_bool(SemaContext *context, Expr *expr);
bool sema_expr_check_assign(SemaContext *c, Expr *expr); bool sema_expr_check_assign(SemaContext *c, Expr *expr);
bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, CallABI abi, Signature *signature, bool is_real_function); bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, CallABI abi, Signature *signature, bool is_real_function);
bool cast_widen_top_down(SemaContext *context, Expr *expr, Type *type);
MemberIndex sema_len_from_const(Expr *expr); MemberIndex sema_len_from_const(Expr *expr);
void cast_promote_vararg(Expr *arg); void cast_promote_vararg(Expr *arg);

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.651" #define COMPILER_VERSION "0.4.652"

View File

@@ -7,7 +7,7 @@ fn void main()
int x = 222; int x = 222;
int y = 223; int y = 223;
long z = 0; long z = 0;
z = x + y; z = (long)x + y;
z *= x; z *= x;
int g = 0; int g = 0;
int* gp = &g; int* gp = &g;

View File

@@ -2,17 +2,17 @@ fn void test()
{ {
int x; int x;
int y; int y;
long z = x * y; long z = x * (long)y;
z = x * y + z; // #error: 'long' z = x * y + z; // #error: 'long'
z = x * y + x; // #error: 'long' z = x * y + x; // #error: 'long'
z = x / y; z = x / y;
z = x + y; z = (long)x + y;
z = x - y; z = (long)x - y;
z = x % y; z = x % y;
z = x / y + z; // #error: 'long' z = x / y + z;
z = x + y + z; // #error: 'long' z = x + y + z; // #error: 'long'
z = x - y + z; // #error: 'long' z = x - y + z; // #error: 'long'
z = x % y + z; // #error: 'long' z = x % y + z;
z = x / y + x; // #error: 'long' z = x / y + x; // #error: 'long'
z = x + y + x; // #error: 'long' z = x + y + x; // #error: 'long'
z = x - y + x; // #error: 'long' z = x - y + x; // #error: 'long'

View File

@@ -2,15 +2,15 @@ fn void test()
{ {
int x; int x;
int y; int y;
long z = x * y; long z = (long)x * y;
z = x / y; z = x / y;
z = x + y; z = (long)x + y;
z = x - y; z = (long)x - y;
z = x % y; z = x % y;
z = x << y; z = (long)x << y;
z = x >> y; z = (long)x >> y;
z = ~x; z = (long)~x;
z = -x; z = (long)-x;
int! w; int! w;
z = w ?? 1; z = w ?? 1;
} }
@@ -33,70 +33,64 @@ entry:
%mul = mul i64 %sext, %sext1 %mul = mul i64 %sext, %sext1
store i64 %mul, ptr %z, align 8 store i64 %mul, ptr %z, align 8
%2 = load i32, ptr %x, align 4 %2 = load i32, ptr %x, align 4
%sext2 = sext i32 %2 to i64
%3 = load i32, ptr %y, align 4 %3 = load i32, ptr %y, align 4
%sext3 = sext i32 %3 to i64 %sdiv = sdiv i32 %2, %3
%sdiv = sdiv i64 %sext2, %sext3 %sext2 = sext i32 %sdiv to i64
store i64 %sdiv, ptr %z, align 8 store i64 %sext2, ptr %z, align 8
%4 = load i32, ptr %x, align 4 %4 = load i32, ptr %x, align 4
%sext4 = sext i32 %4 to i64 %sext3 = sext i32 %4 to i64
%5 = load i32, ptr %y, align 4 %5 = load i32, ptr %y, align 4
%sext5 = sext i32 %5 to i64 %sext4 = sext i32 %5 to i64
%add = add i64 %sext4, %sext5 %add = add i64 %sext3, %sext4
store i64 %add, ptr %z, align 8 store i64 %add, ptr %z, align 8
%6 = load i32, ptr %x, align 4 %6 = load i32, ptr %x, align 4
%sext6 = sext i32 %6 to i64 %sext5 = sext i32 %6 to i64
%7 = load i32, ptr %y, align 4 %7 = load i32, ptr %y, align 4
%sext7 = sext i32 %7 to i64 %sext6 = sext i32 %7 to i64
%sub = sub i64 %sext6, %sext7 %sub = sub i64 %sext5, %sext6
store i64 %sub, ptr %z, align 8 store i64 %sub, ptr %z, align 8
%8 = load i32, ptr %x, align 4 %8 = load i32, ptr %x, align 4
%sext8 = sext i32 %8 to i64
%9 = load i32, ptr %y, align 4 %9 = load i32, ptr %y, align 4
%sext9 = sext i32 %9 to i64 %smod = srem i32 %8, %9
%smod = srem i64 %sext8, %sext9 %sext7 = sext i32 %smod to i64
store i64 %smod, ptr %z, align 8 store i64 %sext7, ptr %z, align 8
%10 = load i32, ptr %x, align 4 %10 = load i32, ptr %x, align 4
%sext10 = sext i32 %10 to i64 %sext8 = sext i32 %10 to i64
%11 = load i32, ptr %y, align 4 %11 = load i32, ptr %y, align 4
%zext = zext i32 %11 to i64 %zext = zext i32 %11 to i64
%shl = shl i64 %sext10, %zext %shl = shl i64 %sext8, %zext
%12 = freeze i64 %shl %12 = freeze i64 %shl
store i64 %12, ptr %z, align 8 store i64 %12, ptr %z, align 8
%13 = load i32, ptr %x, align 4 %13 = load i32, ptr %x, align 4
%sext11 = sext i32 %13 to i64 %sext9 = sext i32 %13 to i64
%14 = load i32, ptr %y, align 4 %14 = load i32, ptr %y, align 4
%zext12 = zext i32 %14 to i64 %zext10 = zext i32 %14 to i64
%ashr = ashr i64 %sext11, %zext12 %ashr = ashr i64 %sext9, %zext10
%15 = freeze i64 %ashr %15 = freeze i64 %ashr
store i64 %15, ptr %z, align 8 store i64 %15, ptr %z, align 8
%16 = load i32, ptr %x, align 4 %16 = load i32, ptr %x, align 4
%sext13 = sext i32 %16 to i64 %bnot = xor i32 %16, -1
%bnot = xor i64 %sext13, -1 %sext11 = sext i32 %bnot to i64
store i64 %bnot, ptr %z, align 8 store i64 %sext11, ptr %z, align 8
%17 = load i32, ptr %x, align 4 %17 = load i32, ptr %x, align 4
%sext14 = sext i32 %17 to i64
%18 = load i32, ptr %x, align 4 %18 = load i32, ptr %x, align 4
%sext15 = sext i32 %18 to i64 %neg = sub i32 0, %18
%neg = sub i64 0, %sext15 %sext12 = sext i32 %neg to i64
store i64 %neg, ptr %z, align 8 store i64 %sext12, ptr %z, align 8
store i64 0, ptr %w.f, align 8 store i64 0, ptr %w.f, align 8
store i32 0, ptr %w, align 4 store i32 0, ptr %w, align 4
%optval = load i64, ptr %w.f, align 8 %optval = load i64, ptr %w.f, align 8
%not_err = icmp eq i64 %optval, 0 %not_err = icmp eq i64 %optval, 0
%19 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) %19 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %19, label %after_check, label %else_block br i1 %19, label %after_check, label %else_block
after_check: ; preds = %entry after_check: ; preds = %entry
%20 = load i32, ptr %w, align 4 %20 = load i32, ptr %w, align 4
%sext16 = sext i32 %20 to i64
br label %phi_block br label %phi_block
else_block: ; preds = %entry else_block: ; preds = %entry
br label %phi_block br label %phi_block
phi_block: ; preds = %else_block, %after_check phi_block: ; preds = %else_block, %after_check
%val = phi i64 [ %sext16, %after_check ], [ 1, %else_block ] %val = phi i32 [ %20, %after_check ], [ 1, %else_block ]
store i64 %val, ptr %z, align 8 %sext13 = sext i32 %val to i64
store i64 %sext13, ptr %z, align 8
ret void ret void
} }

View File

@@ -5,10 +5,10 @@ extern fn int! testError();
fn void test() fn void test()
{ {
double x = (testError() + testError()) ?? 100; double x = ((double)testError() + testError()) ?? 100;
double y = (1 << testError()) ?? 100; double y = (1 << testError()) ?? 100;
double z = testError() >> 1 ?? 100; double z = testError() >> 1 ?? 100;
double w = testError() * testError() ?? 100; double w = (double)testError() * testError() ?? 100;
} }
/* #expect: else_checks.ll /* #expect: else_checks.ll
@@ -23,12 +23,12 @@ entry:
%retparam = alloca i32, align 4 %retparam = alloca i32, align 4
%retparam1 = alloca i32, align 4 %retparam1 = alloca i32, align 4
%y = alloca double, align 8 %y = alloca double, align 8
%retparam4 = alloca i32, align 4 %retparam5 = alloca i32, align 4
%z = alloca double, align 8 %z = alloca double, align 8
%retparam11 = alloca i32, align 4 %retparam12 = alloca i32, align 4
%w = alloca double, align 8 %w = alloca double, align 8
%retparam18 = alloca i32, align 4 %retparam19 = alloca i32, align 4
%retparam21 = alloca i32, align 4 %retparam23 = alloca i32, align 4
%0 = call i64 @testError(ptr %retparam) %0 = call i64 @testError(ptr %retparam)
%not_err = icmp eq i64 %0, 0 %not_err = icmp eq i64 %0, 0
%1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) %1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
@@ -36,6 +36,7 @@ entry:
after_check: ; preds = %entry after_check: ; preds = %entry
%2 = load i32, ptr %retparam, align 4 %2 = load i32, ptr %retparam, align 4
%sifp = sitofp i32 %2 to double
%3 = call i64 @testError(ptr %retparam1) %3 = call i64 @testError(ptr %retparam1)
%not_err2 = icmp eq i64 %3, 0 %not_err2 = icmp eq i64 %3, 0
%4 = call i1 @llvm.expect.i1(i1 %not_err2, i1 true) %4 = call i1 @llvm.expect.i1(i1 %not_err2, i1 true)
@@ -43,75 +44,76 @@ after_check: ; preds = %entry
after_check3: ; preds = %after_check after_check3: ; preds = %after_check
%5 = load i32, ptr %retparam1, align 4 %5 = load i32, ptr %retparam1, align 4
%add = add i32 %2, %5 %sifp4 = sitofp i32 %5 to double
%fadd = fadd double %sifp, %sifp4
br label %phi_block br label %phi_block
else_block: ; preds = %after_check, %entry else_block: ; preds = %after_check, %entry
br label %phi_block br label %phi_block
phi_block: ; preds = %else_block, %after_check3 phi_block: ; preds = %else_block, %after_check3
%val = phi i32 [ %add, %after_check3 ], [ 100, %else_block ] %val = phi double [ %fadd, %after_check3 ], [ 1.000000e+02, %else_block ]
%sifp = sitofp i32 %val to double store double %val, ptr %x, align 8
store double %sifp, ptr %x, align 8 %6 = call i64 @testError(ptr %retparam5)
%6 = call i64 @testError(ptr %retparam4) %not_err6 = icmp eq i64 %6, 0
%not_err5 = icmp eq i64 %6, 0 %7 = call i1 @llvm.expect.i1(i1 %not_err6, i1 true)
%7 = call i1 @llvm.expect.i1(i1 %not_err5, i1 true) br i1 %7, label %after_check7, label %else_block8
br i1 %7, label %after_check6, label %else_block7
after_check6: ; preds = %phi_block after_check7: ; preds = %phi_block
%8 = load i32, ptr %retparam4, align 4 %8 = load i32, ptr %retparam5, align 4
%shl = shl i32 1, %8 %shl = shl i32 1, %8
%9 = freeze i32 %shl %9 = freeze i32 %shl
br label %phi_block8 br label %phi_block9
else_block7: ; preds = %phi_block else_block8: ; preds = %phi_block
br label %phi_block8 br label %phi_block9
phi_block8: ; preds = %else_block7, %after_check6 phi_block9: ; preds = %else_block8, %after_check7
%val9 = phi i32 [ %9, %after_check6 ], [ 100, %else_block7 ] %val10 = phi i32 [ %9, %after_check7 ], [ 100, %else_block8 ]
%sifp10 = sitofp i32 %val9 to double %sifp11 = sitofp i32 %val10 to double
store double %sifp10, ptr %y, align 8 store double %sifp11, ptr %y, align 8
%10 = call i64 @testError(ptr %retparam11) %10 = call i64 @testError(ptr %retparam12)
%not_err12 = icmp eq i64 %10, 0 %not_err13 = icmp eq i64 %10, 0
%11 = call i1 @llvm.expect.i1(i1 %not_err12, i1 true) %11 = call i1 @llvm.expect.i1(i1 %not_err13, i1 true)
br i1 %11, label %after_check13, label %else_block14 br i1 %11, label %after_check14, label %else_block15
after_check13: ; preds = %phi_block8 after_check14: ; preds = %phi_block9
%12 = load i32, ptr %retparam11, align 4 %12 = load i32, ptr %retparam12, align 4
%ashr = ashr i32 %12, 1 %ashr = ashr i32 %12, 1
%13 = freeze i32 %ashr %13 = freeze i32 %ashr
br label %phi_block15 br label %phi_block16
else_block14: ; preds = %phi_block8 else_block15: ; preds = %phi_block9
br label %phi_block15 br label %phi_block16
phi_block15: ; preds = %else_block14, %after_check13 phi_block16: ; preds = %else_block15, %after_check14
%val16 = phi i32 [ %13, %after_check13 ], [ 100, %else_block14 ] %val17 = phi i32 [ %13, %after_check14 ], [ 100, %else_block15 ]
%sifp17 = sitofp i32 %val16 to double %sifp18 = sitofp i32 %val17 to double
store double %sifp17, ptr %z, align 8 store double %sifp18, ptr %z, align 8
%14 = call i64 @testError(ptr %retparam18) %14 = call i64 @testError(ptr %retparam19)
%not_err19 = icmp eq i64 %14, 0 %not_err20 = icmp eq i64 %14, 0
%15 = call i1 @llvm.expect.i1(i1 %not_err19, i1 true) %15 = call i1 @llvm.expect.i1(i1 %not_err20, i1 true)
br i1 %15, label %after_check20, label %else_block24 br i1 %15, label %after_check21, label %else_block27
after_check20: ; preds = %phi_block15 after_check21: ; preds = %phi_block16
%16 = load i32, ptr %retparam18, align 4 %16 = load i32, ptr %retparam19, align 4
%17 = call i64 @testError(ptr %retparam21) %sifp22 = sitofp i32 %16 to double
%not_err22 = icmp eq i64 %17, 0 %17 = call i64 @testError(ptr %retparam23)
%18 = call i1 @llvm.expect.i1(i1 %not_err22, i1 true) %not_err24 = icmp eq i64 %17, 0
br i1 %18, label %after_check23, label %else_block24 %18 = call i1 @llvm.expect.i1(i1 %not_err24, i1 true)
br i1 %18, label %after_check25, label %else_block27
after_check23: ; preds = %after_check20 after_check25: ; preds = %after_check21
%19 = load i32, ptr %retparam21, align 4 %19 = load i32, ptr %retparam23, align 4
%mul = mul i32 %16, %19 %sifp26 = sitofp i32 %19 to double
br label %phi_block25 %fmul = fmul double %sifp22, %sifp26
br label %phi_block28
else_block24: ; preds = %after_check20, %phi_block15 else_block27: ; preds = %after_check21, %phi_block16
br label %phi_block25 br label %phi_block28
phi_block25: ; preds = %else_block24, %after_check23 phi_block28: ; preds = %else_block27, %after_check25
%val26 = phi i32 [ %mul, %after_check23 ], [ 100, %else_block24 ] %val29 = phi double [ %fmul, %after_check25 ], [ 1.000000e+02, %else_block27 ]
%sifp27 = sitofp i32 %val26 to double store double %val29, ptr %w, align 8
store double %sifp27, ptr %w, align 8
ret void ret void
} }

View File

@@ -58,7 +58,7 @@ fn Doc! readDoc(char[] url)
if (contains(url, "title-missing")) return { dupe(Head { .title = null })! }; if (contains(url, "title-missing")) return { dupe(Head { .title = null })! };
if (contains(url, "title-empty")) return { dupe(Head { .title = dupe((char[])"")! })! }; if (contains(url, "title-empty")) return { dupe(Head { .title = dupe((char[])"")! })! };
// Not particularly elegant due to missing string functions. // Not particularly elegant due to missing string functions.
int len = libc::snprintf(null, 0, "Title of %.*s", (int)url.len, url.ptr); isz len = libc::snprintf(null, 0, "Title of %.*s", (int)url.len, url.ptr);
char* str = malloc(len + 1); char* str = malloc(len + 1);
if (!str) return ReadError.OUT_OF_MEMORY?; if (!str) return ReadError.OUT_OF_MEMORY?;
libc::snprintf(str, len + 1, "Title of %.*s", (int)url.len, url.ptr); libc::snprintf(str, len + 1, "Title of %.*s", (int)url.len, url.ptr);
@@ -301,7 +301,7 @@ entry:
%retparam57 = alloca ptr, align 8 %retparam57 = alloca ptr, align 8
%varargslots62 = alloca [1 x %any], align 16 %varargslots62 = alloca [1 x %any], align 16
%indirectarg64 = alloca %"any[]", align 8 %indirectarg64 = alloca %"any[]", align 8
%len = alloca i32, align 4 %len = alloca i64, align 8
%str = alloca ptr, align 8 %str = alloca ptr, align 8
%using72 = alloca ptr, align 8 %using72 = alloca ptr, align 8
%error_var73 = alloca i64, align 8 %error_var73 = alloca i64, align 8
@@ -310,29 +310,29 @@ entry:
%retparam77 = alloca ptr, align 8 %retparam77 = alloca ptr, align 8
%varargslots82 = alloca [1 x %any], align 16 %varargslots82 = alloca [1 x %any], align 16
%indirectarg84 = alloca %"any[]", align 8 %indirectarg84 = alloca %"any[]", align 8
%reterr92 = alloca i64, align 8 %reterr91 = alloca i64, align 8
%literal93 = alloca %Doc, align 8 %literal92 = alloca %Doc, align 8
%error_var94 = alloca i64, align 8 %error_var93 = alloca i64, align 8
%literal95 = alloca %Head, align 8 %literal94 = alloca %Head, align 8
%error_var96 = alloca i64, align 8 %error_var95 = alloca i64, align 8
%value99 = alloca %"char[]", align 8 %value97 = alloca %"char[]", align 8
%temp100 = alloca ptr, align 8 %temp98 = alloca ptr, align 8
%using99 = alloca ptr, align 8
%error_var100 = alloca i64, align 8
%using101 = alloca ptr, align 8 %using101 = alloca ptr, align 8
%error_var102 = alloca i64, align 8 %allocator103 = alloca ptr, align 8
%using103 = alloca ptr, align 8 %retparam105 = alloca ptr, align 8
%allocator105 = alloca ptr, align 8 %varargslots110 = alloca [1 x %any], align 16
%retparam107 = alloca ptr, align 8 %indirectarg112 = alloca %"any[]", align 8
%varargslots112 = alloca [1 x %any], align 16 %value119 = alloca %Head, align 8
%indirectarg114 = alloca %"any[]", align 8 %temp120 = alloca ptr, align 8
%value121 = alloca %Head, align 8 %using121 = alloca ptr, align 8
%temp122 = alloca ptr, align 8 %error_var122 = alloca i64, align 8
%using123 = alloca ptr, align 8 %using123 = alloca ptr, align 8
%error_var124 = alloca i64, align 8 %allocator125 = alloca ptr, align 8
%using125 = alloca ptr, align 8 %retparam127 = alloca ptr, align 8
%allocator127 = alloca ptr, align 8 %varargslots132 = alloca [1 x %any], align 16
%retparam129 = alloca ptr, align 8 %indirectarg134 = alloca %"any[]", align 8
%varargslots134 = alloca [1 x %any], align 16
%indirectarg136 = alloca %"any[]", align 8
store ptr %1, ptr %url, align 8 store ptr %1, ptr %url, align 8
%ptroffset = getelementptr inbounds i64, ptr %url, i64 1 %ptroffset = getelementptr inbounds i64, ptr %url, i64 1
store i64 %2, ptr %ptroffset, align 8 store i64 %2, ptr %ptroffset, align 8
@@ -570,17 +570,17 @@ if.exit71: ; preds = %if.exit18
%78 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0 %78 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%79 = load ptr, ptr %78, align 8 %79 = load ptr, ptr %78, align 8
%80 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @.str.7, i32 %trunc, ptr %79) %80 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @.str.7, i32 %trunc, ptr %79)
store i32 %80, ptr %len, align 4 %sext = sext i32 %80 to i64
store i64 %sext, ptr %len, align 8
%81 = load ptr, ptr @std.core.mem.thread_allocator, align 8 %81 = load ptr, ptr @std.core.mem.thread_allocator, align 8
store ptr %81, ptr %using72, align 8 store ptr %81, ptr %using72, align 8
%82 = load ptr, ptr %using72, align 8 %82 = load ptr, ptr %using72, align 8
store ptr %82, ptr %using74, align 8 store ptr %82, ptr %using74, align 8
%83 = load i32, ptr %len, align 4 %83 = load i64, ptr %len, align 8
%add = add i32 %83, 1 %add = add i64 %83, 1
%84 = load ptr, ptr %using74, align 8 %84 = load ptr, ptr %using74, align 8
store ptr %84, ptr %allocator75, align 8 store ptr %84, ptr %allocator75, align 8
%sext = sext i32 %add to i64 %add76 = add i64 %add, 0
%add76 = add i64 %sext, 0
%85 = load ptr, ptr %allocator75, align 8 %85 = load ptr, ptr %allocator75, align 8
%86 = getelementptr inbounds %Allocator, ptr %85, i32 0, i32 0 %86 = getelementptr inbounds %Allocator, ptr %85, i32 0, i32 0
%87 = load ptr, ptr %86, align 8 %87 = load ptr, ptr %86, align 8
@@ -620,142 +620,140 @@ if.then87: ; preds = %noerr_block85
if.exit88: ; preds = %noerr_block85 if.exit88: ; preds = %noerr_block85
%97 = load ptr, ptr %str, align 8 %97 = load ptr, ptr %str, align 8
%98 = load i32, ptr %len, align 4 %98 = load i64, ptr %len, align 8
%sext89 = sext i32 %98 to i64 %add89 = add i64 %98, 1
%add90 = add i64 %sext89, 1
%99 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1 %99 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 1
%100 = load i64, ptr %99, align 8 %100 = load i64, ptr %99, align 8
%trunc91 = trunc i64 %100 to i32 %trunc90 = trunc i64 %100 to i32
%101 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0 %101 = getelementptr inbounds %"char[]", ptr %url, i32 0, i32 0
%102 = load ptr, ptr %101, align 8 %102 = load ptr, ptr %101, align 8
%103 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %97, i64 %add90, ptr @.str.8, i32 %trunc91, ptr %102) %103 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %97, i64 %add89, ptr @.str.8, i32 %trunc90, ptr %102)
%104 = getelementptr inbounds %Doc, ptr %literal93, i32 0, i32 0 %104 = getelementptr inbounds %Doc, ptr %literal92, i32 0, i32 0
store ptr null, ptr %literal95, align 8 store ptr null, ptr %literal94, align 8
%105 = getelementptr inbounds %Head, ptr %literal95, i32 0, i32 0 %105 = getelementptr inbounds %Head, ptr %literal94, i32 0, i32 0
%106 = load ptr, ptr %str, align 8 %106 = load ptr, ptr %str, align 8
%107 = load i32, ptr %len, align 4 %107 = load i64, ptr %len, align 8
%sub = sub i32 %107, 1 %sub = sub i64 %107, 1
%sext97 = sext i32 %sub to i64 %108 = add i64 %sub, 1
%108 = add i64 %sext97, 1
%size = sub i64 %108, 0 %size = sub i64 %108, 0
%ptroffset98 = getelementptr inbounds i8, ptr %106, i64 0 %ptroffset96 = getelementptr inbounds i8, ptr %106, i64 0
%109 = insertvalue %"char[]" undef, ptr %ptroffset98, 0 %109 = insertvalue %"char[]" undef, ptr %ptroffset96, 0
%110 = insertvalue %"char[]" %109, i64 %size, 1 %110 = insertvalue %"char[]" %109, i64 %size, 1
store %"char[]" %110, ptr %value99, align 8 store %"char[]" %110, ptr %value97, align 8
%111 = load ptr, ptr @std.core.mem.thread_allocator, align 8 %111 = load ptr, ptr @std.core.mem.thread_allocator, align 8
store ptr %111, ptr %using101, align 8 store ptr %111, ptr %using99, align 8
%112 = load ptr, ptr %using101, align 8 %112 = load ptr, ptr %using99, align 8
store ptr %112, ptr %using103, align 8 store ptr %112, ptr %using101, align 8
%113 = load ptr, ptr %using103, align 8 %113 = load ptr, ptr %using101, align 8
store ptr %113, ptr %allocator105, align 8 store ptr %113, ptr %allocator103, align 8
%114 = load ptr, ptr %allocator105, align 8 %114 = load ptr, ptr %allocator103, align 8
%115 = getelementptr inbounds %Allocator, ptr %114, i32 0, i32 0 %115 = getelementptr inbounds %Allocator, ptr %114, i32 0, i32 0
%116 = load ptr, ptr %115, align 8 %116 = load ptr, ptr %115, align 8
%117 = load ptr, ptr %allocator105, align 8 %117 = load ptr, ptr %allocator103, align 8
%118 = call i64 %116(ptr %retparam107, ptr %117, i64 16, i64 0, i64 0, ptr null, i32 0) %118 = call i64 %116(ptr %retparam105, ptr %117, i64 16, i64 0, i64 0, ptr null, i32 0)
%not_err108 = icmp eq i64 %118, 0 %not_err106 = icmp eq i64 %118, 0
%119 = call i1 @llvm.expect.i1(i1 %not_err108, i1 true) %119 = call i1 @llvm.expect.i1(i1 %not_err106, i1 true)
br i1 %119, label %after_check110, label %assign_optional109 br i1 %119, label %after_check108, label %assign_optional107
assign_optional109: ; preds = %if.exit88 assign_optional107: ; preds = %if.exit88
store i64 %118, ptr %error_var102, align 8 store i64 %118, ptr %error_var100, align 8
br label %panic_block111 br label %panic_block109
after_check110: ; preds = %if.exit88 after_check108: ; preds = %if.exit88
%120 = load ptr, ptr %retparam107, align 8 %120 = load ptr, ptr %retparam105, align 8
br label %noerr_block115 br label %noerr_block113
panic_block111: ; preds = %assign_optional109 panic_block109: ; preds = %assign_optional107
%121 = insertvalue %any undef, ptr %error_var102, 0 %121 = insertvalue %any undef, ptr %error_var100, 0
%122 = insertvalue %any %121, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 %122 = insertvalue %any %121, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%123 = getelementptr inbounds [1 x %any], ptr %varargslots112, i64 0, i64 0 %123 = getelementptr inbounds [1 x %any], ptr %varargslots110, i64 0, i64 0
store %any %122, ptr %123, align 16 store %any %122, ptr %123, align 16
%124 = insertvalue %"any[]" undef, ptr %varargslots112, 0 %124 = insertvalue %"any[]" undef, ptr %varargslots110, 0
%"#temp#113" = insertvalue %"any[]" %124, i64 1, 1 %"#temp#111" = insertvalue %"any[]" %124, i64 1, 1
store %"any[]" %"#temp#113", ptr %indirectarg114, align 8 store %"any[]" %"#temp#111", ptr %indirectarg112, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 6, ptr @.func call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 6, ptr @.func
unreachable unreachable
noerr_block115: ; preds = %after_check110 noerr_block113: ; preds = %after_check108
store ptr %120, ptr %temp100, align 8 store ptr %120, ptr %temp98, align 8
%125 = load ptr, ptr %temp100, align 8 %125 = load ptr, ptr %temp98, align 8
%not116 = icmp eq ptr %125, null %not114 = icmp eq ptr %125, null
br i1 %not116, label %if.then117, label %if.exit118 br i1 %not114, label %if.then115, label %if.exit116
if.then117: ; preds = %noerr_block115 if.then115: ; preds = %noerr_block113
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var96, align 8 store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var95, align 8
br label %guard_block119 br label %guard_block117
if.exit118: ; preds = %noerr_block115 if.exit116: ; preds = %noerr_block113
%126 = load ptr, ptr %temp100, align 8 %126 = load ptr, ptr %temp98, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %126, ptr align 8 %value99, i32 16, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %126, ptr align 8 %value97, i32 16, i1 false)
br label %noerr_block120 br label %noerr_block118
guard_block119: ; preds = %if.then117 guard_block117: ; preds = %if.then115
%127 = load i64, ptr %error_var96, align 8 %127 = load i64, ptr %error_var95, align 8
ret i64 %127 ret i64 %127
noerr_block120: ; preds = %if.exit118 noerr_block118: ; preds = %if.exit116
%128 = load ptr, ptr %temp100, align 8 %128 = load ptr, ptr %temp98, align 8
store ptr %128, ptr %105, align 8 store ptr %128, ptr %105, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value121, ptr align 8 %literal95, i32 8, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value119, ptr align 8 %literal94, i32 8, i1 false)
%129 = load ptr, ptr @std.core.mem.thread_allocator, align 8 %129 = load ptr, ptr @std.core.mem.thread_allocator, align 8
store ptr %129, ptr %using123, align 8 store ptr %129, ptr %using121, align 8
%130 = load ptr, ptr %using123, align 8 %130 = load ptr, ptr %using121, align 8
store ptr %130, ptr %using125, align 8 store ptr %130, ptr %using123, align 8
%131 = load ptr, ptr %using125, align 8 %131 = load ptr, ptr %using123, align 8
store ptr %131, ptr %allocator127, align 8 store ptr %131, ptr %allocator125, align 8
%132 = load ptr, ptr %allocator127, align 8 %132 = load ptr, ptr %allocator125, align 8
%133 = getelementptr inbounds %Allocator, ptr %132, i32 0, i32 0 %133 = getelementptr inbounds %Allocator, ptr %132, i32 0, i32 0
%134 = load ptr, ptr %133, align 8 %134 = load ptr, ptr %133, align 8
%135 = load ptr, ptr %allocator127, align 8 %135 = load ptr, ptr %allocator125, align 8
%136 = call i64 %134(ptr %retparam129, ptr %135, i64 8, i64 0, i64 0, ptr null, i32 0) %136 = call i64 %134(ptr %retparam127, ptr %135, i64 8, i64 0, i64 0, ptr null, i32 0)
%not_err130 = icmp eq i64 %136, 0 %not_err128 = icmp eq i64 %136, 0
%137 = call i1 @llvm.expect.i1(i1 %not_err130, i1 true) %137 = call i1 @llvm.expect.i1(i1 %not_err128, i1 true)
br i1 %137, label %after_check132, label %assign_optional131 br i1 %137, label %after_check130, label %assign_optional129
assign_optional131: ; preds = %noerr_block120 assign_optional129: ; preds = %noerr_block118
store i64 %136, ptr %error_var124, align 8 store i64 %136, ptr %error_var122, align 8
br label %panic_block133 br label %panic_block131
after_check132: ; preds = %noerr_block120 after_check130: ; preds = %noerr_block118
%138 = load ptr, ptr %retparam129, align 8 %138 = load ptr, ptr %retparam127, align 8
br label %noerr_block137 br label %noerr_block135
panic_block133: ; preds = %assign_optional131 panic_block131: ; preds = %assign_optional129
%139 = insertvalue %any undef, ptr %error_var124, 0 %139 = insertvalue %any undef, ptr %error_var122, 0
%140 = insertvalue %any %139, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 %140 = insertvalue %any %139, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%141 = getelementptr inbounds [1 x %any], ptr %varargslots134, i64 0, i64 0 %141 = getelementptr inbounds [1 x %any], ptr %varargslots132, i64 0, i64 0
store %any %140, ptr %141, align 16 store %any %140, ptr %141, align 16
%142 = insertvalue %"any[]" undef, ptr %varargslots134, 0 %142 = insertvalue %"any[]" undef, ptr %varargslots132, 0
%"#temp#135" = insertvalue %"any[]" %142, i64 1, 1 %"#temp#133" = insertvalue %"any[]" %142, i64 1, 1
store %"any[]" %"#temp#135", ptr %indirectarg136, align 8 store %"any[]" %"#temp#133", ptr %indirectarg134, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 6, ptr @.func, i64 7 call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 6, ptr @.func, i64 7
unreachable unreachable
noerr_block137: ; preds = %after_check132 noerr_block135: ; preds = %after_check130
store ptr %138, ptr %temp122, align 8 store ptr %138, ptr %temp120, align 8
%143 = load ptr, ptr %temp122, align 8 %143 = load ptr, ptr %temp120, align 8
%not138 = icmp eq ptr %143, null %not136 = icmp eq ptr %143, null
br i1 %not138, label %if.then139, label %if.exit140 br i1 %not136, label %if.then137, label %if.exit138
if.then139: ; preds = %noerr_block137 if.then137: ; preds = %noerr_block135
store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var94, align 8 store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var93, align 8
br label %guard_block141 br label %guard_block139
if.exit140: ; preds = %noerr_block137 if.exit138: ; preds = %noerr_block135
%144 = load ptr, ptr %temp122, align 8 %144 = load ptr, ptr %temp120, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %144, ptr align 8 %value121, i32 8, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %144, ptr align 8 %value119, i32 8, i1 false)
br label %noerr_block142 br label %noerr_block140
guard_block141: ; preds = %if.then139 guard_block139: ; preds = %if.then137
%145 = load i64, ptr %error_var94, align 8 %145 = load i64, ptr %error_var93, align 8
ret i64 %145 ret i64 %145
noerr_block142: ; preds = %if.exit140 noerr_block140: ; preds = %if.exit138
%146 = load ptr, ptr %temp122, align 8 %146 = load ptr, ptr %temp120, align 8
store ptr %146, ptr %104, align 8 store ptr %146, ptr %104, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal93, i32 8, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal92, i32 8, i1 false)
ret i64 0 ret i64 0
} }

View File

@@ -73,8 +73,8 @@ fn int main(int c, char** v)
GameBoard board; GameBoard board;
board.w = w; board.w = w;
board.h = h; board.h = h;
board.world = malloc(h * w); board.world = malloc((isz)h * w);
board.temp = malloc(h * w); board.temp = malloc((isz)h * w);
for (int i = h * w - 1; i >= 0; i--) for (int i = h * w - 1; i >= 0; i--)
{ {

View File

@@ -3,7 +3,7 @@ module foo;
fn float[20] get() fn float[20] get()
{ {
float[20] y; float[20] y;
for (int i = 0; i < 20; i++) y[i] = i * i + 1; for (int i = 0; i < 20; i++) y[i] = (float)i * i + 1;
return y; return y;
} }
fn void main() fn void main()