Fixed issue where &foo[1] was not considered a constant when foo is a global.

This commit is contained in:
Christoffer Lerno
2021-12-06 23:13:48 +01:00
parent 49efa4fafc
commit bbda3a679f
2 changed files with 59 additions and 2 deletions

View File

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

View 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
}