Minor attribute combination checking (#2918)

* Minor attribute combination checking

* Added tests to the test suite.
This commit is contained in:
Damien Wilson
2026-02-19 10:58:39 -06:00
committed by GitHub
parent 152558f5bc
commit 9efb9b90d1
2 changed files with 26 additions and 4 deletions

View File

@@ -3181,7 +3181,6 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
RETURN_SEMA_ERROR(attr, "'%s' is not a valid %s attribute.", attr->name, attribute_domain_to_string(domain)); RETURN_SEMA_ERROR(attr, "'%s' is not a valid %s attribute.", attr->name, attribute_domain_to_string(domain));
} }
// No attribute has more than one argument right now.
unsigned args = vec_size(attr->exprs); unsigned args = vec_size(attr->exprs);
if (args > 1 && type != ATTRIBUTE_LINK && type != ATTRIBUTE_TAG && type != ATTRIBUTE_WASM) if (args > 1 && type != ATTRIBUTE_LINK && type != ATTRIBUTE_TAG && type != ATTRIBUTE_WASM)
{ {
@@ -3507,8 +3506,11 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
} }
return true; return true;
case ATTRIBUTE_NOINLINE: case ATTRIBUTE_NOINLINE:
if (decl->func_decl.attr_inline)
{
RETURN_SEMA_ERROR(attr, "@noinline cannot be combined with @inline.");
}
decl->func_decl.attr_noinline = true; decl->func_decl.attr_noinline = true;
decl->func_decl.attr_inline = false;
break; break;
case ATTRIBUTE_NOPADDING: case ATTRIBUTE_NOPADDING:
decl->attr_nopadding = true; decl->attr_nopadding = true;
@@ -3527,7 +3529,7 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
decl->func_decl.signature.attrs.always_const = true; decl->func_decl.signature.attrs.always_const = true;
break; break;
case ATTRIBUTE_NODISCARD: case ATTRIBUTE_NODISCARD:
if (decl->func_decl.signature.attrs.nodiscard) if (decl->func_decl.signature.attrs.noreturn)
{ {
RETURN_SEMA_ERROR(attr, "@nodiscard cannot be combined with @noreturn."); RETURN_SEMA_ERROR(attr, "@nodiscard cannot be combined with @noreturn.");
} }
@@ -3537,8 +3539,11 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
decl->func_decl.signature.attrs.maydiscard = true; decl->func_decl.signature.attrs.maydiscard = true;
break; break;
case ATTRIBUTE_INLINE: case ATTRIBUTE_INLINE:
if (decl->func_decl.attr_noinline)
{
RETURN_SEMA_ERROR(attr, "@inline cannot be combined with @noinline.");
}
decl->func_decl.attr_inline = true; decl->func_decl.attr_inline = true;
decl->func_decl.attr_noinline = false;
break; break;
case ATTRIBUTE_NORETURN: case ATTRIBUTE_NORETURN:
if (decl->func_decl.signature.attrs.nodiscard) if (decl->func_decl.signature.attrs.nodiscard)
@@ -3616,9 +3621,17 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_
decl->is_packed = true; decl->is_packed = true;
break; break;
case ATTRIBUTE_UNUSED: case ATTRIBUTE_UNUSED:
if(decl->is_must_use)
{
RETURN_SEMA_ERROR(attr, "@unused cannot be combined with @used.");
}
decl->is_maybe_unused = true; decl->is_maybe_unused = true;
break; break;
case ATTRIBUTE_USED: case ATTRIBUTE_USED:
if(decl->is_maybe_unused)
{
RETURN_SEMA_ERROR(attr, "@used cannot be combined with @unused.");
}
decl->is_must_use = true; decl->is_must_use = true;
break; break;
case ATTRIBUTE_PURE: case ATTRIBUTE_PURE:

View File

@@ -0,0 +1,9 @@
module test;
fn void foo() @inline @noinline // #error: cannot be combined
{}
fn void bar() @used @unused // #error: cannot be combined
{}
fn bool baz() @nodiscard @noreturn // #error: cannot be combined
{}