From f2911be116e1f9676d54bbb95dfbb2c53984ecba Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 10 Aug 2024 21:59:41 +0200 Subject: [PATCH] Assertion when has_tagof is accidentally called on fn type #1343 --- src/compiler/compiler_internal.h | 1 + src/compiler/sema_expr.c | 6 +++++- src/compiler/sema_types.c | 3 ++- .../compile_time_introspection/tag_1343.c3t | 17 +++++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 test/test_suite/compile_time_introspection/tag_1343.c3t diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index c697f58fc..884160165 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -2939,6 +2939,7 @@ static inline StorageType type_storage_type(Type *type) case TYPE_MEMBER: case TYPE_UNTYPED_LIST: case TYPE_TYPEINFO: + case TYPE_FUNC_RAW: return STORAGE_COMPILE_TIME; case TYPE_OPTIONAL: type = type->optional; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 6153a46d8..ed986a6b1 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -4280,7 +4280,11 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr, case TYPE_PROPERTY_TAGOF: case TYPE_PROPERTY_HAS_TAGOF: expr->expr_kind = EXPR_TAGOF; - expr->tag_of_expr = (ExprTagOf) { .type = type->decl, .property = property }; + expr->tag_of_expr = (ExprTagOf) { + .type = type->type_kind == TYPE_FUNC_PTR + ? type->pointer->function.decl + : type->decl, + .property = property }; return true; case TYPE_PROPERTY_NONE: return false; diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 83b73fdaf..962cd4531 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -305,7 +305,8 @@ INLINE bool sema_resolve_typeof(SemaContext *context, TypeInfo *type_info) Expr *expr = type_info->unresolved_type_expr; if (!sema_analyse_expr_lvalue_fold_const(context, expr)) return false; Type *expr_type = expr->type; - switch (type_storage_type(expr->type)) + if (expr_type->type_kind == TYPE_FUNC_RAW) expr_type = type_get_func_ptr(expr_type); + switch (type_storage_type(expr_type)) { case STORAGE_NORMAL: case STORAGE_VOID: diff --git a/test/test_suite/compile_time_introspection/tag_1343.c3t b/test/test_suite/compile_time_introspection/tag_1343.c3t new file mode 100644 index 000000000..91e480f83 --- /dev/null +++ b/test/test_suite/compile_time_introspection/tag_1343.c3t @@ -0,0 +1,17 @@ +struct Foo { int a; } +struct Bar { int a; } +fn void Bar.xyz(&self) @tag("footag", 123) {} +macro void Foo.tags(&self, other) +{ + // inner to remove pointer + var $Type = $typefrom($typeof(other).inner); + var $methodcount = $Type.methodsof.len; + $for (var $i = 0; $i < $methodcount; $i++) + var $MethodType1 = $typeof($Type.$eval($Type.methodsof[$i])); + var $MethodType = $typeof(&$Type.$eval($Type.methodsof[$i])); + $MethodType a; + $MethodType1 b; + var $hasfootag = $MethodType.has_tagof("footag"); + $endfor +} +fn void main() { Bar bar; Foo foo; foo.tags(&bar); }