mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Incorrect parsing of call attributes #2144.
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
- Using a non-const as the end range for a bitstruct would trigger an assert.
|
- Using a non-const as the end range for a bitstruct would trigger an assert.
|
||||||
- Incorrect parsing of ad hoc generic types, like `Foo{int}****` #2140.
|
- Incorrect parsing of ad hoc generic types, like `Foo{int}****` #2140.
|
||||||
- $define did not correctly handle generic types #2140.
|
- $define did not correctly handle generic types #2140.
|
||||||
|
- Incorrect parsing of call attributes #2144.
|
||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
- Added `String.quick_ztr` and `String.is_zstr`
|
- Added `String.quick_ztr` and `String.is_zstr`
|
||||||
|
|||||||
@@ -982,21 +982,19 @@ static Expr *parse_call_expr(ParseContext *c, Expr *left)
|
|||||||
PRINT_ERROR_HERE("Expected a macro body here.");
|
PRINT_ERROR_HERE("Expected a macro body here.");
|
||||||
return poisoned_expr;
|
return poisoned_expr;
|
||||||
}
|
}
|
||||||
Attr *attr;
|
|
||||||
int force_inline = -1;
|
int force_inline = -1;
|
||||||
while (1)
|
while (tok_is(c, TOKEN_AT_IDENT))
|
||||||
{
|
{
|
||||||
if (!parse_attribute(c, &attr, true)) return poisoned_expr;
|
AttributeType attr_type = attribute_by_name(symstr(c));
|
||||||
if (!attr) break;
|
advance(c);
|
||||||
|
|
||||||
AttributeType attr_type = attribute_by_name(attr->name);
|
|
||||||
int new_inline = attr_type == ATTRIBUTE_INLINE;
|
int new_inline = attr_type == ATTRIBUTE_INLINE;
|
||||||
switch (attr_type)
|
switch (attr_type)
|
||||||
{
|
{
|
||||||
case ATTRIBUTE_PURE:
|
case ATTRIBUTE_PURE:
|
||||||
if (call->call_expr.attr_pure)
|
if (call->call_expr.attr_pure)
|
||||||
{
|
{
|
||||||
RETURN_PRINT_ERROR_AT(poisoned_expr, attr, "Repeat of the same attribute is not allowed.");
|
PRINT_ERROR_LAST("Repeat of the same attribute is not allowed.");
|
||||||
|
return poisoned_expr;
|
||||||
}
|
}
|
||||||
call->call_expr.attr_pure = true;
|
call->call_expr.attr_pure = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -1004,18 +1002,26 @@ static Expr *parse_call_expr(ParseContext *c, Expr *left)
|
|||||||
case ATTRIBUTE_NOINLINE:
|
case ATTRIBUTE_NOINLINE:
|
||||||
if (force_inline == new_inline)
|
if (force_inline == new_inline)
|
||||||
{
|
{
|
||||||
RETURN_PRINT_ERROR_AT(poisoned_expr, attr, "Repeat of the same attribute is not allowed.");
|
PRINT_ERROR_LAST("Repeat of the same attribute is not allowed.");
|
||||||
|
return poisoned_expr;
|
||||||
}
|
}
|
||||||
if (force_inline != -1)
|
if (force_inline != -1)
|
||||||
{
|
{
|
||||||
RETURN_PRINT_ERROR_AT(poisoned_expr, attr, "@inline and @noinline cannot be combined");
|
PRINT_ERROR_LAST("@inline and @noinline cannot be combined");
|
||||||
|
return poisoned_expr;
|
||||||
}
|
}
|
||||||
force_inline = new_inline;
|
force_inline = new_inline;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
RETURN_PRINT_ERROR_AT(poisoned_expr, attr, "Only '@pure', '@inline' and '@noinline' are valid attributes for calls.");
|
PRINT_ERROR_LAST("Only '@pure', '@inline' and '@noinline' are valid attributes for calls.");
|
||||||
|
return poisoned_expr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tok_is(c, TOKEN_AT_TYPE_IDENT))
|
||||||
|
{
|
||||||
|
PRINT_ERROR_HERE("User defined attributes are not allowed, only @pure, @inline and @noinline.");
|
||||||
|
return poisoned_expr;
|
||||||
|
}
|
||||||
if (force_inline != -1)
|
if (force_inline != -1)
|
||||||
{
|
{
|
||||||
call->call_expr.attr_force_inline = force_inline == 1;
|
call->call_expr.attr_force_inline = force_inline == 1;
|
||||||
|
|||||||
11
test/test_suite/attributes/call_attribute_parse.c3
Normal file
11
test/test_suite/attributes/call_attribute_parse.c3
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
module test;
|
||||||
|
fn VoidFn foo()
|
||||||
|
{
|
||||||
|
return fn void() {};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void main()
|
||||||
|
{
|
||||||
|
foo() @inline ();
|
||||||
|
foo() @inline (foo()); // #error: This argument would exceed the number of parameters
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user