nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: VKCOM/noverify
Pull request #694 (2020-08-20 15:49:36)

linter: fix node path for catch stmt
We don't call Walk() on catch stmt, so ir.CatchStmt never
gets into the node path. This makes Conditional() never
return true for ir.CatchStmt case.

Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>

quasilyte: I'll check whether we can call Walk on catch stmt and get rid of the ugly push/pop hack.

Patch:
diff --git a/src/linter/block.go b/src/linter/block.go
index ee9aa6f..34389a8 100644
--- a/src/linter/block.go
+++ b/src/linter/block.go
@@ -283,6 +283,10 @@ func (b *BlockWalker) EnterNode(n ir.Node) (res bool) {
 
 	case *ir.ReturnStmt:
 		b.handleReturn(s)
+
+	case *ir.CatchStmt:
+		b.handleCatch(s)
+		res = false
 	}
 
 	for _, c := range b.custom {
@@ -543,7 +547,7 @@ func (b *BlockWalker) handleTry(s *ir.TryStmt) bool {
 			for _, s := range cc.Stmts {
 				b.addStatement(s)
 			}
-			b.handleCatch(cc)
+			cc.Walk(b)
 		})
 		contexts = append(contexts, ctx)
 	}
@@ -599,7 +603,7 @@ func (b *BlockWalker) handleTry(s *ir.TryStmt) bool {
 	return false
 }
 
-func (b *BlockWalker) handleCatch(s *ir.CatchStmt) bool {
+func (b *BlockWalker) handleCatch(s *ir.CatchStmt) {
 	m := meta.NewEmptyTypesMap(len(s.Types))
 	for _, t := range s.Types {
 		typ, ok := solver.GetClassName(b.r.ctx.st, t)
@@ -617,8 +621,6 @@ func (b *BlockWalker) handleCatch(s *ir.CatchStmt) bool {
 			stmt.Walk(b)
 		}
 	}
-
-	return false
 }
 
 // We still need to analyze expressions in isset()/unset()/empty() statements


Test patch:
diff --git a/src/tests/custom/path_test.go b/src/tests/custom/path_test.go
index b8bda9a..15590a1 100644
--- a/src/tests/custom/path_test.go
+++ b/src/tests/custom/path_test.go
@@ -16,6 +16,22 @@ func init() {
 	})
 }
 
+func TestPathTryCatch(t *testing.T) {
+	test := linttest.NewSuite(t)
+	test.AddFile(`<?php
+try {
+  echo $_try;
+} catch (Exception $e) {
+  echo $_catch;
+}
+`)
+	test.Expect = []string{
+		`$_try (cond=false) : *ir.Root/*ir.TryStmt/*ir.EchoStmt/*ir.SimpleVar`,
+		`$_catch (cond=true) : *ir.Root/*ir.TryStmt/*ir.CatchStmt/*ir.EchoStmt/*ir.SimpleVar`,
+	}
+	linttest.RunFilterMatch(test, "pathTest")
+}
+
 func TestPathIfElse(t *testing.T) {
 	test := linttest.NewSuite(t)
 	test.AddFile(`<?php