diff options
author | Ori Bernstein <ori@eigenstate.org'> | 2020-02-27 15:09:10 -0500 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org'> | 2020-02-27 15:09:10 -0500 |
commit | 3df95385bcc5294a212534d0991f1ffef1454aca (patch) | |
tree | 8dde027184ce7f6a384931b0d922ccf8b5a963a2 /sys/src/cmd/cc | |
parent | 0f9666ae162f7c330850fa513e8ed3bd5fd995df (diff) |
fix special case for null pointer constants in cond expressions
Section 6.5.15 of the C99 spec requires that if
one argument of a ?: expression is a null pointer
constant, and the other has a pointer type T*, then
the type of the expression is T*.
We were attempting to follow this rule, however,
we only handled literal expressions when checking
for null pointers.
This change looks through casts, so 'nil' and 'NULL',
and their expansion '(void*)0' are all detected as
null pointer constants.
Diffstat (limited to 'sys/src/cmd/cc')
-rw-r--r-- | sys/src/cmd/cc/cc.h | 1 | ||||
-rw-r--r-- | sys/src/cmd/cc/com.c | 6 | ||||
-rw-r--r-- | sys/src/cmd/cc/sub.c | 15 |
3 files changed, 20 insertions, 2 deletions
diff --git a/sys/src/cmd/cc/cc.h b/sys/src/cmd/cc/cc.h index 87aceb598..f22cad7e3 100644 --- a/sys/src/cmd/cc/cc.h +++ b/sys/src/cmd/cc/cc.h @@ -691,6 +691,7 @@ Type* copytyp(Type*); void typeext(Type*, Node*); void typeext1(Type*, Node*); int side(Node*); +int zpconst(Node*); int vconst(Node*); int log2(uvlong); int vlog(Node*); diff --git a/sys/src/cmd/cc/com.c b/sys/src/cmd/cc/com.c index 418bbae26..49fcefd1a 100644 --- a/sys/src/cmd/cc/com.c +++ b/sys/src/cmd/cc/com.c @@ -341,11 +341,13 @@ tcomo(Node *n, int f) o |= tcom(r->left); if(o | tcom(r->right)) goto bad; - if(r->right->type->etype == TIND && vconst(r->left) == 0) { + if(r->right->type->etype == TIND && zpconst(r->left)) { + r->type = r->right->type; r->left->type = r->right->type; r->left->vconst = 0; } - if(r->left->type->etype == TIND && vconst(r->right) == 0) { + if(r->left->type->etype == TIND && zpconst(r->right)) { + r->type = r->left->type; r->right->type = r->left->type; r->right->vconst = 0; } diff --git a/sys/src/cmd/cc/sub.c b/sys/src/cmd/cc/sub.c index ee4ab07ce..9be762a0c 100644 --- a/sys/src/cmd/cc/sub.c +++ b/sys/src/cmd/cc/sub.c @@ -1026,6 +1026,21 @@ loop: } int +zpconst(Node *n) +{ + while(n->op == OCAST){ + if(n->type == T) + break; + if(n->type->etype != TIND) + break; + if(n->type->link->etype != TVOID) + break; + n = n->left; + } + return vconst(n) == 0; +} + +int vconst(Node *n) { int i; |