Taking .ordinal from an enum passed by pointer and then taking the address of this result would return the enum, not int.

This commit is contained in:
Christoffer Lerno
2025-09-18 14:04:49 +02:00
parent c5e3a1b2da
commit fdc20dc642
4 changed files with 44 additions and 21 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 <iso646.h>
#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;
}

View File

@@ -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();
}