diff --git a/releasenotes.md b/releasenotes.md index 1bbc99493..ce31ea4ee 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -30,6 +30,7 @@ - Regression: Compiler segfault when assigning struct literal with too few members #2483 - Fix compile time format check when the formatting string is a constant slice. - Compiler segfault for invalid e-mails in project.json. #2488 +- Taking `.ordinal` from an enum passed by pointer and then taking the address of this result would return the enum, not int. ### Stdlib changes - Added generic `InterfaceList` to store a list of values that implement a specific interface diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 96fe532bd..6d9a4cf4f 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -735,6 +735,7 @@ typedef enum { EXPR_ACCESS_RESOLVED, EXPR_ACCESS_UNRESOLVED, + EXPR_ADDR_CONVERSION, EXPR_ASM, EXPR_BENCHMARK_HOOK, EXPR_BINARY, @@ -744,16 +745,15 @@ typedef enum EXPR_BUILTIN_ACCESS, EXPR_CALL, EXPR_CAST, - EXPR_CATCH_UNRESOLVED, EXPR_CATCH, + EXPR_CATCH_UNRESOLVED, EXPR_COMPILER_CONST, EXPR_COMPOUND_LITERAL, EXPR_COND, EXPR_CONST, - EXPR_TYPECALL, EXPR_CT_ARG, - EXPR_CT_CALL, EXPR_CT_ASSIGNABLE, + EXPR_CT_CALL, EXPR_CT_DEFINED, EXPR_CT_EVAL, EXPR_CT_IDENT, @@ -765,20 +765,19 @@ typedef enum EXPR_DESIGNATOR, EXPR_DISCARD, EXPR_EMBED, - EXPR_VECTOR_TO_ARRAY, - EXPR_SLICE_TO_VEC_ARRAY, - EXPR_SCALAR_TO_VECTOR, + EXPR_ENUM_FROM_ORD, EXPR_EXPRESSION_LIST, - EXPR_FORCE_UNWRAP, + EXPR_EXT_TRUNC, EXPR_FLOAT_TO_INT, + EXPR_FORCE_UNWRAP, EXPR_GENERIC_IDENT, EXPR_HASH_IDENT, EXPR_IDENTIFIER, EXPR_INITIALIZER_LIST, + EXPR_INT_TO_BOOL, EXPR_INT_TO_FLOAT, EXPR_INT_TO_PTR, EXPR_IOTA_DECL, - EXPR_PTR_TO_INT, EXPR_LAMBDA, EXPR_LAST_FAULT, EXPR_LENGTHOF, @@ -793,21 +792,22 @@ typedef enum EXPR_NOP, EXPR_OPERATOR_CHARS, EXPR_OPTIONAL, - EXPR_ENUM_FROM_ORD, EXPR_OTHER_CONTEXT, EXPR_POINTER_OFFSET, - EXPR_ADDR_CONVERSION, EXPR_POISONED, - EXPR_PTR_ACCESS, EXPR_POST_UNARY, + EXPR_PTR_ACCESS, + EXPR_PTR_TO_INT, + EXPR_RECAST, EXPR_RETHROW, EXPR_RETVAL, EXPR_RVALUE, - EXPR_RECAST, + EXPR_SCALAR_TO_VECTOR, EXPR_SLICE, - EXPR_SLICE_LEN, EXPR_SLICE_ASSIGN, EXPR_SLICE_COPY, + EXPR_SLICE_LEN, + EXPR_SLICE_TO_VEC_ARRAY, EXPR_SPLAT, EXPR_STRINGIFY, EXPR_SUBSCRIPT, @@ -816,20 +816,20 @@ typedef enum EXPR_SWIZZLE, EXPR_TERNARY, EXPR_TEST_HOOK, - EXPR_TWO, EXPR_TRY, EXPR_TRY_UNRESOLVED, EXPR_TRY_UNWRAP_CHAIN, + EXPR_TWO, + EXPR_TYPECALL, EXPR_TYPEID, EXPR_TYPEID_INFO, EXPR_TYPEINFO, - EXPR_UNRESOLVED_IDENTIFIER, EXPR_UNARY, + EXPR_UNRESOLVED_IDENTIFIER, EXPR_VASPLAT, EXPR_VECTOR_FROM_ARRAY, - EXPR_EXT_TRUNC, - EXPR_INT_TO_BOOL, - EXPR_LAST = EXPR_VASPLAT + EXPR_VECTOR_TO_ARRAY, + EXPR_LAST = EXPR_VECTOR_TO_ARRAY } ExprKind; typedef enum diff --git a/src/compiler/expr.c b/src/compiler/expr.c index e387a54b1..f09f8b67f 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -2,6 +2,8 @@ // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. +#include + #include "compiler_internal.h" static inline bool expr_list_is_constant_eval(Expr **exprs); @@ -574,16 +576,18 @@ Expr *expr_new_two(Expr *first, Expr *second) void expr_insert_addr(Expr *original) { ASSERT(original->resolve_status == RESOLVE_DONE); + Type *type = original->type; + bool optional = type_is_optional(type); + Type *new_type = type_add_optional(type_get_ptr(type_no_optional(type)), optional); if (original->expr_kind == EXPR_UNARY && original->unary_expr.operator == UNARYOP_DEREF) { *original = *original->unary_expr.expr; + original->type = new_type; return; } Expr *inner = expr_copy(original); original->expr_kind = EXPR_UNARY; - Type *inner_type = inner->type; - bool optional = type_is_optional(inner->type); - original->type = type_add_optional(type_get_ptr(type_no_optional(inner_type)), optional); + original->type = new_type; original->unary_expr.operator = UNARYOP_ADDR; original->unary_expr.expr = inner; } diff --git a/test/test_suite/enumerations/enum_to_ordinal.c3 b/test/test_suite/enumerations/enum_to_ordinal.c3 new file mode 100644 index 000000000..6a15ed1fe --- /dev/null +++ b/test/test_suite/enumerations/enum_to_ordinal.c3 @@ -0,0 +1,18 @@ +import std::io; + +enum Foo +{ + A, + B, +} + +fn void Foo.hello(&self) +{ + io::printf("%d\n", self.ordinal); +} + +fn void main() +{ + Foo x = B; + x.hello(); +} \ No newline at end of file