https://github.com/Snape3058 created 
https://github.com/llvm/llvm-project/pull/187530

Addressing #173210 in terms of path-sensitive analysis.

The self-assignment initialization `Type var = var;` is an idiom in C code. The 
analyzer is expected to suppress uninitialized assignment reports for this 
idiom and delay reporting until the uninitialized variable is actually used. 
Since GCC will not generate assembly code for such usage, even if under -O0 
optimization (but Clang will), this patch resolves this problem by ignoring 
such self-assigned `DeclStmt`s in the `ExprEngine`.

This is only a C idiom. In C++, both the frontend warning and the analyzer are 
expected to report this usage.

>From 1d87171dc76bab8fd78e60deb9b239874c5fd83b Mon Sep 17 00:00:00 2001
From: Ella Ma <[email protected]>
Date: Thu, 19 Mar 2026 14:15:11 +0100
Subject: [PATCH] wip-2026-03-19_16:24:09

---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 14 +++++++++
 .../Analysis/issue-173210-self-assign-init.c  | 29 +++++++++++++++++++
 2 files changed, 43 insertions(+)
 create mode 100644 clang/test/Analysis/issue-173210-self-assign-init.c

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 67beed5dbb6fb..214f266e21e4c 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -624,6 +624,20 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, 
ExplodedNode *Pred,
     return;
   }
 
+  // Bypass a nop initialization that assign to itself at variable declaration.
+  // I.e., int x = x;
+  // This is an idiom in C code and GCC will not generate any assemblies for
+  // this self initialization, even under -O0, but Clang will.
+  // Since the frontend will warn in C++ code, and it is ill-formed for C++
+  // reference types, the bypass is effected to C code only.
+  if (getContext().getLangOpts().getCLangStd())
+    if (const Expr *EI = VD->getInit())
+      if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(EI->IgnoreImpCasts()))
+        if (VD == DR->getDecl()) {
+          Dst.insert(Pred);
+          return;
+        }
+
   // FIXME: all pre/post visits should eventually be handled by ::Visit().
   ExplodedNodeSet dstPreVisit;
   getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
diff --git a/clang/test/Analysis/issue-173210-self-assign-init.c 
b/clang/test/Analysis/issue-173210-self-assign-init.c
new file mode 100644
index 0000000000000..c9e5e2be58875
--- /dev/null
+++ b/clang/test/Analysis/issue-173210-self-assign-init.c
@@ -0,0 +1,29 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -verify
+
+// Self assignment initialization in C code will be treated as nop.
+// We will not report the VarDecl, but the following DeclRefExpr if it has not
+// yet been initialized then.
+
+void clang_analyzer_warnIfReached();
+
+struct S { int x; };
+union U { int x; };
+
+void nowarn() {
+  int x = x; // no-warning
+  int *p = p; // no-warning
+  struct S s = s; // no-warning
+  union U u = u; // no-warning
+  // Ensure the analysis is not terminated sliently.
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+}
+
+int warn() {
+  int x = x;
+  return x; // expected-warning{{Undefined or garbage value returned to 
caller}}
+}
+
+// NOTE: The self assignment of reference type is tested with 
stack-addr-ps.cpp.
+// I.e., `int& i = i;` in function f5

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to