summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-07-01 15:04:25 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2023-07-01 15:48:37 +0200
commita44fb702058974cc7592e8f8a81260f6ab35bece (patch)
tree03989d4a0d612c09ee207fef47fc0e697cc7239e
parent31012ea997656061d07790de5a07b4e629211cd1 (diff)
d: Fix ICE in setValue, at d/dmd/dinterpret.c:7013
Backports ICE fix from upstream. When casting null to integer or real, instead of painting the type on the NullExp, we emplace an IntegerExp/RealExp with the value zero. Same as when casting from NullExp to bool. Reviewed-on: https://github.com/dlang/dmd/pull/13172 PR d/110511 gcc/d/ChangeLog: * dmd/dinterpret.c (Interpreter::visit (CastExp *)): Handle casting null to int or float. gcc/testsuite/ChangeLog: * gdc.test/compilable/test21794.d: New test. (cherry picked from commit 066385c918485d4cef5c243d3b0691193df382de)
-rw-r--r--gcc/d/dmd/dinterpret.c12
-rw-r--r--gcc/testsuite/gdc.test/compilable/test21794.d52
2 files changed, 63 insertions, 1 deletions
diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c
index 214a73cd8bb..51b4a7d1c48 100644
--- a/gcc/d/dmd/dinterpret.c
+++ b/gcc/d/dmd/dinterpret.c
@@ -5843,12 +5843,22 @@ public:
}
if (e->to->ty == Tsarray)
e1 = resolveSlice(e1);
- if (e->to->toBasetype()->ty == Tbool && e1->type->ty == Tpointer)
+ Type *tobt = e->to->toBasetype();
+ if (tobt->ty == Tbool && e1->type->ty == Tpointer)
{
new(pue) IntegerExp(e->loc, e1->op != TOKnull, e->to);
result = pue->exp();
return;
}
+ else if (tobt->isTypeBasic() && e1->op == TOKnull)
+ {
+ if (tobt->isintegral())
+ new(pue) IntegerExp(e->loc, 0, e->to);
+ else if (tobt->isreal())
+ new(pue) RealExp(e->loc, CTFloat::zero, e->to);
+ result = pue->exp();
+ return;
+ }
result = ctfeCast(pue, e->loc, e->type, e->to, e1);
}
diff --git a/gcc/testsuite/gdc.test/compilable/test21794.d b/gcc/testsuite/gdc.test/compilable/test21794.d
new file mode 100644
index 00000000000..68e504bce56
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test21794.d
@@ -0,0 +1,52 @@
+// https://issues.dlang.org/show_bug.cgi?id=21794
+/*
+TEST_OUTPUT:
+---
+0
+0u
+0L
+0LU
+0.0F
+0.0
+0.0L
+---
+*/
+
+bool fun(void* p) {
+ const x = cast(ulong)p;
+ return 1;
+}
+
+static assert(fun(null));
+
+T fun2(T)(void* p) {
+ const x = cast(T)p;
+ return x;
+}
+
+// These were an error before, they were returning a NullExp instead of IntegerExp/RealExp
+
+static assert(fun2!int(null) == 0);
+static assert(fun2!uint(null) == 0);
+static assert(fun2!long(null) == 0);
+static assert(fun2!ulong(null) == 0);
+static assert(fun2!float(null) == 0);
+static assert(fun2!double(null) == 0);
+static assert(fun2!real(null) == 0);
+
+// These were printing 'null' instead of the corresponding number
+
+const i = cast(int)null;
+const ui = cast(uint)null;
+const l = cast(long)null;
+const ul = cast(ulong)null;
+const f = cast(float)null;
+const d = cast(double)null;
+const r = cast(real)null;
+pragma(msg, i);
+pragma(msg, ui);
+pragma(msg, l);
+pragma(msg, ul);
+pragma(msg, f);
+pragma(msg, d);
+pragma(msg, r);