https://github.com/balazske updated 
https://github.com/llvm/llvm-project/pull/208173

From 2891ff62aa1dae5b4371e273be2c63e2f2eae073 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= <[email protected]>
Date: Wed, 8 Jul 2026 09:26:19 +0200
Subject: [PATCH 1/2] [clang][analyzer] Improved message in
 uninitialized.Assign at default assignment

---
 .../Checkers/UndefinedAssignmentChecker.cpp   | 14 +++++++++++++
 clang/test/Analysis/operator-calls.cpp        | 20 +++++++++++++++----
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
index 7f8923c7c09fc..f97dd8ee67d57 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -73,6 +73,20 @@ void UndefinedAssignmentChecker::checkBind(SVal location, 
SVal val,
         }
       }
 
+      if (const auto *MD =
+              dyn_cast<CXXMethodDecl>(C.getStackFrame()->getDecl())) {
+        if ((MD->isCopyAssignmentOperator() ||
+             MD->isMoveAssignmentOperator()) &&
+            MD->isDefaulted() && B->isAssignmentOp()) {
+          OS << "Value assigned to field '"
+             << cast<MemberExpr>(B->getRHS()->IgnoreImpCasts())
+                    ->getMemberDecl()
+                    ->getName()
+             << "' in " << (!MD->isImplicit() ? "default" : "implicit")
+             << " assignment operator is uninitialized";
+          break;
+        }
+      }
       ex = B->getRHS();
       break;
     }
diff --git a/clang/test/Analysis/operator-calls.cpp 
b/clang/test/Analysis/operator-calls.cpp
index a89624d44ac42..5af0d72b60bc0 100644
--- a/clang/test/Analysis/operator-calls.cpp
+++ b/clang/test/Analysis/operator-calls.cpp
@@ -111,6 +111,11 @@ namespace SynthesizedAssignment {
     B& operator=(B&&) = default;
   };
 
+  struct C {
+    int x;
+    A a[3];
+  };
+
   // This used to produce a warning about the iteration variable in the
   // synthesized assignment operator being undefined.
   //
@@ -121,16 +126,16 @@ namespace SynthesizedAssignment {
   void testNoWarning() {
 
     B v, u;
-    u = v; // expected-warning@110{{Assigned value is uninitialized}}
+    u = v; // expected-warning@110{{Value assigned to field 'x' in default 
assignment operator is uninitialized}}
     // expected-note@-1{{Calling defaulted copy assignment operator for 'B'}}
-    // expected-note@110{{Assigned value is uninitialized}}
+    // expected-note@110{{Value assigned to field 'x' in default assignment 
operator is uninitialized}}
   }
 
   void testNoWarningMove() {
     B v, u;
-    u = static_cast<B &&>(v); // expected-warning@111{{Assigned value is 
uninitialized}}
+    u = static_cast<B &&>(v); // expected-warning@111{{Value assigned to field 
'x' in default assignment operator is uninitialized}}
     // expected-note@-1{{Calling defaulted move assignment operator for 'B'}}
-    // expected-note@111{{Assigned value is uninitialized}}
+    // expected-note@111{{Value assigned to field 'x' in default assignment 
operator is uninitialized}}
   }
 
   void testConsistency() {
@@ -162,4 +167,11 @@ namespace SynthesizedAssignment {
     clang_analyzer_eval(u.a[2].a == 43); // expected-warning{{TRUE}}
     // expected-note@-1{{TRUE}}
   }
+
+  void testImplicitAssign() {
+    C c1, c2;
+    c1 = c2; // expected-warning@114{{Value assigned to field 'x' in implicit 
assignment operator is uninitialized}}
+    // expected-note@-1{{Calling implicit copy assignment operator for 'C'}}
+    // expected-note@114{{Value assigned to field 'x' in implicit assignment 
operator is uninitialized}}
+  }
 }

From 0c3ef2a8006a564d55dceb1f89ed09778b370426 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= <[email protected]>
Date: Mon, 13 Jul 2026 12:36:33 +0200
Subject: [PATCH 2/2] safer MemberExpr check, using label in test

---
 .../Checkers/UndefinedAssignmentChecker.cpp    |  5 +++--
 clang/test/Analysis/operator-calls.cpp         | 18 +++++++++---------
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
index f97dd8ee67d57..331df5d8c750d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -77,9 +77,10 @@ void UndefinedAssignmentChecker::checkBind(SVal location, 
SVal val,
               dyn_cast<CXXMethodDecl>(C.getStackFrame()->getDecl())) {
         if ((MD->isCopyAssignmentOperator() ||
              MD->isMoveAssignmentOperator()) &&
-            MD->isDefaulted() && B->isAssignmentOp()) {
+            MD->isDefaulted() && B->isAssignmentOp() &&
+            isa<MemberExpr>(B->getLHS()->IgnoreImpCasts())) {
           OS << "Value assigned to field '"
-             << cast<MemberExpr>(B->getRHS()->IgnoreImpCasts())
+             << cast<MemberExpr>(B->getLHS()->IgnoreImpCasts())
                     ->getMemberDecl()
                     ->getName()
              << "' in " << (!MD->isImplicit() ? "default" : "implicit")
diff --git a/clang/test/Analysis/operator-calls.cpp 
b/clang/test/Analysis/operator-calls.cpp
index 5af0d72b60bc0..57da7cdc16923 100644
--- a/clang/test/Analysis/operator-calls.cpp
+++ b/clang/test/Analysis/operator-calls.cpp
@@ -107,11 +107,11 @@ namespace SynthesizedAssignment {
   struct B {
     int x;
     A a[3];
-    B& operator=(B&) = default;
-    B& operator=(B&&) = default;
+    B& operator=(B&) = default; // #b_copy_assign
+    B& operator=(B&&) = default; // #b_move_assign
   };
 
-  struct C {
+  struct C { // #c_definition
     int x;
     A a[3];
   };
@@ -126,16 +126,16 @@ namespace SynthesizedAssignment {
   void testNoWarning() {
 
     B v, u;
-    u = v; // expected-warning@110{{Value assigned to field 'x' in default 
assignment operator is uninitialized}}
+    u = v; // expected-warning@#b_copy_assign{{Value assigned to field 'x' in 
default assignment operator is uninitialized}}
     // expected-note@-1{{Calling defaulted copy assignment operator for 'B'}}
-    // expected-note@110{{Value assigned to field 'x' in default assignment 
operator is uninitialized}}
+    // expected-note@#b_copy_assign{{Value assigned to field 'x' in default 
assignment operator is uninitialized}}
   }
 
   void testNoWarningMove() {
     B v, u;
-    u = static_cast<B &&>(v); // expected-warning@111{{Value assigned to field 
'x' in default assignment operator is uninitialized}}
+    u = static_cast<B &&>(v); // expected-warning@#b_move_assign{{Value 
assigned to field 'x' in default assignment operator is uninitialized}}
     // expected-note@-1{{Calling defaulted move assignment operator for 'B'}}
-    // expected-note@111{{Value assigned to field 'x' in default assignment 
operator is uninitialized}}
+    // expected-note@#b_move_assign{{Value assigned to field 'x' in default 
assignment operator is uninitialized}}
   }
 
   void testConsistency() {
@@ -170,8 +170,8 @@ namespace SynthesizedAssignment {
 
   void testImplicitAssign() {
     C c1, c2;
-    c1 = c2; // expected-warning@114{{Value assigned to field 'x' in implicit 
assignment operator is uninitialized}}
+    c1 = c2; // expected-warning@#c_definition{{Value assigned to field 'x' in 
implicit assignment operator is uninitialized}}
     // expected-note@-1{{Calling implicit copy assignment operator for 'C'}}
-    // expected-note@114{{Value assigned to field 'x' in implicit assignment 
operator is uninitialized}}
+    // expected-note@#c_definition{{Value assigned to field 'x' in implicit 
assignment operator is uninitialized}}
   }
 }

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

Reply via email to