ref: bcb57e195084cc997b8540b032c37c41d994d3b0
parent: 11c86352844f5300d504753a5e0019e24a8a0eec
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Jan 8 12:47:30 EST 2016
Fix ternary operator and null pointer constants Only null pointer constants are converted, no void * pointers.
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -127,6 +127,14 @@
*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 @@
} 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;