scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit bcb57e195084cc997b8540b032c37c41d994d3b0
parent 11c86352844f5300d504753a5e0019e24a8a0eec
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri,  8 Jan 2016 17:47:30 +0100

Fix ternary operator and null pointer constants

Only null pointer constants are converted, no
void * pointers.

Diffstat:
Mcc1/expr.c | 30+++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/cc1/expr.c b/cc1/expr.c @@ -127,6 +127,14 @@ set_p1_p2: *p2 = np2; } +static int +isnull(Node *np) +{ + if (!np->constant || np->type != pvoidtype) + return 0; + return cmpnode(np, 0); +} + static Node * chkternary(Node *yes, Node *no) { @@ -146,18 +154,26 @@ chkternary(Node *yes, Node *no) } else if (yes->type->op != PTR && no->type->op != PTR) { goto wrong_type; } else { + /* convert integer 0 to NULL */ if (yes->type->integer && cmpnode(yes, 0)) - yes = convert(yes, no->type, 0); + yes = convert(yes, pvoidtype, 0); if (no->type->integer && cmpnode(no, 0)) - no = convert(no, yes->type, 0); - + no = convert(no, pvoidtype, 0); + /* + * At this point the type of both should be + * a pointer to something, or we have don't + * compatible types + */ if (yes->type->op != PTR || no->type->op != PTR) goto wrong_type; - - if (yes->type == pvoidtype) + /* + * If we have a null pointer constant then + * convert to the another type + */ + if (isnull(yes)) yes = convert(yes, no->type, 0); - if (no->type == pvoidtype) - no = convert(no, no->type, 0); + if (isnull(no)) + no = convert(no, yes->type, 0); if (!eqtype(yes->type, no->type)) goto wrong_type;