diff options
-rw-r--r-- | expr.c | 4 | ||||
-rw-r--r-- | tests/lvalue-conversion.c | 6 | ||||
-rw-r--r-- | tests/lvalue-conversion.qbe | 14 | ||||
-rw-r--r-- | type.c | 2 |
4 files changed, 26 insertions, 0 deletions
@@ -473,6 +473,7 @@ postfixexpr(struct scope *s, struct expression *r) if (!p && !t->func.isvararg && t->func.paraminfo) error(&tok.loc, "too many arguments for function call"); *end = assignexpr(s); + lvalueconvert(*end); if (!t->func.isprototype || (t->func.isvararg && !p)) *end = exprconvert(*end, typeargpromote((*end)->type)); else @@ -585,17 +586,20 @@ unaryexpr(struct scope *s) case TADD: next(); e = castexpr(s); + lvalueconvert(e); e = exprconvert(e, typeintpromote(e->type)); break; case TSUB: next(); e = castexpr(s); + lvalueconvert(e); e = exprconvert(e, typeintpromote(e->type)); e = mkbinaryexpr(&tok.loc, TSUB, mkconstexpr(&typeint, 0), e); break; case TBNOT: next(); e = castexpr(s); + lvalueconvert(e); e = exprconvert(e, typeintpromote(e->type)); e = mkbinaryexpr(&tok.loc, TXOR, e, mkconstexpr(e->type, -1)); break; diff --git a/tests/lvalue-conversion.c b/tests/lvalue-conversion.c new file mode 100644 index 0000000..6bbc326 --- /dev/null +++ b/tests/lvalue-conversion.c @@ -0,0 +1,6 @@ +void g(); +void f(void) { + static const unsigned char c = 0; + g(c); + g(~c); +} diff --git a/tests/lvalue-conversion.qbe b/tests/lvalue-conversion.qbe new file mode 100644 index 0000000..ac5fbc3 --- /dev/null +++ b/tests/lvalue-conversion.qbe @@ -0,0 +1,14 @@ +data $.Lc.2 = align 1 { b 0, } +export +function $f() { +@start.1 +@body.2 + %.1 =w loadub $.Lc.2 + %.2 =w extub %.1 + call $g(w %.2) + %.3 =w loadub $.Lc.2 + %.4 =w extub %.3 + %.5 =w xor %.4, 18446744073709551615 + call $g(w %.5) + ret +} @@ -237,6 +237,7 @@ typeunqual(struct type *t, enum typequalifier *tq) struct type * typeintpromote(struct type *t) { + assert(t->kind != TYPEQUALIFIED); if (typeprop(t) & PROPINT && typerank(t) <= typerank(&typeint)) return t->size < typeint.size || t->basic.issigned ? &typeint : &typeuint; return t; @@ -245,6 +246,7 @@ typeintpromote(struct type *t) struct type * typeargpromote(struct type *t) { + assert(t->kind != TYPEQUALIFIED); if (t == &typefloat) return &typedouble; return typeintpromote(t); |