aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2019-02-17 15:17:01 -0800
committerMichael Forney <mforney@mforney.org>2019-02-17 19:04:25 -0800
commit132e0c466c4198445f8e327c291ab38fe79f6032 (patch)
treeb9708ed3ca0f1f243054a9296031e7867a99b11f
parent0beaca9548a524557d33d3c618e5ec586cf489d3 (diff)
downloadcproc-132e0c466c4198445f8e327c291ab38fe79f6032.tar.xz
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.
-rw-r--r--expr.c11
-rw-r--r--tests/sizeof-compound-literal.c1
-rw-r--r--tests/sizeof-compound-literal.qbe1
-rw-r--r--tests/sizeof-postfix.c4
-rw-r--r--tests/sizeof-postfix.qbe8
5 files changed, 23 insertions, 2 deletions
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 }