From fbde76e0775911b1dce07202a04b1a8e9ee5fa76 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 14 Jul 2026 13:26:40 +0200 Subject: [PATCH 1/4] C#: Add some GOOD dead store of local test examples. --- .../Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.cs b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.cs index 03a6644fe800..23ba1a655d05 100644 --- a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.cs +++ b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; public class DeadStoreOfLocal { @@ -484,3 +485,16 @@ void Pi() Console.WriteLine($"Pi, {pi,align:F3}"); } } + +class LinqFields +{ + private readonly IEnumerable QueryBackedField = + from x1 in new[] { 1, 2, 3 } + where x1 > 1 + select x1; // GOOD: The query range variable is used by the LINQ expression. + + public static readonly IEnumerable StaticQueryBackedField = + from x2 in new[] { 1, 2, 3 } + where x2 > 1 + select x2; // GOOD: The query range variable is used by the LINQ expression. +} From 6a40b86ff0bfd1bd675bf59096c9d1af8d42d10b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 14 Jul 2026 13:27:55 +0200 Subject: [PATCH 2/4] C#: Update test expected output. --- .../DeadStoreOfLocal.expected | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected index 2073fce06a77..4bbcf8565293 100644 --- a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected +++ b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected @@ -1,21 +1,25 @@ -| DeadStoreOfLocal.cs:12:13:12:20 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:12:13:12:13 | x | x | -| DeadStoreOfLocal.cs:19:21:19:25 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:18:13:18:13 | x | x | -| DeadStoreOfLocal.cs:44:13:44:20 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:44:13:44:13 | x | x | -| DeadStoreOfLocal.cs:50:9:50:14 | ... += ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:49:13:49:13 | x | x | -| DeadStoreOfLocal.cs:56:9:56:11 | ...++ | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:55:13:55:13 | x | x | -| DeadStoreOfLocal.cs:82:22:82:24 | String val | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:82:22:82:24 | val | val | -| DeadStoreOfLocal.cs:101:13:101:37 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:94:40:94:44 | extra | extra | -| DeadStoreOfLocal.cs:104:13:104:37 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:94:16:94:20 | info1 | info1 | -| DeadStoreOfLocal.cs:142:26:142:27 | Exception ex | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:142:26:142:27 | ex | ex | -| DeadStoreOfLocal.cs:246:17:246:24 | Int32 y = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:246:17:246:17 | y | y | -| DeadStoreOfLocal.cs:261:17:261:21 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:261:17:261:17 | x | x | -| DeadStoreOfLocal.cs:300:23:300:28 | Object v1 | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:300:27:300:28 | v1 | v1 | -| DeadStoreOfLocal.cs:314:18:314:23 | Object v2 | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:314:22:314:23 | v2 | v2 | -| DeadStoreOfLocal.cs:331:9:331:32 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:327:23:327:23 | b | b | -| DeadStoreOfLocal.cs:372:13:372:20 | String s = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:372:13:372:13 | s | s | -| DeadStoreOfLocal.cs:472:20:472:76 | FileStream y = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:472:20:472:20 | y | y | +#select +| DeadStoreOfLocal.cs:13:13:13:20 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:13:13:13:13 | x | x | +| DeadStoreOfLocal.cs:20:21:20:25 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:19:13:19:13 | x | x | +| DeadStoreOfLocal.cs:45:13:45:20 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:45:13:45:13 | x | x | +| DeadStoreOfLocal.cs:51:9:51:14 | ... += ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:50:13:50:13 | x | x | +| DeadStoreOfLocal.cs:57:9:57:11 | ...++ | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:56:13:56:13 | x | x | +| DeadStoreOfLocal.cs:83:22:83:24 | String val | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:83:22:83:24 | val | val | +| DeadStoreOfLocal.cs:102:13:102:37 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:95:40:95:44 | extra | extra | +| DeadStoreOfLocal.cs:105:13:105:37 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:95:16:95:20 | info1 | info1 | +| DeadStoreOfLocal.cs:143:26:143:27 | Exception ex | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:143:26:143:27 | ex | ex | +| DeadStoreOfLocal.cs:247:17:247:24 | Int32 y = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:247:17:247:17 | y | y | +| DeadStoreOfLocal.cs:262:17:262:21 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:262:17:262:17 | x | x | +| DeadStoreOfLocal.cs:301:23:301:28 | Object v1 | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:301:27:301:28 | v1 | v1 | +| DeadStoreOfLocal.cs:315:18:315:23 | Object v2 | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:315:22:315:23 | v2 | v2 | +| DeadStoreOfLocal.cs:332:9:332:32 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:328:23:328:23 | b | b | +| DeadStoreOfLocal.cs:373:13:373:20 | String s = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:373:13:373:13 | s | s | +| DeadStoreOfLocal.cs:473:20:473:76 | FileStream y = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:473:20:473:20 | y | y | +| DeadStoreOfLocal.cs:497:9:497:36 | Int32 x2 = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:497:14:497:15 | x2 | x2 | | DeadStoreOfLocalBad.cs:7:13:7:48 | Boolean success = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:7:13:7:19 | success | success | | DeadStoreOfLocalBad.cs:23:32:23:32 | FormatException e | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:23:32:23:32 | e | e | | DeadStoreOfLocalBad.cs:32:22:32:22 | String s | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:32:22:32:22 | s | s | | DeadStoreOfLocalBad.cs:39:18:39:22 | Int32 i | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:39:22:39:22 | i | i | | DeadStoreOfLocalBad.cs:49:18:49:25 | String s | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:49:25:49:25 | s | s | +testFailures +| DeadStoreOfLocal.cs:497:9:497:36 | This assignment to $@ is useless, since its value is never read. | Unexpected result: Alert | From 6d0e0793ed0ebe576d47a19afdb5fe217c2c282a Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 14 Jul 2026 13:33:12 +0200 Subject: [PATCH 3/4] C#: Consider the static constructor the enclosing callable for static member initialization. Note that a class can only have ONE static constructor (so it will be unique). --- csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll index 2cf09707459d..493337a8edd4 100644 --- a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll +++ b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll @@ -6,6 +6,7 @@ import csharp private import internal.Location +private import controlflow.internal.ControlFlowGraph /** * INTERNAL: Do not use. @@ -145,6 +146,8 @@ private module Cached { parent*(cfe, c.(Constructor).getObjectInitializerCall()) or parent*(cfe, any(AssignExpr init | c.(ObjectInitMethod).initializes(init))) + or + parent*(cfe, any(Expr init | Initializers::staticMemberInitializer(c, init))) } /** Holds if the enclosing statement of expression `e` is `s`. */ From dbf8c6a3ae45601cbc66c430a2c09942cafb2500 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 14 Jul 2026 13:34:46 +0200 Subject: [PATCH 4/4] C#: Update test expected output. --- .../Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected | 4 ---- 1 file changed, 4 deletions(-) diff --git a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected index 4bbcf8565293..27ddb157eca3 100644 --- a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected +++ b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected @@ -1,4 +1,3 @@ -#select | DeadStoreOfLocal.cs:13:13:13:20 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:13:13:13:13 | x | x | | DeadStoreOfLocal.cs:20:21:20:25 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:19:13:19:13 | x | x | | DeadStoreOfLocal.cs:45:13:45:20 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:45:13:45:13 | x | x | @@ -15,11 +14,8 @@ | DeadStoreOfLocal.cs:332:9:332:32 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:328:23:328:23 | b | b | | DeadStoreOfLocal.cs:373:13:373:20 | String s = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:373:13:373:13 | s | s | | DeadStoreOfLocal.cs:473:20:473:76 | FileStream y = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:473:20:473:20 | y | y | -| DeadStoreOfLocal.cs:497:9:497:36 | Int32 x2 = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:497:14:497:15 | x2 | x2 | | DeadStoreOfLocalBad.cs:7:13:7:48 | Boolean success = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:7:13:7:19 | success | success | | DeadStoreOfLocalBad.cs:23:32:23:32 | FormatException e | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:23:32:23:32 | e | e | | DeadStoreOfLocalBad.cs:32:22:32:22 | String s | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:32:22:32:22 | s | s | | DeadStoreOfLocalBad.cs:39:18:39:22 | Int32 i | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:39:22:39:22 | i | i | | DeadStoreOfLocalBad.cs:49:18:49:25 | String s | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocalBad.cs:49:25:49:25 | s | s | -testFailures -| DeadStoreOfLocal.cs:497:9:497:36 | This assignment to $@ is useless, since its value is never read. | Unexpected result: Alert |