From 85efc53cc18afd9c8b1d78f13129a1da6908276f Mon Sep 17 00:00:00 2001 From: ike709 Date: Fri, 6 Dec 2024 20:17:45 -0600 Subject: [PATCH 1/5] Compile error when outputting to const vars in `for()` loops --- .../Statements/For/reuse_decl_const.dm | 2 +- DMCompiler/DM/Builders/DMProcBuilder.cs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) rename Content.Tests/DMProject/{Broken Tests => Tests}/Statements/For/reuse_decl_const.dm (89%) diff --git a/Content.Tests/DMProject/Broken Tests/Statements/For/reuse_decl_const.dm b/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const.dm similarity index 89% rename from Content.Tests/DMProject/Broken Tests/Statements/For/reuse_decl_const.dm rename to Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const.dm index 4b404cb05c..2f39dc4f12 100644 --- a/Content.Tests/DMProject/Broken Tests/Statements/For/reuse_decl_const.dm +++ b/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const.dm @@ -1,4 +1,4 @@ -// COMPILE ERROR +// COMPILE ERROR OD0501 /datum var/const/idx = 0 diff --git a/DMCompiler/DM/Builders/DMProcBuilder.cs b/DMCompiler/DM/Builders/DMProcBuilder.cs index e4fcd52a2d..e0162c6e04 100644 --- a/DMCompiler/DM/Builders/DMProcBuilder.cs +++ b/DMCompiler/DM/Builders/DMProcBuilder.cs @@ -487,6 +487,11 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) { outputExpr = exprRange.Value; } + if (outputExpr is DMASTIdentifier identifier && + dmObject.GetVariable(identifier.Identifier) is { IsConst: true }) { + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); + } + var outputVar = _exprBuilder.Create(outputExpr); var start = _exprBuilder.Create(exprRange.StartRange); From 93d52ba15442f65abbddaf93158a210e5f0e9fa4 Mon Sep 17 00:00:00 2001 From: ike709 Date: Sun, 8 Dec 2024 09:41:37 -0600 Subject: [PATCH 2/5] review --- .../Tests/Statements/For/reuse_decl_const2.dm | 18 ++++++++++++++++++ DMCompiler/DM/Builders/DMProcBuilder.cs | 14 ++++++++------ DMCompiler/DM/Expressions/LValue.cs | 1 + 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const2.dm diff --git a/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const2.dm b/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const2.dm new file mode 100644 index 0000000000..a8144a4359 --- /dev/null +++ b/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const2.dm @@ -0,0 +1,18 @@ +// COMPILE ERROR OD0501 + +/datum + var/const/idx = 0 + var/c = 0 + proc/do_loop() + for (idx in list(1,2,3)) + c += idx + +/proc/RunTest() + var/datum/d = new + d.do_loop() + + var/const/idx = 0 + var/c = 0 + for (idx in list(1,2,3)) + c += idx + diff --git a/DMCompiler/DM/Builders/DMProcBuilder.cs b/DMCompiler/DM/Builders/DMProcBuilder.cs index e0162c6e04..d3090527c2 100644 --- a/DMCompiler/DM/Builders/DMProcBuilder.cs +++ b/DMCompiler/DM/Builders/DMProcBuilder.cs @@ -487,13 +487,12 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) { outputExpr = exprRange.Value; } - if (outputExpr is DMASTIdentifier identifier && - dmObject.GetVariable(identifier.Identifier) is { IsConst: true }) { - compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); - } - var outputVar = _exprBuilder.Create(outputExpr); + if (outputVar is Local { LocalVar: DMProc.LocalConstVariable } or Field { IsConst: true }) { + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, $"Cannot change constant value"); + } + var start = _exprBuilder.Create(exprRange.StartRange); var end = _exprBuilder.Create(exprRange.EndRange); var step = exprRange.Step != null @@ -525,7 +524,10 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) { if (outputVar is Local outputLocal) { outputLocal.LocalVar.ExplicitValueType = statementFor.DMTypes; - } + if(outputLocal.LocalVar is DMProc.LocalConstVariable) + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, $"Cannot change constant value"); + } else if (outputVar is Field { IsConst: true }) + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); ProcessStatementForList(list, outputVar, statementFor.DMTypes, statementFor.Body); break; diff --git a/DMCompiler/DM/Expressions/LValue.cs b/DMCompiler/DM/Expressions/LValue.cs index a32902f4f9..d5fd05f468 100644 --- a/DMCompiler/DM/Expressions/LValue.cs +++ b/DMCompiler/DM/Expressions/LValue.cs @@ -122,6 +122,7 @@ public override void EmitPushInitial(ExpressionContext ctx) { // Identifier of field internal sealed class Field(Location location, DMVariable variable, DMComplexValueType valType) : LValue(location, variable.Type) { + public bool IsConst { get; } = variable.IsConst; public override DMComplexValueType ValType => valType; public override void EmitPushInitial(ExpressionContext ctx) { From 89ca9044eb067a3b5b2e68e104b571a1b219fdac Mon Sep 17 00:00:00 2001 From: ike709 Date: Sun, 8 Dec 2024 09:47:47 -0600 Subject: [PATCH 3/5] Update DMCompiler/DM/Builders/DMProcBuilder.cs --- DMCompiler/DM/Builders/DMProcBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DMCompiler/DM/Builders/DMProcBuilder.cs b/DMCompiler/DM/Builders/DMProcBuilder.cs index d3090527c2..0ea42ab26c 100644 --- a/DMCompiler/DM/Builders/DMProcBuilder.cs +++ b/DMCompiler/DM/Builders/DMProcBuilder.cs @@ -490,7 +490,7 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) { var outputVar = _exprBuilder.Create(outputExpr); if (outputVar is Local { LocalVar: DMProc.LocalConstVariable } or Field { IsConst: true }) { - compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, $"Cannot change constant value"); + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); } var start = _exprBuilder.Create(exprRange.StartRange); From 9818d4ba6349dd932c7355b9f9ea2eb1962a9d56 Mon Sep 17 00:00:00 2001 From: ike709 Date: Sun, 8 Dec 2024 09:47:51 -0600 Subject: [PATCH 4/5] Update DMCompiler/DM/Builders/DMProcBuilder.cs --- DMCompiler/DM/Builders/DMProcBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DMCompiler/DM/Builders/DMProcBuilder.cs b/DMCompiler/DM/Builders/DMProcBuilder.cs index 0ea42ab26c..1f75307b1e 100644 --- a/DMCompiler/DM/Builders/DMProcBuilder.cs +++ b/DMCompiler/DM/Builders/DMProcBuilder.cs @@ -525,7 +525,7 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) { if (outputVar is Local outputLocal) { outputLocal.LocalVar.ExplicitValueType = statementFor.DMTypes; if(outputLocal.LocalVar is DMProc.LocalConstVariable) - compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, $"Cannot change constant value"); + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); } else if (outputVar is Field { IsConst: true }) compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); From bf74a7610fac4b69d3e0aed7e27325bcaf2988eb Mon Sep 17 00:00:00 2001 From: wixoa Date: Sun, 8 Dec 2024 22:38:49 -0500 Subject: [PATCH 5/5] Update DMCompiler/DM/Builders/DMProcBuilder.cs --- DMCompiler/DM/Builders/DMProcBuilder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DMCompiler/DM/Builders/DMProcBuilder.cs b/DMCompiler/DM/Builders/DMProcBuilder.cs index 1f75307b1e..38f2c0d729 100644 --- a/DMCompiler/DM/Builders/DMProcBuilder.cs +++ b/DMCompiler/DM/Builders/DMProcBuilder.cs @@ -524,8 +524,8 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) { if (outputVar is Local outputLocal) { outputLocal.LocalVar.ExplicitValueType = statementFor.DMTypes; - if(outputLocal.LocalVar is DMProc.LocalConstVariable) - compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); + if(outputLocal.LocalVar is DMProc.LocalConstVariable) + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); } else if (outputVar is Field { IsConst: true }) compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value");