mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fixed issue where &foo[1] was not considered a constant when foo is a global.
This commit is contained in:
@@ -332,10 +332,22 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind)
|
||||
case EXPR_SCOPED_EXPR:
|
||||
case EXPR_SLICE_ASSIGN:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_IDENTIFIER:
|
||||
case EXPR_RETHROW:
|
||||
case EXPR_UNDEF:
|
||||
return false;
|
||||
case EXPR_IDENTIFIER:
|
||||
if (expr->identifier_expr.decl->decl_kind != DECL_VAR) return true;
|
||||
switch (expr->identifier_expr.decl->var.kind)
|
||||
{
|
||||
case VARDECL_CONST:
|
||||
case VARDECL_PARAM_CT_TYPE:
|
||||
case VARDECL_LOCAL_CT_TYPE:
|
||||
case VARDECL_LOCAL_CT:
|
||||
case VARDECL_PARAM_CT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
return expr_list_is_constant_eval(expr->expression_list, eval_kind);
|
||||
case EXPR_FAILABLE:
|
||||
@@ -358,10 +370,32 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind)
|
||||
if (expr->slice_expr.end && !expr_is_constant_eval(expr->slice_expr.end, CONSTANT_EVAL_FOLDABLE)) return false;
|
||||
return expr_is_constant_eval(expr->slice_expr.expr, eval_kind);
|
||||
case EXPR_SUBSCRIPT:
|
||||
case EXPR_SUBSCRIPT_ADDR:
|
||||
if (!expr_is_constant_eval(expr->subscript_expr.index, eval_kind)) return false;
|
||||
expr = expr->subscript_expr.expr;
|
||||
goto RETRY;
|
||||
case EXPR_SUBSCRIPT_ADDR:
|
||||
if (!expr_is_constant_eval(expr->subscript_expr.index, eval_kind)) return false;
|
||||
expr = expr->subscript_expr.expr;
|
||||
if (expr->expr_kind == EXPR_IDENTIFIER)
|
||||
{
|
||||
Decl *decl = expr->identifier_expr.decl;
|
||||
if (decl->decl_kind == DECL_VAR)
|
||||
{
|
||||
switch (decl->var.kind)
|
||||
{
|
||||
case VARDECL_CONST:
|
||||
case VARDECL_GLOBAL:
|
||||
break;
|
||||
case VARDECL_LOCAL:
|
||||
if (decl->var.is_static) break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return eval_kind != CONSTANT_EVAL_FOLDABLE;
|
||||
}
|
||||
}
|
||||
goto RETRY;
|
||||
|
||||
case EXPR_TERNARY:
|
||||
assert(!expr_is_constant_eval(expr->ternary_expr.cond, eval_kind));
|
||||
return false;
|
||||
|
||||
23
test/test_suite/compile_time/compile_time_array_ref.c3t
Normal file
23
test/test_suite/compile_time/compile_time_array_ref.c3t
Normal file
@@ -0,0 +1,23 @@
|
||||
// #target: x64-darwin
|
||||
module foo;
|
||||
|
||||
char[8192] stack;
|
||||
char* x = &stack[0] + 1000;
|
||||
|
||||
fn void test()
|
||||
{
|
||||
static char[2] y;
|
||||
static char* z = &y[1];
|
||||
}
|
||||
|
||||
/* #expect: foo.ll
|
||||
|
||||
@foo.stack = global [8192 x i8] zeroinitializer, align 16
|
||||
@foo.x = global i8* getelementptr inbounds ([8192 x i8], [8192 x i8]* @foo.stack, i64 0, i64 1000), align 8
|
||||
@test.y = hidden global [2 x i8] zeroinitializer, align 1
|
||||
@test.z = hidden global i8* getelementptr inbounds ([2 x i8], [2 x i8]* @test.y, i64 0, i64 1), align 8
|
||||
; Function Attrs: nounwind
|
||||
define void @foo.test() #0 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
Reference in New Issue
Block a user