summaryrefslogtreecommitdiff
path: root/sys/src/cmd/cc
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org'>2020-02-27 15:09:10 -0500
committerOri Bernstein <ori@eigenstate.org'>2020-02-27 15:09:10 -0500
commit3df95385bcc5294a212534d0991f1ffef1454aca (patch)
tree8dde027184ce7f6a384931b0d922ccf8b5a963a2 /sys/src/cmd/cc
parent0f9666ae162f7c330850fa513e8ed3bd5fd995df (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.h1
-rw-r--r--sys/src/cmd/cc/com.c6
-rw-r--r--sys/src/cmd/cc/sub.c15
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;