scc

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

commit 0681c99653ef080b235082875a2b6e5490ec4ff8
parent 27b3c745a4bbdf3c0e6ed5d482b2fd673ba0fd83
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 21 Apr 2014 07:04:14 +0200

Allow comparision between 0 and pointers

This comparision is allowed in ANSI standard and it is necessary
in expressions where pointers act as conditions.

Diffstat:
Mcc1.h | 2+-
Mexpr.c | 49+++++++++++++++++++++++++++----------------------
2 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/cc1.h b/cc1.h @@ -12,6 +12,7 @@ struct user_opt { unsigned char npromote; unsigned char useless; unsigned char charsign; + unsigned char pcompare; }; extern struct user_opt options; @@ -237,7 +238,6 @@ extern Node #define SYM(s) ((union unode) {.sym = s}) #define OP(s) ((union unode) {.op = s}) #define TYP(s) ((union unode) {.type = s}) -#define ISNODESYM(n) ((n)->code == emitsym) #define ISNODEBIN(n) ((n)->code == emitbin) #define ISNODECMP(n) (ISNODEBIN(n) && (n)->u.op & 0x40) diff --git a/expr.c b/expr.c @@ -175,42 +175,47 @@ arithmetic(char op, Node *np1, Node *np2) } static Node * -compare(char op, Node *np1, Node *np2) -{ - Type *tp1, *tp2; - uint8_t t1, t2; +pcompare(char op, Node *np1, Node *np2) +{ + if (np2->typeop == INT && np2->b.symbol && np2->u.sym->u.i == 0) { + np2 = castcode(np2, pvoidtype); + } else if (np2->typeop != PTR) { + error("incompatibles type in comparision"); + } else { + warn(options.pcompare, + "comparision between different pointer types"); + } - np1 = promote(np1); - np2 = promote(np2); - GETBTYPE(np1, tp1, t1); - GETBTYPE(np2, tp2, t2); + return bincode(op, inttype, np1, np2); +} - switch (t1) { +static Node * +compare(char op, Node *np1, Node *np2) +{ + switch (np1->typeop) { case INT: case FLOAT: - switch (t2) { + switch (np1->typeop) { case INT: case FLOAT: - if (tp1 != tp2) - typeconv(&np1, &np2); + typeconv(&np1, &np2); break; + case ARY: case FTN: + np2 = addr2ptr(np2); + case PTR: + return pcompare(op, np2, np1); default: - goto incompatibles; + goto nocompat; } break; case ARY: case FTN: np1 = addr2ptr(np1); - tp1 = UNQUAL(np1->type); case PTR: - if (tp1 != tp2) - goto incompatibles; - break; + return pcompare(op, np1, np2); default: - goto incompatibles; + nocompat: + error("incompatibles type in comparision"); } return bincode(op, inttype, np1, np2); - -incompatibles: - error("incompatibles type in comparision"); } static Node * @@ -451,7 +456,7 @@ unary(void) op = OADDR; if (!np->b.lvalue) goto no_lvalue; - if (ISNODESYM(np) && np->u.sym->s.isregister) + if (np->b.symbol && np->u.sym->s.isregister) goto reg_address; tp = mktype(tp, PTR, NULL, 0); break;