[clang] [Sema] Diagnose use of if/else-if condition variable inside else-if/else branch(s) (PR #156436)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 2 03:13:33 PDT 2025
https://github.com/arrowten created https://github.com/llvm/llvm-project/pull/156436
This patch adds a warning when variable(s) declared in if/else-if scope are used in else-if/else branch(s)
>From 232cb40aecf07eeac0c9bf9a1aa302f3a55a5ee1 Mon Sep 17 00:00:00 2001
From: arrowten <ajaywakodikarsocial at gmail.com>
Date: Tue, 2 Sep 2025 15:33:52 +0530
Subject: [PATCH] [Sema] Diagnose use of if/else-if condition variable inside
else-if/else branch(s)
---
.../clang/Basic/DiagnosticSemaKinds.td | 3 ++
clang/lib/Sema/SemaStmt.cpp | 29 +++++++++++++++++++
clang/test/Sema/warn-conditional-scope.cpp | 23 +++++++++++++++
3 files changed, 55 insertions(+)
create mode 100644 clang/test/Sema/warn-conditional-scope.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c934fed2c7462..3d370d46480d5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13594,6 +13594,9 @@ def warn_acc_var_referenced_lacks_op
"reference has no effect">,
InGroup<DiagGroup<"openacc-var-lacks-operation">>,
DefaultError;
+def warn_out_of_scope_var_usage
+ : Warning<"variable %0 used in else/else if block is out of scope">,
+ InGroup<DiagGroup<"conditional-scope">>;
// AMDGCN builtins diagnostics
def err_amdgcn_load_lds_size_invalid_value : Error<"invalid size value">;
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 5625fb359807a..f0f5c62380f30 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -25,6 +25,7 @@
#include "clang/AST/StmtObjC.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeOrdering.h"
+#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
@@ -971,6 +972,34 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc,
if (!ConstevalOrNegatedConsteval && !elseStmt)
DiagnoseEmptyStmtBody(RParenLoc, thenStmt, diag::warn_empty_if_body);
+ // Checks for if/else-if condition variable usage in else-if/else scope
+ if (elseStmt) {
+ VarDecl *ConditionVar = nullptr;
+
+ if (auto *CondVar = Cond.get().first) {
+ ConditionVar = dyn_cast<VarDecl>(CondVar);
+ }
+
+ if (ConditionVar) {
+ struct ElseVariableUsageChecker
+ : public RecursiveASTVisitor<ElseVariableUsageChecker> {
+ VarDecl *TargetVar;
+ Sema &SemaRef;
+ ElseVariableUsageChecker(VarDecl *Var, Sema &S) : TargetVar(Var), SemaRef(S) {}
+
+ bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+ if (DRE->getDecl() == TargetVar) {
+ SemaRef.Diag(DRE->getBeginLoc(), diag::warn_out_of_scope_var_usage) << TargetVar->getName();
+ }
+ return true;
+ }
+ };
+
+ ElseVariableUsageChecker Checker(ConditionVar, *this);
+ Checker.TraverseStmt(elseStmt);
+ }
+ }
+
if (ConstevalOrNegatedConsteval ||
StatementKind == IfStatementKind::Constexpr) {
auto DiagnoseLikelihood = [&](const Stmt *S) {
diff --git a/clang/test/Sema/warn-conditional-scope.cpp b/clang/test/Sema/warn-conditional-scope.cpp
new file mode 100644
index 0000000000000..3d7d1ad522fdd
--- /dev/null
+++ b/clang/test/Sema/warn-conditional-scope.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wconditional-scope %s
+
+int *get_something();
+int *get_something_else();
+int *get_something_else_again();
+
+int test() {
+ if (int *ptr = get_something()) {
+ return ptr[0] * ptr[0];
+ }
+ else if (int *ptr2 = get_something_else()) {
+ // expected-warning at +1{{variable ptr used in else/else if block is out of scope}}
+ return ptr[0] * ptr2[0];
+ }
+ else if (int* ptr3 = get_something_else_again()) {
+ // expected-warning at +2{{variable ptr used in else/else if block is out of scope}}
+ // expected-warning at +1{{variable ptr2 used in else/else if block is out of scope}}
+ return ptr[0] * ptr2[0] * ptr3[0];
+ }
+ else {
+ return -1;
+ }
+}
More information about the cfe-commits
mailing list