cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit 8e47cf45dfed44627fa6f73f8734f2149c661044
parent 41e862a6a2b193b6bab86bc29e2db3d42baa828a
Author: Michael Forney <mforney@mforney.org>
Date:   Fri, 31 Jan 2020 13:41:04 -0800

eval: Allow casting address constants to integer types in constant expressions

Diffstat:
Meval.c | 11+++++++++--
Atest/initializer-pointer-int-cast.c | 2++
Atest/initializer-pointer-int-cast.qbe | 2++
3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/eval.c b/eval.c @@ -137,8 +137,15 @@ eval(struct expr *expr, enum evalkind kind) else expr->constant = l->constant; cast(expr); - } else if (l->type->kind == TYPEPOINTER && expr->type->kind == TYPEPOINTER) { - expr = l; + } else if (l->type->kind == TYPEPOINTER) { + /* + A cast from a pointer to integer is not a valid constant + expression, but C11 allows implementations to recognize + other forms of constant expressions (6.6p10), and some + programs expect this functionality. + */ + if (expr->type->kind == TYPEPOINTER || expr->type->prop & PROPINT && expr->type->size == typelong.size) + expr = l; } break; case EXPRBINARY: diff --git a/test/initializer-pointer-int-cast.c b/test/initializer-pointer-int-cast.c @@ -0,0 +1,2 @@ +int x; +long p = (long)&x; diff --git a/test/initializer-pointer-int-cast.qbe b/test/initializer-pointer-int-cast.qbe @@ -0,0 +1,2 @@ +export data $p = align 8 { l $x, } +export data $x = align 4 { z 4 }