From 132e0c466c4198445f8e327c291ab38fe79f6032 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Sun, 17 Feb 2019 15:17:01 -0800 Subject: Fix sizeof with unparenthesized postfix or compound literal expression Determining whether it is a typename or unparenthesized expression requires consuming the '(', so we need to call postfixexpr/parseinit ourselves. --- expr.c | 11 +++++++++-- tests/sizeof-compound-literal.c | 1 + tests/sizeof-compound-literal.qbe | 1 + tests/sizeof-postfix.c | 4 ++++ tests/sizeof-postfix.qbe | 8 ++++++++ 5 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/sizeof-compound-literal.c create mode 100644 tests/sizeof-compound-literal.qbe create mode 100644 tests/sizeof-postfix.c create mode 100644 tests/sizeof-postfix.qbe diff --git a/expr.c b/expr.c index 4cc45b4..1c0f4ff 100644 --- a/expr.c +++ b/expr.c @@ -603,13 +603,20 @@ unaryexpr(struct scope *s) next(); if (consume(TLPAREN)) { t = typename(s); - if (!t) { + if (t) { + expect(TRPAREN, "after type name"); + /* might be part of a compound literal */ + if (op == TSIZEOF && tok.kind == TLBRACE) + parseinit(s, t); + } else { e = expr(s); + expect(TRPAREN, "after expression"); + if (op == TSIZEOF) + e = postfixexpr(s, e); if (e->flags & EXPRFLAG_DECAYED) e = e->unary.base; t = e->type; } - expect(TRPAREN, "after type name"); } else if (op == TSIZEOF) { e = unaryexpr(s); if (e->flags & EXPRFLAG_DECAYED) diff --git a/tests/sizeof-compound-literal.c b/tests/sizeof-compound-literal.c new file mode 100644 index 0000000..b25d06a --- /dev/null +++ b/tests/sizeof-compound-literal.c @@ -0,0 +1 @@ +int x = sizeof (int){1}; diff --git a/tests/sizeof-compound-literal.qbe b/tests/sizeof-compound-literal.qbe new file mode 100644 index 0000000..23be3d8 --- /dev/null +++ b/tests/sizeof-compound-literal.qbe @@ -0,0 +1 @@ +export data $x = align 4 { w 4, } diff --git a/tests/sizeof-postfix.c b/tests/sizeof-postfix.c new file mode 100644 index 0000000..9062517 --- /dev/null +++ b/tests/sizeof-postfix.c @@ -0,0 +1,4 @@ +int x; +int f(void) { + return sizeof (x)++; +} diff --git a/tests/sizeof-postfix.qbe b/tests/sizeof-postfix.qbe new file mode 100644 index 0000000..d9eedd8 --- /dev/null +++ b/tests/sizeof-postfix.qbe @@ -0,0 +1,8 @@ +export +function w $f() { +@start.1 +@body.2 + %.1 =w copy 4 + ret %.1 +} +export data $x = align 4 { z 4 } -- cgit v1.2.3