[clang] [Sema] Diagnose use of if/else-if condition variable inside else-if/else branch(s) (PR #156436)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 23 06:26:29 PDT 2025


================
@@ -1526,6 +1526,44 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
   SourceLocation ElseStmtLoc;
   StmtResult ElseStmt;
 
+  static llvm::DenseMap<const IdentifierInfo*, SourceLocation> UsedCondVars;
+  const VarDecl *VD = dyn_cast_or_null<VarDecl>(Cond.get().first);
+
+  if (VD) {
+    SourceLocation Loc = VD->getLocation();
+
+    if (!UsedCondVars.count(VD->getIdentifier()))
+      UsedCondVars[VD->getIdentifier()] = Loc;
+  }
+
+  std::function<void(const Stmt *)> DiagnoseOutOfScopeUse = [&](const Stmt *S) {
+    if (!S) return;
+
+    for (const Stmt *Child : S->children()) {
+      if (!Child) continue;
+
+      if (const auto *DRE = dyn_cast<DeclRefExpr>(Child)) {
+        if (const auto *UsedVD = dyn_cast<VarDecl>(DRE->getDecl())) {
+          if (UsedCondVars.count(UsedVD->getIdentifier()) && UsedVD != VD) {
+            if (Diags.isIgnored(diag::warn_out_of_scope_var_usage, DRE->getExprLoc()))
+              continue; 
+
+            Diag(DRE->getExprLoc(), diag::warn_out_of_scope_var_usage)
+              << UsedVD->getName();
+          }
+        }
+      }
+
+      DiagnoseOutOfScopeUse(Child);
+    }
+  };
+
+  if (ThenStmt.get())
+    DiagnoseOutOfScopeUse(ThenStmt.get());
+ 
+  if (ElseStmt.get())
+    DiagnoseOutOfScopeUse(ElseStmt.get());
----------------
erichkeane wrote:

Yep, exactly.  Searching the AST for this pattern is, as I've said before, the wrong approach, and I'm against this.



https://github.com/llvm/llvm-project/pull/156436


More information about the cfe-commits mailing list