mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
"poison" the current function early when a declaration can't be correctly resolved.
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
- Allow even smaller memory limits.
|
||||
- Check unaligned array access.
|
||||
- Add "@structlike" for typedefs.
|
||||
- "poison" the current function early when a declaration can't be correctly resolved.
|
||||
|
||||
### Fixes
|
||||
- mkdir/rmdir would not work properly with substring paths on non-windows platforms.
|
||||
|
||||
@@ -4639,6 +4639,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
|
||||
|
||||
VarDeclKind kind = decl->var.kind;
|
||||
|
||||
bool success = true;
|
||||
bool is_global = !local;
|
||||
switch (kind)
|
||||
{
|
||||
@@ -4811,25 +4812,26 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
|
||||
CallEnvKind env_kind = context->call_env.kind;
|
||||
if (is_static) context->call_env.kind = CALL_ENV_FUNCTION_STATIC;
|
||||
decl->in_init = true;
|
||||
if (!sema_expr_analyse_assign_right_side(context, NULL, decl->type, init, false, true, NULL))
|
||||
{
|
||||
context->call_env.kind = env_kind;
|
||||
return decl_poison(decl);
|
||||
}
|
||||
success = sema_expr_analyse_assign_right_side(context, NULL, decl->type, init, false, true, NULL);
|
||||
decl->in_init = false;
|
||||
context->call_env.kind = env_kind;
|
||||
|
||||
if (infer_len)
|
||||
{
|
||||
if (!success) return decl_poison(decl);
|
||||
decl->type = type_add_optional(init->type, IS_OPTIONAL(decl));
|
||||
}
|
||||
|
||||
// 2. Check const-ness
|
||||
if (global_level_var && !expr_is_runtime_const(init))
|
||||
if (global_level_var)
|
||||
{
|
||||
SEMA_ERROR(init, "The expression must be a constant value.");
|
||||
return decl_poison(decl);
|
||||
if (!success) return decl_poison(decl);
|
||||
if (!expr_is_runtime_const(init))
|
||||
{
|
||||
SEMA_ERROR(init, "The expression must be a constant value.");
|
||||
return decl_poison(decl);
|
||||
}
|
||||
}
|
||||
if (!success) goto EXIT_OK;
|
||||
if (global_level_var || !type_is_abi_aggregate(init->type)) sema_cast_const(init);
|
||||
if (expr_is_const(init))
|
||||
{
|
||||
@@ -4850,7 +4852,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
|
||||
{
|
||||
if (!sema_set_alloca_alignment(context, decl->type, &decl->alignment)) return false;
|
||||
}
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1232,7 +1232,11 @@ static inline bool sema_analyse_declare_stmt(SemaContext *context, Ast *statemen
|
||||
Decl *decl = statement->declare_stmt;
|
||||
VarDeclKind kind = decl->var.kind;
|
||||
bool erase = kind == VARDECL_LOCAL_CT_TYPE || kind == VARDECL_LOCAL_CT;
|
||||
if (!sema_analyse_var_decl(context, decl, true)) return false;
|
||||
if (!sema_analyse_var_decl(context, decl, true))
|
||||
{
|
||||
if (!decl_ok(decl)) context->active_scope.is_poisoned = true;
|
||||
return false;
|
||||
}
|
||||
if (erase || decl->decl_kind == DECL_ERASED) statement->ast_kind = AST_NOP_STMT;
|
||||
return true;
|
||||
}
|
||||
@@ -1445,6 +1449,7 @@ static inline bool sema_analyse_for_stmt(SemaContext *context, Ast *statement)
|
||||
|
||||
if (is_infinite && !statement->for_stmt.flow.has_break)
|
||||
{
|
||||
if (!success) context->active_scope.is_poisoned = true;
|
||||
SET_JUMP_END(context, statement);
|
||||
}
|
||||
return success;
|
||||
|
||||
@@ -442,7 +442,7 @@ fn void test_file(Path file_path)
|
||||
// Start process
|
||||
SubProcess compilation = process::create(cmdline.array_view(), { .search_user_path, .no_window, .inherit_environment })!!;
|
||||
defer compilation.destroy();
|
||||
CInt result = compilation.join()!!;
|
||||
CInt result = compilation.join() ?? 1;
|
||||
DString out;
|
||||
io::copy_to(&&compilation.stderr(), &out)!!;
|
||||
if (result != 0 && result != 1)
|
||||
|
||||
@@ -25,13 +25,15 @@ struct BazTwo
|
||||
fn void test()
|
||||
{
|
||||
Foo x;
|
||||
Bar y = (Bar)(x); // #error: 'Foo' to 'Bar'
|
||||
{ Bar y = (Bar)(x); } // #error: 'Foo' to 'Bar'
|
||||
|
||||
Baz z;
|
||||
int[2] w = (int[2])(z); // #error: 'Baz' to 'int[2]'
|
||||
z = (Baz)(w);
|
||||
BazTwo v = (BazTwo)(z); // #error: 'Baz' to 'BazTwo'
|
||||
v = (BazTwo)(w);
|
||||
z = (Baz)(v);
|
||||
w = (int[2])(v);
|
||||
{ int[2] w = (int[2])(z); } // #error: 'Baz' to 'int[2]'
|
||||
int[2] w;
|
||||
z = (Baz)(w); // #error: to 'Baz'
|
||||
{ BazTwo v = (BazTwo)(z); } // #error: 'Baz' to 'BazTwo'
|
||||
BazTwo v;
|
||||
v = (BazTwo)(w); // #error: to 'BazTwo'
|
||||
z = (Baz)(v); // #error: possible to cast 'BazTwo' to 'Baz'
|
||||
w = (int[2])(v); // #error: possible to cast 'BazTwo' to 'int[2]'
|
||||
}
|
||||
|
||||
@@ -10,6 +10,18 @@ $foreach $c : $chars:
|
||||
int $offset = ($c - $from) / BITS;
|
||||
int $rem = ($c - $from) % BITS;
|
||||
uint128 $value = $bitmap[$offset]; // #error: is out of range
|
||||
$endforeach
|
||||
}
|
||||
|
||||
fn int main2()
|
||||
{
|
||||
String $chars = "Abcd";
|
||||
char $from = 2;
|
||||
char[10] $bitmap = {};
|
||||
$foreach $c : $chars:
|
||||
int $offset = ($c - $from) / BITS;
|
||||
int $rem = ($c - $from) % BITS;
|
||||
uint128 $value = 1;
|
||||
$value |= 1ULL << $rem;
|
||||
$bitmap = $bitmap[:$offset] +++ $value +++ $bitmap[$offset+1..]; // #error: End index out of bounds
|
||||
$endforeach
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
module testing;
|
||||
import std::io;
|
||||
|
||||
macro char[] read(src, Allocator allocator, n)
|
||||
macro void read(src, Allocator allocator, n)
|
||||
{
|
||||
char* data = allocator::malloc_try(allocator, n)!; // #error: Rethrow is only allowed in macros
|
||||
io::read_all(src, data[:n])!;
|
||||
(void)io::read_all(src, data[:n]);
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
ByteReader br;
|
||||
read(&br, allocator::temp(), 10);
|
||||
read(&br, allocator::temp(), 10)!!;
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import abc @norecurse @public;
|
||||
|
||||
fn int test()
|
||||
{
|
||||
Abc x; // #error: is '@private'
|
||||
{ Abc x; } // #error: is '@private'
|
||||
abc::baz::test(); // #error: is '@private'
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user