From 0bae34bee3a6a8a87da946aceeaf385dcc99ea27 Mon Sep 17 00:00:00 2001 From: amy Date: Sun, 26 Oct 2025 22:40:30 +0000 Subject: [PATCH 1/7] fix runtime --- Content.Tests/DMProject/Tests/Operators/Division.dm | 2 +- Content.Tests/DMProject/Tests/Operators/valid_and_null.dm | 2 +- OpenDreamRuntime/Procs/DMOpcodeHandlers.cs | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Content.Tests/DMProject/Tests/Operators/Division.dm b/Content.Tests/DMProject/Tests/Operators/Division.dm index 0250ae9dcd..cd3b704284 100644 --- a/Content.Tests/DMProject/Tests/Operators/Division.dm +++ b/Content.Tests/DMProject/Tests/Operators/Division.dm @@ -7,7 +7,7 @@ var/list/expected = list( 1, "Error", - 10, + "Error", "Error", "Error", // index 5 "Error", diff --git a/Content.Tests/DMProject/Tests/Operators/valid_and_null.dm b/Content.Tests/DMProject/Tests/Operators/valid_and_null.dm index d7655bda0c..2403efa2e2 100644 --- a/Content.Tests/DMProject/Tests/Operators/valid_and_null.dm +++ b/Content.Tests/DMProject/Tests/Operators/valid_and_null.dm @@ -57,7 +57,7 @@ ASSERT(C(4) / C(2) == C(2)) ASSERT(C(null) / C(2) == C(0)) - ASSERT(C(2) / C(null) == C(2)) + //ASSERT(C(2) / C(null) == C(2)) // Runtime error ASSERT(C(null) / C(null) == C(0)) ASSERT(C(4) % C(3) == C(1)) diff --git a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs index 51f8143b0f..f50d0a7d1c 100644 --- a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs +++ b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs @@ -1143,8 +1143,7 @@ public static ProcStatus Divide(DMProcState state) { state.Push(new DreamValue(0)); break; case DreamValue.DreamValueType.Float when second.IsNull: - state.Push(new DreamValue(first.MustGetValueAsFloat())); - break; + throw new Exception("Division by null"); case DreamValue.DreamValueType.Float when second.Type == DreamValue.DreamValueType.Float: var secondFloat = second.MustGetValueAsFloat(); if (secondFloat == 0) { From 591db0679d6eb1e6d5d4f68d5aa1e8d4f57ba33f Mon Sep 17 00:00:00 2001 From: amy Date: Sun, 26 Oct 2025 23:04:48 +0000 Subject: [PATCH 2/7] ew I touched the compiler --- DMCompiler/DM/Expressions/Binary.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DMCompiler/DM/Expressions/Binary.cs b/DMCompiler/DM/Expressions/Binary.cs index c05a7d3d4c..dc09a92fa3 100644 --- a/DMCompiler/DM/Expressions/Binary.cs +++ b/DMCompiler/DM/Expressions/Binary.cs @@ -116,6 +116,8 @@ public override bool TryAsConstant(DMCompiler compiler, [NotNullWhen(true)] out if (lhs is Number lhsNum && rhs is Number rhsNum) { constant = new Number(Location, lhsNum.Value / rhsNum.Value); + } else if (lhs is Number lhsNumNull && rhs is Null) { + constant = new Number(Location, lhsNumNull.Value); } else { constant = null; return false; From 06292069c1cd19325dcd548178ea32049f2cb88a Mon Sep 17 00:00:00 2001 From: amy Date: Thu, 6 Nov 2025 22:59:44 +0000 Subject: [PATCH 3/7] all errors --- .../DMProject/Tests/Operators/valid_and_null_const.dm | 4 ++-- DMCompiler/DM/Expressions/Binary.cs | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Content.Tests/DMProject/Tests/Operators/valid_and_null_const.dm b/Content.Tests/DMProject/Tests/Operators/valid_and_null_const.dm index ff53488055..1e3fda8c7c 100644 --- a/Content.Tests/DMProject/Tests/Operators/valid_and_null_const.dm +++ b/Content.Tests/DMProject/Tests/Operators/valid_and_null_const.dm @@ -30,8 +30,8 @@ ASSERT(C(4) / C(2) == C(2)) ASSERT(C(null) / C(2) == C(0)) - ASSERT(C(2) / C(null) == C(2)) - ASSERT(C(null) / C(null) == C(0)) + //ASSERT(C(2) / C(null) == C(2)) //compile time error + //ASSERT(C(null) / C(null) == C(0)) ASSERT(C(4) % C(3) == C(1)) ASSERT(C(null) % C(3) == C(0)) diff --git a/DMCompiler/DM/Expressions/Binary.cs b/DMCompiler/DM/Expressions/Binary.cs index dc09a92fa3..ad2958ef29 100644 --- a/DMCompiler/DM/Expressions/Binary.cs +++ b/DMCompiler/DM/Expressions/Binary.cs @@ -116,8 +116,10 @@ public override bool TryAsConstant(DMCompiler compiler, [NotNullWhen(true)] out if (lhs is Number lhsNum && rhs is Number rhsNum) { constant = new Number(Location, lhsNum.Value / rhsNum.Value); - } else if (lhs is Number lhsNumNull && rhs is Null) { - constant = new Number(Location, lhsNumNull.Value); + } else if (rhs is Null) { + compiler.ForcedError(Location, "Division by null is invalid!"); + constant = null; + return false; } else { constant = null; return false; From 5aff10a392be3de25c6a82aacaa669d471c379c0 Mon Sep 17 00:00:00 2001 From: amy Date: Thu, 6 Nov 2025 23:08:09 +0000 Subject: [PATCH 4/7] add a proper error and test --- Content.Tests/DMProject/Tests/Operators/div_by_null.dm | 3 +++ DMCompiler/Compiler/CompilerError.cs | 2 ++ DMCompiler/DM/Expressions/Binary.cs | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Content.Tests/DMProject/Tests/Operators/div_by_null.dm diff --git a/Content.Tests/DMProject/Tests/Operators/div_by_null.dm b/Content.Tests/DMProject/Tests/Operators/div_by_null.dm new file mode 100644 index 0000000000..639ec93158 --- /dev/null +++ b/Content.Tests/DMProject/Tests/Operators/div_by_null.dm @@ -0,0 +1,3 @@ +// COMPILE ERROR OD0502 +/proc/RunTest + var/test = 10/null \ No newline at end of file diff --git a/DMCompiler/Compiler/CompilerError.cs b/DMCompiler/Compiler/CompilerError.cs index 223f02caa0..80680f026f 100644 --- a/DMCompiler/Compiler/CompilerError.cs +++ b/DMCompiler/Compiler/CompilerError.cs @@ -27,6 +27,7 @@ public enum WarningCode { IAmATeaPot = 418, // TODO: Implement the HTCPC protocol for OD HardConstContext = 500, WriteToConstant = 501, + DivideByNull = 502, InvalidInclusion = 900, // 1000 - 1999 are reserved for preprocessor configuration. @@ -126,6 +127,7 @@ public struct CompilerEmission { {WarningCode.IAmATeaPot, ErrorLevel.Error}, {WarningCode.HardConstContext, ErrorLevel.Error}, {WarningCode.WriteToConstant, ErrorLevel.Error}, + {WarningCode.DivideByNull, ErrorLevel.Error}, {WarningCode.InvalidInclusion, ErrorLevel.Error}, //1000-1999 diff --git a/DMCompiler/DM/Expressions/Binary.cs b/DMCompiler/DM/Expressions/Binary.cs index ad2958ef29..82cef7637a 100644 --- a/DMCompiler/DM/Expressions/Binary.cs +++ b/DMCompiler/DM/Expressions/Binary.cs @@ -117,7 +117,7 @@ public override bool TryAsConstant(DMCompiler compiler, [NotNullWhen(true)] out if (lhs is Number lhsNum && rhs is Number rhsNum) { constant = new Number(Location, lhsNum.Value / rhsNum.Value); } else if (rhs is Null) { - compiler.ForcedError(Location, "Division by null is invalid!"); + compiler.Emit(WarningCode.DivideByNull, Location, "Division by null is invalid!"); constant = null; return false; } else { From a8768bd075de8d064fbcb7db0501e42d8f4e062b Mon Sep 17 00:00:00 2001 From: Amy <3855802+amylizzle@users.noreply.github.com> Date: Sat, 15 Nov 2025 10:17:14 +0000 Subject: [PATCH 5/7] Update OpenDreamRuntime/Procs/DMOpcodeHandlers.cs Co-authored-by: wixoa --- OpenDreamRuntime/Procs/DMOpcodeHandlers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs index f50d0a7d1c..86060d7e32 100644 --- a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs +++ b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs @@ -1143,7 +1143,7 @@ public static ProcStatus Divide(DMProcState state) { state.Push(new DreamValue(0)); break; case DreamValue.DreamValueType.Float when second.IsNull: - throw new Exception("Division by null"); + throw new Exception($"Attempted to divide {first} by null"); case DreamValue.DreamValueType.Float when second.Type == DreamValue.DreamValueType.Float: var secondFloat = second.MustGetValueAsFloat(); if (secondFloat == 0) { From 959d46d8ef6ba51ab999a4877129899427980b78 Mon Sep 17 00:00:00 2001 From: wixoaGit Date: Mon, 8 Dec 2025 19:46:30 -0500 Subject: [PATCH 6/7] Remove `WarningCode.DivideByNull` --- DMCompiler/Compiler/CompilerError.cs | 2 -- DMCompiler/DM/Expressions/Binary.cs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/DMCompiler/Compiler/CompilerError.cs b/DMCompiler/Compiler/CompilerError.cs index 80680f026f..223f02caa0 100644 --- a/DMCompiler/Compiler/CompilerError.cs +++ b/DMCompiler/Compiler/CompilerError.cs @@ -27,7 +27,6 @@ public enum WarningCode { IAmATeaPot = 418, // TODO: Implement the HTCPC protocol for OD HardConstContext = 500, WriteToConstant = 501, - DivideByNull = 502, InvalidInclusion = 900, // 1000 - 1999 are reserved for preprocessor configuration. @@ -127,7 +126,6 @@ public struct CompilerEmission { {WarningCode.IAmATeaPot, ErrorLevel.Error}, {WarningCode.HardConstContext, ErrorLevel.Error}, {WarningCode.WriteToConstant, ErrorLevel.Error}, - {WarningCode.DivideByNull, ErrorLevel.Error}, {WarningCode.InvalidInclusion, ErrorLevel.Error}, //1000-1999 diff --git a/DMCompiler/DM/Expressions/Binary.cs b/DMCompiler/DM/Expressions/Binary.cs index 82cef7637a..0869d0d357 100644 --- a/DMCompiler/DM/Expressions/Binary.cs +++ b/DMCompiler/DM/Expressions/Binary.cs @@ -117,7 +117,7 @@ public override bool TryAsConstant(DMCompiler compiler, [NotNullWhen(true)] out if (lhs is Number lhsNum && rhs is Number rhsNum) { constant = new Number(Location, lhsNum.Value / rhsNum.Value); } else if (rhs is Null) { - compiler.Emit(WarningCode.DivideByNull, Location, "Division by null is invalid!"); + compiler.Emit(WarningCode.BadExpression, Location, "Division by null is invalid"); constant = null; return false; } else { From 28f99de4ce46b05ad28d070ab061e7ecc62df546 Mon Sep 17 00:00:00 2001 From: wixoa Date: Mon, 8 Dec 2025 19:48:24 -0500 Subject: [PATCH 7/7] Update Content.Tests/DMProject/Tests/Operators/div_by_null.dm --- Content.Tests/DMProject/Tests/Operators/div_by_null.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Tests/DMProject/Tests/Operators/div_by_null.dm b/Content.Tests/DMProject/Tests/Operators/div_by_null.dm index 639ec93158..dca5ec8a1a 100644 --- a/Content.Tests/DMProject/Tests/Operators/div_by_null.dm +++ b/Content.Tests/DMProject/Tests/Operators/div_by_null.dm @@ -1,3 +1,3 @@ -// COMPILE ERROR OD0502 +// COMPILE ERROR OD0011 /proc/RunTest var/test = 10/null \ No newline at end of file