From e153c7671948c0f0d6408e15be654cac1b55f3bd Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sun, 23 Jun 2024 16:13:37 +0200 Subject: [PATCH] Bit negate now properly does type promotion. --- releasenotes.md | 3 +- src/compiler/sema_casts.c | 3 +- src/compiler/sema_expr.c | 67 ++++++++----------------- test/test_suite/constants/constants.c3t | 2 +- 4 files changed, 25 insertions(+), 50 deletions(-) diff --git a/releasenotes.md b/releasenotes.md index 107de72bc..b5a695f24 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -16,7 +16,8 @@ - Fixed crash on certain recursive function definitions #1209. - Return the typekind "FUNC" for a function pointer. - No longer possible to dereference a function pointer. -- Fix bug with @jump miscompile +- Fix bug with @jump miscompile. +- Bit negate does implicit integer promotion. ### Stdlib changes - Added `remove_first_item` `remove_last_item` and `remove_item` as aliases for the `match` functions. diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 7ad1d38e1..0a58ac39f 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -276,6 +276,8 @@ static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool { Type *from_type = expr->type; + if (from_type == to_type) return true; + if (to_type->canonical->type_kind == TYPE_POINTER && from_type->canonical->type_kind != TYPE_POINTER && to_type->canonical->pointer == from_type->canonical && expr->expr_kind == EXPR_IDENTIFIER && expr->identifier_expr.was_ref) @@ -285,7 +287,6 @@ static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool " with '&' to pass it as a pointer."); } - if (from_type == to_type) return true; bool is_void_silence = type_is_void(to_type) && is_explicit; bool add_optional = type_is_optional(to_type) || type_is_optional(from_type); diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 96c162b2a..af984c30e 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -3279,8 +3279,6 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp } Decl *decl = canonical->decl; - // TODO add more constants that can be inspected? - // e.g. SomeEnum.values, MyUnion.x.offset etc? switch (decl->decl_kind) { case DECL_ENUM: @@ -4081,7 +4079,6 @@ static inline bool sema_expr_analyse_swizzle(SemaContext *context, Expr *expr, E if ((val & 0xF) >= vec_len) { RETURN_SEMA_ERROR(expr, "The '%c' component is not present in a vector of length %d, did you assume a longer vector?", kw[i], vec_len); - return false; } if (i == 0) { @@ -6087,32 +6084,28 @@ static bool sema_expr_analyse_comp(SemaContext *context, Expr *expr, Expr *left, // 4. If no common type, then that's an error: if (!max) { - SEMA_ERROR(expr, "%s and %s are different types and cannot be compared.", - type_quoted_error_string(left->type), type_quoted_error_string(right->type)); - return false; + RETURN_SEMA_ERROR(expr, "%s and %s are different types and cannot be compared.", + type_quoted_error_string(left->type), type_quoted_error_string(right->type)); } if (!type_is_comparable(max)) { if (type_is_user_defined(max->canonical)) { - SEMA_ERROR(expr, "%s does not support comparisons, you need to manually implement a comparison if you need it.", - type_quoted_error_string(left->type)); + RETURN_SEMA_ERROR(expr, + "%s does not support comparisons, you need to manually implement a comparison if you need it.", + type_quoted_error_string(left->type)); } - else - { - SEMA_ERROR(expr, "%s does not support comparisons.", - type_quoted_error_string(left->type)); - } - return false; + RETURN_SEMA_ERROR(expr, "%s does not support comparisons.", + type_quoted_error_string(left->type)); } if (!is_equality_type_op) { if (!type_is_ordered(max)) { - SEMA_ERROR(expr, "%s can only be compared using '!=' and '==' it cannot be ordered, did you make a mistake?", - type_quoted_error_string(left->type)); - return false; + RETURN_SEMA_ERROR(expr, "%s can only be compared using '!=' and '==' it " + "cannot be ordered, did you make a mistake?", + type_quoted_error_string(left->type)); } if (type_is_pointer_type(type_flatten(max))) { @@ -6120,9 +6113,8 @@ static bool sema_expr_analyse_comp(SemaContext *context, Expr *expr, Expr *left, // Only comparisons between the same type is allowed. Subtypes not allowed. if (left_type != right_type && left_type != type_voidptr && right_type != type_voidptr) { - SEMA_ERROR(expr, "You are not allowed to compare pointers of different types, " - "if you need to do, first convert all pointers to void*."); - return false; + RETURN_SEMA_ERROR(expr, "You are not allowed to compare pointers of different types, " + "if you need to do, first convert all pointers to void*."); } } } @@ -6441,8 +6433,7 @@ static inline bool sema_expr_analyse_bit_not(SemaContext *context, Expr *expr) { Type *vector_type = type_vector_type(canonical); if (vector_type && (type_is_integer(vector_type) || vector_type == type_bool)) goto VALID_VEC; - SEMA_ERROR(expr, "Cannot bit negate '%s'.", type_to_error_string(inner->type)); - return false; + RETURN_SEMA_ERROR(expr, "Cannot bit negate '%s'.", type_to_error_string(inner->type)); } VALID_VEC: @@ -6452,9 +6443,15 @@ VALID_VEC: sema_invert_bitstruct_const_initializer(expr->const_expr.initializer); return true; } + + // Arithmetic promotion + Type *result_type = cast_numeric_arithmetic_promotion(type_no_optional(inner->type)); + if (!cast_implicit(context, inner, result_type)) return false; + // 3. The simple case, non-const. if (!sema_constant_fold_ops(inner)) { + expr->type = inner->type; return true; } @@ -6468,7 +6465,6 @@ VALID_VEC: } // 5. Perform ~ constant folded - // TODO arithmetic promotion? expr->const_expr.ixx = int_not(inner->const_expr.ixx); return true; } @@ -7574,6 +7570,7 @@ static inline bool sema_may_reuse_lambda(SemaContext *context, Decl *lambda, Typ if (typeget(sig->rtype)->canonical != types[0]) return false; FOREACH_BEGIN_IDX(i, Decl *param, sig->params) TypeInfo *info = vartype(param); + assert(info && types[i + 1]); // NOLINT if (info->type->canonical != types[i + 1]) return false; FOREACH_END(); return true; @@ -8327,30 +8324,6 @@ bool sema_append_const_array(SemaContext *context, Expr *expr, Expr *list, Expr return true; } -static bool sema_concat_join_single(Expr *expr, Expr **exprs, Type *type, ArraySize len) -{ - ConstInitializer **inits = VECNEW(ConstInitializer*, len); - assert(len == vec_size(exprs)); - for (unsigned i = 0; i < len; i++) - { - ConstInitializer *in = CALLOCS(ConstInitializer); - in->kind = CONST_INIT_VALUE; - in->init_value = exprs[i]; - vec_add(inits, in); - } - expr->expr_kind = EXPR_CONST; - expr->resolve_status = RESOLVE_DONE; - ConstInitializer *new_init = CALLOCS(ConstInitializer); - new_init->init_array_full = inits; - new_init->type = expr->type = type_get_array(type, len); - new_init->kind = CONST_INIT_ARRAY_FULL; - expr->const_expr = (ExprConst) { - .const_kind = CONST_INITIALIZER, - .initializer = new_init - }; - return true; -} - bool sema_concat_join_bytes(Expr *expr, Expr **exprs, ArraySize len) { bool is_bytes = exprs[0]->const_expr.const_kind == CONST_BYTES; diff --git a/test/test_suite/constants/constants.c3t b/test/test_suite/constants/constants.c3t index 2c91ac5e3..9afeb8c99 100644 --- a/test/test_suite/constants/constants.c3t +++ b/test/test_suite/constants/constants.c3t @@ -1,4 +1,4 @@ -const char AA @private = ~(char)(0); +const char AA @private = (char)~(char)(0); const char BB = 200 ; const uint CC @private = ~(uint)(0); const uint DD @private = FOO;