From 8e47cf45dfed44627fa6f73f8734f2149c661044 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Fri, 31 Jan 2020 13:41:04 -0800 Subject: eval: Allow casting address constants to integer types in constant expressions --- eval.c | 11 +++++++++-- test/initializer-pointer-int-cast.c | 2 ++ test/initializer-pointer-int-cast.qbe | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 test/initializer-pointer-int-cast.c create mode 100644 test/initializer-pointer-int-cast.qbe diff --git a/eval.c b/eval.c index c4974b8..48053c4 100644 --- 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 new file mode 100644 index 0000000..75963b2 --- /dev/null +++ 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 new file mode 100644 index 0000000..a996882 --- /dev/null +++ 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 } -- cgit v1.2.3