mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Scalar -> vector not implicit in call or assign.
This commit is contained in:
@@ -190,7 +190,7 @@ macro rotate_axis_angle(v, axis, angle) @private
|
||||
var w = axis * math::sin(angle);
|
||||
var wv = w.cross(v);
|
||||
var wwv = w.cross(wv);
|
||||
wv *= math::cos(angle) * 2;
|
||||
wv *= math::cos(($typeof(v))angle) * 2;
|
||||
wwv *= 2;
|
||||
|
||||
return v + wv + wwv;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
### Changes / improvements
|
||||
- Updated LLVM passes
|
||||
- Added `is_substruct` type property.
|
||||
- Scalar -> vector not implicit in call or assign.
|
||||
- Added `--vector-conv` to enable the old scalar->vector conversion behaviour.
|
||||
|
||||
### Fixes
|
||||
None
|
||||
|
||||
@@ -278,6 +278,12 @@ typedef enum
|
||||
WIN_CRT_STATIC = 2,
|
||||
} WinCrtLinking;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VECTOR_CONV_DEFAULT = 0,
|
||||
VECTOR_CONV_OLD = 1,
|
||||
} VectorConv;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RELOC_DEFAULT = -1,
|
||||
@@ -341,6 +347,7 @@ typedef struct BuildOptions_
|
||||
const char* linker_libs[MAX_LIB_DIRS];
|
||||
int linker_lib_count;
|
||||
const char* std_lib_dir;
|
||||
VectorConv vector_conv;
|
||||
struct {
|
||||
const char *sdk;
|
||||
const char *def;
|
||||
@@ -515,6 +522,7 @@ typedef struct
|
||||
TrustLevel trust_level;
|
||||
OptimizationSetting optsetting;
|
||||
OptimizationLevel optlevel;
|
||||
VectorConv vector_conv;
|
||||
MemoryEnvironment memory_environment;
|
||||
SizeOptimizationLevel optsize;
|
||||
SingleModule single_module;
|
||||
|
||||
@@ -27,6 +27,11 @@ static const char *wincrt_linking[3] = {
|
||||
[WIN_CRT_STATIC] = "static",
|
||||
};
|
||||
|
||||
static const char *vector_conv[2] = {
|
||||
[VECTOR_CONV_DEFAULT] = "default",
|
||||
[VECTOR_CONV_OLD] = "old",
|
||||
};
|
||||
|
||||
static const char *optsizes[3] = {
|
||||
[SIZE_OPTIMIZATION_NONE] = "none",
|
||||
[SIZE_OPTIMIZATION_SMALL] = "small",
|
||||
|
||||
@@ -182,6 +182,8 @@ static void usage(void)
|
||||
PRINTF("");
|
||||
PRINTF(" --linux-crt <dir> - Set the directory to use for finding crt1.o and related files.");
|
||||
PRINTF(" --linux-crtbegin <dir> - Set the directory to use for finding crtbegin.o and related files.");
|
||||
PRINTF("");
|
||||
PRINTF(" --vector-conv=<option> - Set vector conversion behaviour: default, old.");
|
||||
}
|
||||
|
||||
|
||||
@@ -951,6 +953,11 @@ static void parse_option(BuildOptions *options)
|
||||
options->win.def = next_arg();
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("vector-conv")))
|
||||
{
|
||||
options->vector_conv = (VectorConv)parse_multi_option(argopt, 2, vector_conv);
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("wincrt")))
|
||||
{
|
||||
options->win.crt_linking = (WinCrtLinking)parse_multi_option(argopt, 3, wincrt_linking);
|
||||
|
||||
@@ -320,6 +320,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
if (options->benchfn) target->benchfn = options->benchfn;
|
||||
target->benchmarking = options->benchmarking;
|
||||
target->testing = options->testing;
|
||||
target->vector_conv = options->vector_conv;
|
||||
if (options->macos.sysroot) target->macos.sysroot = options->macos.sysroot;
|
||||
if (options->win.sdk) target->win.sdk = options->win.sdk;
|
||||
if (options->macos.min_version) target->macos.min_version = options->macos.min_version;
|
||||
|
||||
@@ -2168,8 +2168,10 @@ INLINE AsmRegister *asm_reg_by_index(unsigned index);
|
||||
|
||||
AsmRegister *asm_reg_by_index(unsigned index);
|
||||
|
||||
bool cast_implicit_silent(SemaContext *context, Expr *expr, Type *to_type);
|
||||
bool cast_implicit(SemaContext *context, Expr *expr, Type *to_type);
|
||||
bool cast_implicit_silent(SemaContext *context, Expr *expr, Type *to_type, bool is_binary_conversion);
|
||||
|
||||
bool cast_implicit_binary(SemaContext *context, Expr *expr, Type *to_type, bool is_silent);
|
||||
bool cast_implicit(SemaContext *context, Expr *expr, Type *to_type, bool is_binary);
|
||||
bool cast_explicit_silent(SemaContext *context, Expr *expr, Type *to_type);
|
||||
bool cast_explicit(SemaContext *context, Expr *expr, Type *to_type);
|
||||
|
||||
@@ -2345,7 +2347,8 @@ void sema_erase_var(SemaContext *context, Decl *decl);
|
||||
void sema_erase_unwrapped(SemaContext *context, Decl *decl);
|
||||
bool sema_analyse_cond_expr(SemaContext *context, Expr *expr, CondResult *result);
|
||||
|
||||
bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allow_optional, bool *no_match_ref);
|
||||
bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allow_optional, bool *no_match_ref,
|
||||
bool as_binary);
|
||||
ArrayIndex sema_get_initializer_const_array_size(SemaContext *context, Expr *initializer, bool *may_be_array, bool *is_const_size);
|
||||
bool sema_analyse_expr(SemaContext *context, Expr *expr);
|
||||
bool sema_cast_const(Expr *expr);
|
||||
@@ -2359,7 +2362,9 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local);
|
||||
bool sema_analyse_ct_assert_stmt(SemaContext *context, Ast *statement);
|
||||
bool sema_analyse_ct_echo_stmt(SemaContext *context, Ast *statement);
|
||||
bool sema_analyse_statement(SemaContext *context, Ast *statement);
|
||||
bool sema_expr_analyse_assign_right_side(SemaContext *context, Expr *expr, Type *left_type, Expr *right, bool is_unwrapped_var);
|
||||
|
||||
bool sema_expr_analyse_assign_right_side(SemaContext *context, Expr *expr, Type *left_type, Expr *right,
|
||||
bool is_unwrapped_var, bool is_declaration);
|
||||
bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *expr);
|
||||
Expr **sema_expand_vasplat_exprs(SemaContext *c, Expr **exprs);
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ static bool sema_check_builtin_args_const(SemaContext *context, Expr **args, siz
|
||||
|
||||
static bool sema_check_alignment_expression(SemaContext *context, Expr *align)
|
||||
{
|
||||
if (!sema_analyse_expr_rhs(context, type_usz, align, false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, type_usz, align, false, NULL, false)) return false;
|
||||
if (!expr_is_const_int(align)
|
||||
|| !int_fits(align->const_expr.ixx, TYPE_U64)
|
||||
|| (!is_power_of_two(align->const_expr.ixx.i.low) && align->const_expr.ixx.i.low))
|
||||
@@ -187,7 +187,7 @@ static inline bool sema_expr_analyse_swizzle(SemaContext *context, Expr *expr, b
|
||||
for (unsigned i = first_mask_value; i < arg_count; i++)
|
||||
{
|
||||
Expr *mask_val = args[i];
|
||||
if (!sema_analyse_expr_rhs(context, type_int, mask_val, false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, type_int, mask_val, false, NULL, false)) return false;
|
||||
if (!expr_is_const_int(mask_val))
|
||||
{
|
||||
RETURN_SEMA_ERROR(mask_val, "The swizzle positions must be compile time constants.");
|
||||
@@ -226,7 +226,7 @@ static bool sema_expr_analyse_compare_exchange(SemaContext *context, Expr *expr)
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
Expr *arg = args[i];
|
||||
if (!sema_analyse_expr_rhs(context, type_is_void(pointee) ? NULL : pointee, arg, true, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, type_is_void(pointee) ? NULL : pointee, arg, true, NULL, false)) return false;
|
||||
if (type_is_void(pointee)) pointee = arg->type->canonical;
|
||||
if (!type_is_atomic(type_flatten(arg->type)))
|
||||
{
|
||||
@@ -237,14 +237,14 @@ static bool sema_expr_analyse_compare_exchange(SemaContext *context, Expr *expr)
|
||||
}
|
||||
for (int i = 3; i < 5; i++)
|
||||
{
|
||||
if (!sema_analyse_expr_rhs(context, type_bool, args[i], false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, type_bool, args[i], false, NULL, false)) return false;
|
||||
if (!sema_cast_const(args[i]))
|
||||
{
|
||||
RETURN_SEMA_ERROR(args[i], "Expected a constant boolean value.");}
|
||||
}
|
||||
for (int i = 5; i < 7; i++)
|
||||
{
|
||||
if (!sema_analyse_expr_rhs(context, type_char, args[i], false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, type_char, args[i], false, NULL, false)) return false;
|
||||
if (!is_valid_atomicity(context, args[i])) return false;
|
||||
}
|
||||
unsigned success = args[5]->const_expr.ixx.i.low;
|
||||
@@ -273,7 +273,7 @@ static bool sema_expr_analyse_syscall(SemaContext *context, Expr *expr)
|
||||
for (unsigned i = 0; i < arg_count; i++)
|
||||
{
|
||||
Expr *arg = args[i];
|
||||
if (!sema_analyse_expr_rhs(context, type_uptr, arg, true, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, type_uptr, arg, true, NULL, false)) return false;
|
||||
optional = optional || type_is_optional(arg->type);
|
||||
}
|
||||
switch (platform_target.arch)
|
||||
@@ -573,7 +573,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
case BUILTIN_EXPECT_WITH_PROBABILITY:
|
||||
assert(arg_count == 3);
|
||||
if (!sema_check_builtin_args(context, args, (BuiltinArg[]) {BA_BOOLINT, BA_BOOLINT}, 2)) return false;
|
||||
if (!cast_implicit(context, args[2], type_double))
|
||||
if (!cast_implicit(context, args[2], type_double, false))
|
||||
{
|
||||
RETURN_SEMA_ERROR(args[2], "Expected a 'double', but was %s.", type_quoted_error_string(args[2]->type));
|
||||
}
|
||||
@@ -618,19 +618,19 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
case BUILTIN_RETURNADDRESS:
|
||||
assert(arg_count);
|
||||
if (!sema_check_builtin_args(context, args, (BuiltinArg[]) {BA_INTEGER}, arg_count)) return false;
|
||||
if (!cast_implicit(context, args[0], type_int)) return false;
|
||||
if (!cast_implicit(context, args[0], type_int, false)) return false;
|
||||
if (!expr_is_const_int(args[0])) RETURN_SEMA_ERROR(args[0], "Expected a compile time constant integer.");
|
||||
rtype = type_voidptr;
|
||||
break;
|
||||
case BUILTIN_WASM_MEMORY_SIZE:
|
||||
assert(arg_count == 1);
|
||||
if (!cast_implicit(context, args[0], type_uint)) return false;
|
||||
if (!cast_implicit(context, args[0], type_uint, false)) return false;
|
||||
rtype = type_uptr;
|
||||
break;
|
||||
case BUILTIN_WASM_MEMORY_GROW:
|
||||
assert(arg_count == 2);
|
||||
if (!cast_implicit(context, args[0], type_uint)) return false;
|
||||
if (!cast_implicit(context, args[1], type_uptr)) return false;
|
||||
if (!cast_implicit(context, args[0], type_uint, false)) return false;
|
||||
if (!cast_implicit(context, args[1], type_uptr, false)) return false;
|
||||
rtype = type_iptr;
|
||||
break;
|
||||
case BUILTIN_PREFETCH:
|
||||
@@ -639,7 +639,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
for (unsigned i = 1; i < 3; i++)
|
||||
{
|
||||
if (!sema_cast_const(args[i])) RETURN_SEMA_ERROR(args[i], "A constant value is required.");
|
||||
if (!cast_implicit(context, args[i], type_int)) return false;
|
||||
if (!cast_implicit(context, args[i], type_int, false)) return false;
|
||||
}
|
||||
if (!expr_in_int_range(args[1], 0, 1))
|
||||
{
|
||||
@@ -651,7 +651,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
SEMA_ERROR(args[2], "Expected a value between 0 and 3.");
|
||||
return false;
|
||||
}
|
||||
if (!cast_implicit(context, args[0], type_voidptr)) return false;
|
||||
if (!cast_implicit(context, args[0], type_voidptr, false)) return false;
|
||||
rtype = type_void;
|
||||
break;
|
||||
case BUILTIN_POW:
|
||||
@@ -663,14 +663,14 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
case BUILTIN_POW_INT:
|
||||
assert(arg_count == 2);
|
||||
if (!sema_check_builtin_args(context, args, (BuiltinArg[]) {BA_FLOATLIKE, BA_INTLIKE}, 2)) return false;
|
||||
if (!cast_implicit(context, args[1], type_cint)) return false;
|
||||
if (!cast_implicit(context, args[1], type_cint, false)) return false;
|
||||
rtype = args[0]->type;
|
||||
break;
|
||||
case BUILTIN_REDUCE_FMUL:
|
||||
case BUILTIN_REDUCE_FADD:
|
||||
assert(arg_count == 2);
|
||||
if (!sema_check_builtin_args(context, args, (BuiltinArg[]) {BA_FLOATVEC, BA_FLOAT}, 2)) return false;
|
||||
if (!cast_implicit(context, args[1], args[0]->type->canonical->array.base)) return false;
|
||||
if (!cast_implicit(context, args[1], args[0]->type->canonical->array.base, false)) return false;
|
||||
{
|
||||
Expr *arg = args[0];
|
||||
args[0] = args[1];
|
||||
@@ -844,7 +844,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
if (!sema_check_alignment_expression(context, args[2])) return false;
|
||||
if (original != type_voidptr)
|
||||
{
|
||||
if (!cast_implicit(context, args[1], original->pointer)) return false;
|
||||
if (!cast_implicit(context, args[1], original->pointer, false)) return false;
|
||||
}
|
||||
rtype = args[1]->type;
|
||||
break;
|
||||
@@ -865,7 +865,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
Type *original = type_flatten(args[0]->type);
|
||||
if (original != type_voidptr)
|
||||
{
|
||||
if (!cast_implicit(context, args[1], original->pointer)) return false;
|
||||
if (!cast_implicit(context, args[1], original->pointer, false)) return false;
|
||||
}
|
||||
rtype = args[1]->type;
|
||||
break;
|
||||
@@ -888,7 +888,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
{
|
||||
RETURN_SEMA_ERROR(args[0], "Expected a pointer to an unsigned integer.");
|
||||
}
|
||||
if (!cast_implicit(context, args[1], original->pointer)) return false;
|
||||
if (!cast_implicit(context, args[1], original->pointer, false)) return false;
|
||||
}
|
||||
if (!sema_cast_const(args[2])) RETURN_SEMA_ERROR(args[2], "'is_volatile' must be a compile time constant.");
|
||||
if (!sema_cast_const(args[3])) RETURN_SEMA_ERROR(args[3], "Ordering must be a compile time constant.");
|
||||
@@ -912,7 +912,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
Type *original = type_flatten(args[0]->type);
|
||||
if (original != type_voidptr)
|
||||
{
|
||||
if (!cast_implicit(context, args[1], original->pointer)) return false;
|
||||
if (!cast_implicit(context, args[1], original->pointer, false)) return false;
|
||||
}
|
||||
if (!sema_cast_const(args[2])) RETURN_SEMA_ERROR(args[2], "'is_volatile' must be a compile time constant.");
|
||||
if (!sema_cast_const(args[3])) RETURN_SEMA_ERROR(args[3], "Ordering must be a compile time constant.");
|
||||
@@ -933,7 +933,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
Type *original = type_flatten(args[0]->type);
|
||||
if (original != type_voidptr)
|
||||
{
|
||||
if (!cast_implicit(context, args[1], original->pointer)) return false;
|
||||
if (!cast_implicit(context, args[1], original->pointer, false)) return false;
|
||||
}
|
||||
Type *val = type_flatten(args[1]->type);
|
||||
if (!type_is_atomic(val)) RETURN_SEMA_ERROR(args[1], "%s exceeds pointer size.", val);
|
||||
@@ -959,7 +959,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
Type *original = type_flatten(args[0]->type);
|
||||
if (original != type_voidptr)
|
||||
{
|
||||
if (!cast_implicit(context, args[1], original->pointer)) return false;
|
||||
if (!cast_implicit(context, args[1], original->pointer, false)) return false;
|
||||
}
|
||||
if (!sema_cast_const(args[2])) RETURN_SEMA_ERROR(args[2], "'is_volatile' must be a compile time constant.");
|
||||
if (!sema_cast_const(args[3])) RETURN_SEMA_ERROR(args[3], "Ordering must be a compile time constant.");
|
||||
@@ -981,7 +981,7 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
|
||||
Type *original = type_flatten(args[0]->type);
|
||||
if (original != type_voidptr)
|
||||
{
|
||||
if (!cast_implicit(context, args[1], original->pointer)) return false;
|
||||
if (!cast_implicit(context, args[1], original->pointer, false)) return false;
|
||||
}
|
||||
if (!sema_cast_const(args[2])) RETURN_SEMA_ERROR(args[2], "'is_volatile' must be a compile time constant.");
|
||||
if (!sema_cast_const(args[3])) RETURN_SEMA_ERROR(args[3], "Ordering must be a compile time constant.");
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool is_binary_conversion;
|
||||
SemaContext *context;
|
||||
Expr *expr;
|
||||
Type *from;
|
||||
@@ -29,7 +30,8 @@ static void vector_const_initializer_convert_to_type(SemaContext *context, Const
|
||||
static bool cast_is_allowed(CastContext *cc, bool is_explicit, bool is_silent);
|
||||
INLINE bool insert_runtime_cast_unless_const(Expr *expr, CastKind kind, Type *type);
|
||||
|
||||
static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool is_explicit, bool is_silent);
|
||||
static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool is_explicit, bool is_silent,
|
||||
bool is_binary_conversion);
|
||||
INLINE ConvGroup type_to_group(Type *type);
|
||||
INLINE void cast_context_set_from(CastContext *cc, Type *new_from);
|
||||
INLINE void cast_context_set_to(CastContext *cc, Type *new_to);
|
||||
@@ -43,17 +45,21 @@ extern CastRule cast_rules[CONV_LAST + 1][CONV_LAST + 1];
|
||||
/**
|
||||
* Try to make an implicit cast. Optional types are allowed.
|
||||
*/
|
||||
bool cast_implicit(SemaContext *context, Expr *expr, Type *to_type)
|
||||
bool cast_implicit(SemaContext *context, Expr *expr, Type *to_type, bool is_binary)
|
||||
{
|
||||
return cast_if_valid(context, expr, to_type, false, false);
|
||||
return cast_if_valid(context, expr, to_type, false, false, is_binary);
|
||||
}
|
||||
|
||||
bool cast_implicit_binary(SemaContext *context, Expr *expr, Type *to_type, bool is_silent)
|
||||
{
|
||||
return cast_if_valid(context, expr, to_type, false, is_silent, true);
|
||||
}
|
||||
/**
|
||||
* Try to make an explicit cast, Optional types are allowed.
|
||||
*/
|
||||
bool cast_explicit(SemaContext *context, Expr *expr, Type *to_type)
|
||||
{
|
||||
return cast_if_valid(context, expr, to_type, true, false);
|
||||
return cast_if_valid(context, expr, to_type, true, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,14 +67,14 @@ bool cast_explicit(SemaContext *context, Expr *expr, Type *to_type)
|
||||
*/
|
||||
bool cast_explicit_silent(SemaContext *context, Expr *expr, Type *to_type)
|
||||
{
|
||||
return cast_if_valid(context, expr, to_type, true, true);
|
||||
return cast_if_valid(context, expr, to_type, true, true, false);
|
||||
}
|
||||
/**
|
||||
* Silent implicit casting will attempt a cast, but will silently back out if it fails.
|
||||
*/
|
||||
bool cast_implicit_silent(SemaContext *context, Expr *expr, Type *to_type)
|
||||
bool cast_implicit_silent(SemaContext *context, Expr *expr, Type *to_type, bool is_binary_conversion)
|
||||
{
|
||||
return cast_if_valid(context, expr, to_type, false, true);
|
||||
return cast_if_valid(context, expr, to_type, false, true, is_binary_conversion);
|
||||
}
|
||||
|
||||
|
||||
@@ -270,7 +276,8 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type)
|
||||
}
|
||||
}
|
||||
|
||||
static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool is_explicit, bool is_silent)
|
||||
static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool is_explicit, bool is_silent,
|
||||
bool is_binary_conversion)
|
||||
{
|
||||
Type *from_type = expr->type;
|
||||
|
||||
@@ -300,6 +307,7 @@ static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool
|
||||
from_type = from_type->canonical;
|
||||
Type *to = to_type->canonical;
|
||||
CastContext cc = {
|
||||
.is_binary_conversion = is_binary_conversion,
|
||||
.from_group = type_to_group(from_type),
|
||||
.from = from_type,
|
||||
.to_group = type_to_group(to),
|
||||
@@ -1254,6 +1262,12 @@ static bool rule_vec_to_vec(CastContext *cc, bool is_explicit, bool is_silent)
|
||||
|
||||
static bool rule_expand_to_vec(CastContext *cc, bool is_explicit, bool is_silent)
|
||||
{
|
||||
if (!is_explicit && active_target.vector_conv == VECTOR_CONV_DEFAULT && !cc->is_binary_conversion)
|
||||
{
|
||||
if (is_silent) return false;
|
||||
bool explicit_works = rule_expand_to_vec(cc, true, true);
|
||||
return sema_cast_error(cc, explicit_works, false);
|
||||
}
|
||||
cast_context_set_to(cc, cc->to->array.base);
|
||||
return cast_is_allowed(cc, is_explicit, is_silent);
|
||||
}
|
||||
|
||||
@@ -1298,7 +1298,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
|
||||
Expr *expr = param->var.init_expr;
|
||||
if (expr_is_const(expr))
|
||||
{
|
||||
if (!sema_analyse_expr_rhs(context, param->type, expr, true, NULL)) return decl_poison(param);
|
||||
if (!sema_analyse_expr_rhs(context, param->type, expr, true, NULL, false)) return decl_poison(param);
|
||||
}
|
||||
}
|
||||
if (!sema_check_param_uniqueness_and_type(context, params, param, i, param_count)) return decl_poison(param);
|
||||
@@ -1540,7 +1540,7 @@ static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *era
|
||||
{
|
||||
Expr *arg = args[j];
|
||||
|
||||
if (!sema_analyse_expr_rhs(context, associated_values[j]->type, arg, false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, associated_values[j]->type, arg, false, NULL, false)) return false;
|
||||
if (!expr_is_constant_eval(arg, CONSTANT_EVAL_GLOBAL_INIT))
|
||||
{
|
||||
SEMA_ERROR(arg, "Expected a constant expression as parameter.");
|
||||
@@ -3504,7 +3504,7 @@ bool sema_analyse_var_decl_ct(SemaContext *context, Decl *decl)
|
||||
}
|
||||
|
||||
// Analyse the expression.
|
||||
if (!sema_analyse_expr_rhs(context, decl->type, init, false, NULL)) goto FAIL;
|
||||
if (!sema_analyse_expr_rhs(context, decl->type, init, false, NULL, false)) goto FAIL;
|
||||
|
||||
// Check that it is constant.
|
||||
if (!expr_is_constant_eval(init, CONSTANT_EVAL_CONSTANT_VALUE))
|
||||
@@ -3712,7 +3712,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
|
||||
|
||||
CallEnvKind env_kind = context->call_env.kind;
|
||||
if (is_static) context->call_env.kind = CALL_ENV_FUNCTION_STATIC;
|
||||
if (!sema_expr_analyse_assign_right_side(context, NULL, decl->type, init, false))
|
||||
if (!sema_expr_analyse_assign_right_side(context, NULL, decl->type, init, false, true))
|
||||
{
|
||||
context->call_env.kind = env_kind;
|
||||
return decl_poison(decl);
|
||||
|
||||
@@ -914,7 +914,8 @@ static inline bool sema_expr_analyse_ternary(SemaContext *context, Expr *expr)
|
||||
return false;
|
||||
}
|
||||
Type *no_fail_max = type_no_optional(max);
|
||||
if (!cast_implicit(context, left, no_fail_max) || !cast_implicit(context, right, no_fail_max)) return false;
|
||||
if (!cast_implicit_binary(context, left, no_fail_max, false) || !cast_implicit_binary(context, right, no_fail_max,
|
||||
false)) return false;
|
||||
}
|
||||
|
||||
if (path != COND_MISSING)
|
||||
@@ -1415,7 +1416,7 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
|
||||
SCOPE_START
|
||||
new_context->original_inline_line = context->original_inline_line ? context->original_inline_line : call->span.row;
|
||||
new_context->original_module = context->original_module ? context->original_module : context->core_module;
|
||||
success = sema_analyse_expr_rhs(new_context, param->type, arg, true, no_match_ref);
|
||||
success = sema_analyse_expr_rhs(new_context, param->type, arg, true, no_match_ref, false);
|
||||
SCOPE_END;
|
||||
sema_context_destroy(&default_context);
|
||||
if (!success)
|
||||
@@ -1582,7 +1583,7 @@ static bool sema_analyse_parameter(SemaContext *context, Expr *arg, Decl *param,
|
||||
}
|
||||
case VARDECL_PARAM:
|
||||
// foo
|
||||
if (!sema_analyse_expr_rhs(context, type, arg, true, no_match_ref)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, type, arg, true, no_match_ref, false)) return false;
|
||||
if (IS_OPTIONAL(arg)) *optional_ref = true;
|
||||
switch (type_storage_type(arg->type))
|
||||
{
|
||||
@@ -1618,7 +1619,7 @@ static bool sema_analyse_parameter(SemaContext *context, Expr *arg, Decl *param,
|
||||
case VARDECL_PARAM_CT:
|
||||
// $foo
|
||||
assert(macro);
|
||||
if (!sema_analyse_expr_rhs(context, type, arg, true, no_match_ref))
|
||||
if (!sema_analyse_expr_rhs(context, type, arg, true, no_match_ref, false))
|
||||
{
|
||||
SEMA_NOTE(definition, "The definition is here.");
|
||||
return false;
|
||||
@@ -1758,7 +1759,7 @@ static inline bool sema_call_analyse_invocation(SemaContext *context, Expr *call
|
||||
FOREACH(Expr*, val, varargs)
|
||||
{
|
||||
// 11e. A simple variadic value:
|
||||
if (!sema_analyse_expr_rhs(context, variadic_type, val, true, no_match_ref)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, variadic_type, val, true, no_match_ref, false)) return false;
|
||||
*optional |= IS_OPTIONAL(val);
|
||||
}
|
||||
}
|
||||
@@ -1938,7 +1939,7 @@ static inline Type *context_unify_returns(SemaContext *context)
|
||||
context_unify_returns(context);
|
||||
}
|
||||
// 8. All casts should work.
|
||||
if (!cast_implicit(context, ret_expr, common_type))
|
||||
if (!cast_implicit(context, ret_expr, common_type, false))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -2232,7 +2233,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
|
||||
inferred_len = false;
|
||||
}
|
||||
}
|
||||
bool success = cast_implicit_silent(context, ret_expr, rtype);
|
||||
bool success = cast_implicit_silent(context, ret_expr, rtype, false);
|
||||
if (inferred_len || (!may_be_optional && IS_OPTIONAL(ret_expr)) || !success)
|
||||
{
|
||||
SEMA_ERROR(ret_expr, "Expected %s, not %s.", type_quoted_error_string(rtype),
|
||||
@@ -2993,7 +2994,7 @@ static inline bool sema_expr_analyse_pointer_offset(SemaContext *context, Expr *
|
||||
Type *flat = type_flatten(pointer->type);
|
||||
unsigned vec_len = flat->type_kind == TYPE_VECTOR ? flat->array.len : 0;
|
||||
|
||||
if (!cast_implicit(context, offset, vec_len ? type_get_vector(type_isz, vec_len) : type_isz)) return false;
|
||||
if (!cast_implicit_binary(context, offset, vec_len ? type_get_vector(type_isz, vec_len) : type_isz, false)) return false;
|
||||
|
||||
// 3. Store optionality
|
||||
bool is_optional = IS_OPTIONAL(pointer) || IS_OPTIONAL(offset);
|
||||
@@ -3049,7 +3050,7 @@ static inline bool sema_expr_analyse_slice(SemaContext *context, Expr *expr)
|
||||
SEMA_ERROR(expr, "No common type can be found between start and end index.");
|
||||
return false;
|
||||
}
|
||||
if (!cast_implicit(context, start, common) || !cast_implicit(context, end, common)) return false;
|
||||
if (!cast_implicit(context, start, common, false) || !cast_implicit(context, end, common, false)) return false;
|
||||
}
|
||||
|
||||
bool start_from_end = expr->subscript_expr.range.start_from_end;
|
||||
@@ -4913,12 +4914,12 @@ static bool sema_expr_analyse_slice_assign(SemaContext *context, Expr *expr, Typ
|
||||
if (base == rhs_type->array.base) goto SLICE_COPY;
|
||||
break;
|
||||
default:
|
||||
if (!cast_implicit(context, right, base)) return false;
|
||||
if (!cast_implicit(context, right, base, false)) return false;
|
||||
goto SLICE_ASSIGN;
|
||||
}
|
||||
|
||||
// By default we need to make a silent attempt.
|
||||
bool could_cast = cast_implicit_silent(context, right, base);
|
||||
bool could_cast = cast_implicit_silent(context, right, base, false);
|
||||
|
||||
// Failed, so let's go back to the original
|
||||
if (!could_cast) goto SLICE_COPY;
|
||||
@@ -4949,7 +4950,7 @@ SLICE_COPY:;
|
||||
if (!count) goto EXPECTED;
|
||||
// Cast to an array of the length.
|
||||
rhs_type = type_get_array(base, count);
|
||||
if (!cast_implicit(context, right, rhs_type)) return false;
|
||||
if (!cast_implicit(context, right, rhs_type, false)) return false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -4994,7 +4995,8 @@ EXPECTED:
|
||||
type_quoted_error_string(base));
|
||||
}
|
||||
|
||||
bool sema_expr_analyse_assign_right_side(SemaContext *context, Expr *expr, Type *left_type, Expr *right, bool is_unwrapped)
|
||||
bool sema_expr_analyse_assign_right_side(SemaContext *context, Expr *expr, Type *left_type, Expr *right,
|
||||
bool is_unwrapped, bool is_declaration)
|
||||
{
|
||||
if (expr && exprptr(expr->binary_expr.left)->expr_kind == EXPR_SLICE)
|
||||
{
|
||||
@@ -5003,7 +5005,7 @@ bool sema_expr_analyse_assign_right_side(SemaContext *context, Expr *expr, Type
|
||||
|
||||
// 1. Evaluate right side to required type.
|
||||
bool to_optional = left_type && type_is_optional(left_type);
|
||||
if (!sema_analyse_expr_rhs(context, left_type, right, is_unwrapped || to_optional, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, left_type, right, is_unwrapped || to_optional, NULL, is_declaration)) return false;
|
||||
if (IS_OPTIONAL(right) && !to_optional)
|
||||
{
|
||||
if (is_unwrapped)
|
||||
@@ -5065,7 +5067,7 @@ static bool sema_expr_analyse_ct_identifier_assign(SemaContext *context, Expr *e
|
||||
if (!sema_binary_analyse_ct_identifier_lvalue(context, left)) return false;
|
||||
|
||||
// 3. Evaluate right side to required type.
|
||||
if (!sema_expr_analyse_assign_right_side(context, expr, left->type, right, false)) return false;
|
||||
if (!sema_expr_analyse_assign_right_side(context, expr, left->type, right, false, false)) return false;
|
||||
|
||||
left->ct_ident_expr.decl->var.init_expr = right;
|
||||
expr_replace(expr, right);
|
||||
@@ -5134,7 +5136,7 @@ static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *lef
|
||||
bool is_unwrapped_var = expr_is_unwrapped_ident(left);
|
||||
|
||||
// 3. Evaluate right side to required type.
|
||||
if (!sema_expr_analyse_assign_right_side(context, expr, left->type, right, is_unwrapped_var)) return false;
|
||||
if (!sema_expr_analyse_assign_right_side(context, expr, left->type, right, is_unwrapped_var, false)) return false;
|
||||
|
||||
if (is_unwrapped_var && IS_OPTIONAL(right))
|
||||
{
|
||||
@@ -5229,7 +5231,7 @@ static bool sema_expr_analyse_op_assign(SemaContext *context, Expr *expr, Expr *
|
||||
BITSTRUCT_OK:
|
||||
// 5. Cast the right hand side to the one on the left
|
||||
if (!sema_analyse_expr(context, right)) return false;
|
||||
if (!cast_implicit(context, right, no_fail)) return false;
|
||||
if (!cast_implicit_binary(context, right, no_fail, false)) return false;
|
||||
if (IS_OPTIONAL(right) && !IS_OPTIONAL(left))
|
||||
{
|
||||
RETURN_SEMA_ERROR(right, "The expression may not be optional.");
|
||||
@@ -5339,13 +5341,13 @@ static bool sema_expr_analyse_add_sub_assign(SemaContext *context, Expr *expr, E
|
||||
Type *lhs_flat = type_flatten(left_type_canonical);
|
||||
if (lhs_flat->type_kind == TYPE_ENUM)
|
||||
{
|
||||
if (!cast_implicit(context, right, type_base(lhs_flat))) return false;
|
||||
if (!cast_implicit(context, right, type_base(lhs_flat), false)) return false;
|
||||
expr->type = type_add_optional(expr->type, optional);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8. Otherwise we cast rhs to lhs
|
||||
if (!cast_implicit(context, right, left->type)) return false;
|
||||
if (!cast_implicit_binary(context, right, left->type, false)) return false;
|
||||
|
||||
// 9. We expect a numeric type on both left and right
|
||||
if (!type_underlying_may_add_sub(left->type))
|
||||
@@ -5376,8 +5378,8 @@ static bool sema_binary_arithmetic_promotion(SemaContext *context, Expr *left, E
|
||||
SEMA_ERROR(parent, error_message, type_quoted_error_string(left->type), type_quoted_error_string(right->type));
|
||||
return false;
|
||||
}
|
||||
return cast_implicit(context, left, max) &&
|
||||
cast_implicit(context, right, max);
|
||||
return cast_implicit_binary(context, left, max, false) &&
|
||||
cast_implicit_binary(context, right, max, false);
|
||||
}
|
||||
|
||||
static void sema_binary_unify_voidptr(SemaContext *context, Expr *left, Expr *right, Type **left_type_ref, Type **right_type_ref)
|
||||
@@ -5558,7 +5560,7 @@ static bool sema_expr_analyse_sub(SemaContext *context, Expr *expr, Expr *left,
|
||||
}
|
||||
|
||||
// 6. Convert to isz
|
||||
if (!cast_implicit(context, right, offset_type)) return true;
|
||||
if (!cast_implicit_binary(context, right, offset_type, false)) return true;
|
||||
|
||||
if (left->expr_kind == EXPR_POINTER_OFFSET)
|
||||
{
|
||||
@@ -6009,7 +6011,7 @@ static bool sema_expr_analyse_shift(SemaContext *context, Expr *expr, Expr *left
|
||||
}
|
||||
|
||||
// 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_binary(context, left, cast_numeric_arithmetic_promotion(type_no_optional(left->type)), false)) return false;
|
||||
|
||||
// 4. For a constant rhs side we will make a series of checks.
|
||||
if (sema_cast_const(right))
|
||||
@@ -6266,7 +6268,7 @@ static bool sema_expr_analyse_comp(SemaContext *context, Expr *expr, Expr *left,
|
||||
}
|
||||
|
||||
// 6. Do the explicit cast.
|
||||
if (!cast_implicit(context, left, max) || !cast_implicit(context, right, max)) return false;
|
||||
if (!cast_implicit(context, left, max, false) || !cast_implicit(context, right, max, false)) return false;
|
||||
bool success = cast_explicit(context, left, max) && cast_explicit(context, right, max);
|
||||
assert(success);
|
||||
DONE:
|
||||
@@ -6535,7 +6537,7 @@ static inline bool sema_expr_analyse_neg_plus(SemaContext *context, Expr *expr)
|
||||
}
|
||||
// 3. Promote the type
|
||||
Type *result_type = cast_numeric_arithmetic_promotion(no_fail);
|
||||
if (!cast_implicit(context, inner, result_type)) return false;
|
||||
if (!cast_implicit(context, inner, result_type, false)) return false;
|
||||
|
||||
// If it's a plus, we simply replace the inner with the outer.
|
||||
if (is_plus)
|
||||
@@ -6598,7 +6600,7 @@ VALID_VEC:
|
||||
|
||||
// Arithmetic promotion
|
||||
Type *result_type = cast_numeric_arithmetic_promotion(type_no_optional(inner->type));
|
||||
if (!cast_implicit(context, inner, result_type)) return false;
|
||||
if (!cast_implicit(context, inner, result_type, false)) return false;
|
||||
|
||||
// 3. The simple case, non-const.
|
||||
if (!sema_constant_fold_ops(inner))
|
||||
@@ -6877,8 +6879,8 @@ static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr)
|
||||
type_quoted_error_string(else_type));
|
||||
return false;
|
||||
}
|
||||
if (!cast_implicit(context, lhs, common)) return false;
|
||||
if (!cast_implicit(context, rhs, common)) return false;
|
||||
if (!cast_implicit(context, lhs, common, false)) return false;
|
||||
if (!cast_implicit(context, rhs, common, false)) return false;
|
||||
expr->type = type_add_optional(common, add_optional);
|
||||
return true;
|
||||
}
|
||||
@@ -8548,7 +8550,7 @@ bool sema_append_const_array(SemaContext *context, Expr *expr, Expr *list, Expr
|
||||
{
|
||||
Expr *element = exprs[i];
|
||||
if (!sema_analyse_inferred_expr(context, indexed, element)) return false;
|
||||
if (!cast_implicit(context, element, indexed)) return false;
|
||||
if (!cast_implicit(context, element, indexed, false)) return false;
|
||||
ConstInitializer *in = CALLOCS(ConstInitializer);
|
||||
in->kind = CONST_INIT_VALUE;
|
||||
in->init_value = element;
|
||||
@@ -8691,7 +8693,7 @@ static inline bool sema_expr_analyse_ct_concat(SemaContext *context, Expr *conca
|
||||
if (type != type_untypedlist && !type_is_arraylike(type_flatten(single_expr->type))) RETURN_SEMA_ERROR(single_expr, "Expected an array or list.");
|
||||
break;
|
||||
case CONCAT_JOIN_BYTES:
|
||||
if (!cast_implicit(context, single_expr, element_type)) return false;
|
||||
if (!cast_implicit(context, single_expr, element_type, false)) return false;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE
|
||||
@@ -9126,7 +9128,8 @@ bool sema_analyse_cond_expr(SemaContext *context, Expr *expr, CondResult *result
|
||||
}
|
||||
|
||||
|
||||
bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allow_optional, bool *no_match_ref)
|
||||
bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allow_optional, bool *no_match_ref,
|
||||
bool as_binary)
|
||||
{
|
||||
if (to && type_is_optional(to))
|
||||
{
|
||||
@@ -9177,8 +9180,15 @@ bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allo
|
||||
NO_SLICE:;
|
||||
if (to)
|
||||
{
|
||||
bool cast_works = no_match_ref ? cast_implicit_silent(context, expr, to) : cast_implicit(context, expr, to);
|
||||
if (!cast_works) return false;
|
||||
if (as_binary)
|
||||
{
|
||||
if (!cast_implicit_binary(context, expr, to, no_match_ref != NULL)) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool cast_works = no_match_ref ? cast_implicit_silent(context, expr, to, false) : cast_implicit(context, expr, to, false);
|
||||
if (!cast_works) return false;
|
||||
}
|
||||
}
|
||||
if (!allow_optional && IS_OPTIONAL(expr))
|
||||
{
|
||||
|
||||
@@ -159,7 +159,7 @@ static inline bool sema_expr_analyse_struct_plain_initializer(SemaContext *conte
|
||||
}
|
||||
Expr *element = elements[i];
|
||||
// 6. We know the required type, so resolve the expression.
|
||||
if (!sema_analyse_expr_rhs(context, members[i]->type, element, true, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, members[i]->type, element, true, NULL, false)) return false;
|
||||
if (member->decl_kind == DECL_VAR && member->var.kind == VARDECL_BITMEMBER)
|
||||
{
|
||||
if (!sema_bit_assignment_check(context, element, members[i])) return false;
|
||||
@@ -284,7 +284,7 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex
|
||||
sub->subscript_expr.expr = exprid(expr_variable(decl));
|
||||
sub->subscript_expr.range.start = exprid(expr_new_const_int(element->span, type_usz, 0));
|
||||
vec_add(expr_list->expression_list, sub);
|
||||
if (!sema_analyse_expr_rhs(context, inner_type, expr_list, true, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, inner_type, expr_list, true, NULL, false)) return false;
|
||||
elements[i] = expr_list;
|
||||
for (unsigned j = 1; j < len; j++)
|
||||
{
|
||||
@@ -292,7 +292,7 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex
|
||||
sub->subscript_expr.expr = exprid(expr_variable(decl));
|
||||
sub->subscript_expr.range.start = exprid(expr_new_const_int(element->span, type_usz, 1));
|
||||
vec_insert_at(elements, i + j, sub);
|
||||
if (!sema_analyse_expr_rhs(context, inner_type, sub, true, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, inner_type, sub, true, NULL, false)) return false;
|
||||
}
|
||||
initializer->initializer_list = elements;
|
||||
count += len - 1;
|
||||
@@ -300,17 +300,17 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex
|
||||
optional = optional || IS_OPTIONAL(element);
|
||||
continue;
|
||||
}
|
||||
if (!cast_implicit(context, element, inner_type)) return false;
|
||||
if (!cast_implicit(context, element, inner_type, false)) return false;
|
||||
optional = optional || IS_OPTIONAL(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sema_analyse_expr_rhs(context, inner_type, element, true, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, inner_type, element, true, NULL, false)) return false;
|
||||
if (inner_is_inferred)
|
||||
{
|
||||
if (inferred_element)
|
||||
{
|
||||
if (!cast_implicit(context, element, inferred_element))
|
||||
if (!cast_implicit(context, element, inferred_element, false))
|
||||
{
|
||||
SEMA_NOTE(elements[0], "Type inferred from here.");
|
||||
return false;
|
||||
@@ -424,7 +424,7 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type
|
||||
bitmember_count_without_value += 1;
|
||||
}
|
||||
if (!value) RETURN_SEMA_ERROR(expr, "This initializer needs a value.");
|
||||
if (!sema_analyse_expr_rhs(context, result, value, true, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, result, value, true, NULL, false)) return false;
|
||||
if (is_bitmember)
|
||||
{
|
||||
if (!sema_bit_assignment_check(context, value, member)) return false;
|
||||
|
||||
@@ -438,7 +438,7 @@ static inline bool sema_analyse_block_exit_stmt(SemaContext *context, Ast *state
|
||||
{
|
||||
if (block_type)
|
||||
{
|
||||
if (!sema_analyse_expr_rhs(context, block_type, ret_expr, true, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, block_type, ret_expr, true, NULL, false)) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -549,7 +549,7 @@ static inline bool sema_analyse_return_stmt(SemaContext *context, Ast *statement
|
||||
|
||||
if (return_expr)
|
||||
{
|
||||
if (!sema_analyse_expr_rhs(context, expected_rtype, return_expr, type_is_optional(expected_rtype), NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, expected_rtype, return_expr, type_is_optional(expected_rtype), NULL, false)) return false;
|
||||
if (!sema_check_not_stack_variable_escape(context, return_expr)) return false;
|
||||
if (!sema_return_optional_check_is_valid_in_scope(context, return_expr)) return false;
|
||||
}
|
||||
@@ -784,7 +784,7 @@ static inline bool sema_analyse_try_unwrap(SemaContext *context, Expr *expr)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cast_implicit(context, optional, ident->type)) return false;
|
||||
if (!cast_implicit(context, optional, ident->type, false)) return false;
|
||||
|
||||
expr->try_unwrap_expr.assign_existing = true;
|
||||
expr->try_unwrap_expr.lhs = ident;
|
||||
@@ -824,7 +824,7 @@ static inline bool sema_analyse_try_unwrap(SemaContext *context, Expr *expr)
|
||||
|
||||
if (var_type)
|
||||
{
|
||||
if (!cast_implicit(context, optional, var_type->type)) return false;
|
||||
if (!cast_implicit(context, optional, var_type->type, false)) return false;
|
||||
}
|
||||
|
||||
// 4c. Create a type_info if needed.
|
||||
@@ -1018,13 +1018,13 @@ static inline bool sema_analyse_last_cond(SemaContext *context, Expr *expr, Cond
|
||||
Expr *right = exprptr(expr->binary_expr.right);
|
||||
bool is_deref = right->expr_kind == EXPR_UNARY && right->unary_expr.operator == UNARYOP_DEREF;
|
||||
if (is_deref) right = right->unary_expr.expr;
|
||||
if (!sema_analyse_expr_rhs(context, NULL, right, false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, NULL, right, false, NULL, false)) return false;
|
||||
Type *type = right->type->canonical;
|
||||
if (type == type_get_ptr(type_any) && is_deref)
|
||||
{
|
||||
is_deref = false;
|
||||
right = exprptr(expr->binary_expr.right);
|
||||
if (!sema_analyse_expr_rhs(context, NULL, right, false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, NULL, right, false, NULL, false)) return false;
|
||||
}
|
||||
if (type != type_any) goto NORMAL_EXPR;
|
||||
// Found an expansion here
|
||||
@@ -1674,7 +1674,7 @@ static inline bool sema_analyse_foreach_stmt(SemaContext *context, Ast *statemen
|
||||
// Create const len if missing.
|
||||
len_call = expr_new_const_int(enumerator->span, type_isz, array_len);
|
||||
}
|
||||
if (!cast_implicit(context, len_call, index_type)) return false;
|
||||
if (!cast_implicit(context, len_call, index_type, false)) return false;
|
||||
// __idx$ = (IndexType)(@__enum$.len()) (or const)
|
||||
vec_add(expressions, expr_generate_decl(idx_decl, len_call));
|
||||
}
|
||||
@@ -1683,7 +1683,7 @@ static inline bool sema_analyse_foreach_stmt(SemaContext *context, Ast *statemen
|
||||
if (len_call)
|
||||
{
|
||||
len_decl = decl_new_generated_var(index_type, VARDECL_LOCAL, enumerator->span);
|
||||
if (!cast_implicit_silent(context, len_call, index_type))
|
||||
if (!cast_implicit_silent(context, len_call, index_type, false))
|
||||
{
|
||||
SEMA_ERROR(enumerator,
|
||||
"'foreach' is not supported, as the length %s cannot "
|
||||
@@ -2123,7 +2123,7 @@ static bool sema_analyse_nextcase_stmt(SemaContext *context, Ast *statement)
|
||||
|
||||
Type *expected_type = parent->ast_kind == AST_SWITCH_STMT ? cond->type : type_anyfault;
|
||||
|
||||
if (!sema_analyse_expr_rhs(context, expected_type, value, false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, expected_type, value, false, NULL, false)) return false;
|
||||
|
||||
statement->nextcase_stmt.defer_id = context_get_defers(context, context->active_scope.defer_last, parent->switch_stmt.defer, true);
|
||||
|
||||
@@ -2243,7 +2243,7 @@ static inline bool sema_analyse_compound_statement_no_scope(SemaContext *context
|
||||
static inline bool sema_check_type_case(SemaContext *context, Type *switch_type, Ast *case_stmt, Ast **cases, unsigned index)
|
||||
{
|
||||
Expr *expr = exprptr(case_stmt->case_stmt.expr);
|
||||
if (!sema_analyse_expr_rhs(context, type_typeid, expr, false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, type_typeid, expr, false, NULL, false)) return false;
|
||||
|
||||
if (sema_cast_const(expr))
|
||||
{
|
||||
@@ -2271,8 +2271,8 @@ static inline bool sema_check_value_case(SemaContext *context, Type *switch_type
|
||||
Expr *to_expr = exprptrzero(case_stmt->case_stmt.to_expr);
|
||||
|
||||
// 1. Try to do implicit conversion to the correct type.
|
||||
if (!sema_analyse_expr_rhs(context, switch_type, expr, false, NULL)) return false;
|
||||
if (to_expr && !sema_analyse_expr_rhs(context, switch_type, to_expr, false, NULL)) return false;
|
||||
if (!sema_analyse_expr_rhs(context, switch_type, expr, false, NULL, false)) return false;
|
||||
if (to_expr && !sema_analyse_expr_rhs(context, switch_type, to_expr, false, NULL, false)) return false;
|
||||
|
||||
bool is_range = to_expr != NULL;
|
||||
bool first_is_const = sema_cast_const(expr);
|
||||
@@ -2570,8 +2570,8 @@ static inline bool sema_analyse_ct_switch_stmt(SemaContext *context, Ast *statem
|
||||
{
|
||||
// Do not evaluate if found.
|
||||
if (matched_case != case_count && expr->resolve_status != RESOLVE_DONE) continue;
|
||||
if (!sema_analyse_expr_rhs(context, type, expr, false, NULL)) goto FAILED;
|
||||
if (to_expr && !sema_analyse_expr_rhs(context, type, to_expr, false, NULL)) goto FAILED;
|
||||
if (!sema_analyse_expr_rhs(context, type, expr, false, NULL, false)) goto FAILED;
|
||||
if (to_expr && !sema_analyse_expr_rhs(context, type, to_expr, false, NULL, false)) goto FAILED;
|
||||
}
|
||||
if (!sema_cast_const(expr))
|
||||
{
|
||||
|
||||
14
test/test_suite/vector/vector_conversion_scalar.c3
Normal file
14
test/test_suite/vector/vector_conversion_scalar.c3
Normal file
@@ -0,0 +1,14 @@
|
||||
fn void test2(int[<2>] x) {}
|
||||
fn void main()
|
||||
{
|
||||
int[<2>] y = 1;
|
||||
y[..] = 3;
|
||||
y.xy = 3; // #error: cannot use swizzling
|
||||
y *= 2;
|
||||
y = 3; // #error: explicit cast
|
||||
test2(3); // #error: explicit cast
|
||||
{|
|
||||
if (y[0] == 3) return 1; // #error: explicit cast
|
||||
return y;
|
||||
|};
|
||||
}
|
||||
Reference in New Issue
Block a user