Assertion when has_tagof is accidentally called on fn type #1343

This commit is contained in:
Christoffer Lerno
2024-08-10 21:59:41 +02:00
parent 05c5eaed48
commit f2911be116
4 changed files with 25 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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