Skip to content

Commit 3d9367c

Browse files
committed
Fix#6784 - Add diagnostic for for-loop update expressions with no effect
This commit introduces a new warning diagnostic (30506) for cases where the update expression in a for-loop does not modify any variables, potentially leading to infinite loops. The implementation includes checks in the `SemanticsStmtVisitor` to identify such expressions and provide appropriate warnings. Additionally, tests have been added to verify the new diagnostic behavior.
1 parent 786f456 commit 3d9367c

File tree

4 files changed

+36
-0
lines changed

4 files changed

+36
-0
lines changed

source/slang/slang-check-stmt.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,31 @@ void SemanticsStmtVisitor::visitForStmt(ForStmt* stmt)
240240
if (stmt->sideEffectExpression)
241241
{
242242
stmt->sideEffectExpression = CheckExpr(stmt->sideEffectExpression);
243+
244+
// Check for common mistake where update expression has no side effect
245+
auto sideEffect = stmt->sideEffectExpression;
246+
if (auto infixExpr = as<InfixExpr>(sideEffect))
247+
{
248+
// Check if the operation is a binary operation like "+" and not "+="
249+
auto funcExpr = as<DeclRefExpr>(infixExpr->functionExpr);
250+
if (funcExpr && funcExpr->declRef.getDecl())
251+
{
252+
// Check if the operator name doesn't contain "="
253+
auto opName = funcExpr->declRef.getName();
254+
if (opName && !String(opName->text).contains("="))
255+
{
256+
// This is a potential issue - binary operators without "=" in for-loop updates
257+
// usually don't modify variables
258+
StringBuilder builder;
259+
builder << opName->text;
260+
261+
getSink()->diagnose(
262+
sideEffect,
263+
Diagnostics::forLoopUpdateExpressionHasNoEffect,
264+
builder.produceString());
265+
}
266+
}
267+
}
243268
}
244269
subContext.checkStmt(stmt->statement);
245270

source/slang/slang-diagnostic-defs.h

+5
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,11 @@ DIAGNOSTIC(
13961396
Warning,
13971397
loopRunsForZeroIterations,
13981398
"the loop runs for 0 iterations and will be removed.")
1399+
DIAGNOSTIC(
1400+
30506,
1401+
Warning,
1402+
forLoopUpdateExpressionHasNoEffect,
1403+
"the for loop update expression '$0' has no effect; this will result in an infinite loop")
13991404
DIAGNOSTIC(
14001405
30510,
14011406
Error,

tests/diagnostics/for-loop-warning.slang

+3
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,8 @@ float doSomething(int x)
5656
{
5757
i--;
5858
}
59+
for (int i = 1; i < 100; i + 2) //warn
60+
{
61+
}
5962
return 0.0;
6063
}

tests/diagnostics/for-loop-warning.slang.expected

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ tests/diagnostics/for-loop-warning.slang(45): warning 30505: the loop runs for 0
2121
tests/diagnostics/for-loop-warning.slang(51): warning 30505: the loop runs for 0 iterations and will be removed.
2222
for (int i = 1; i > 1; i--) // warn
2323
^~~
24+
tests/diagnostics/for-loop-warning.slang(59): warning 30506: the for loop update expression '+' has no effect; this will result in an infinite loop
25+
for (int i = 1; i < 100; i + 2) //warn
26+
^
2427
tests/diagnostics/for-loop-warning.slang(23): warning 30504: the for loop is statically determined to terminate within 3 iterations, which is less than what [MaxIters] specifies.
2528
[MaxIters(6)] // warn
2629
^~~~~~~~

0 commit comments

Comments
 (0)