https://github.com/AmrDeveloper updated 
https://github.com/llvm/llvm-project/pull/223510

>From f920c60e39e17077cb3d39ff851f07e827e23839 Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Mon, 14 Sep 2026 21:15:35 +0200
Subject: [PATCH 1/2] [Clang][Sema] Improve diagnostic when using imag with non
 complex as lvalue

---
 clang/docs/ReleaseNotes.md                           |  2 ++
 clang/include/clang/Basic/DiagnosticSemaKinds.td     |  2 ++
 clang/lib/Sema/SemaExpr.cpp                          | 12 +++++++++++-
 .../SemaCXX/imag-lvalue-with-non-complex-operand.cpp |  8 ++++----
 4 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 8c1637388d990..fc49bbcd59306 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -510,6 +510,8 @@ features cannot lower the translation-unit ABI level;
 
 - Clang now diagnoses matrix logical operations are only supported for HLSL. 
(GH222381)
 
+- Improve Clang diagnoses when unary `__imag` operator with non-complex type 
operand is used as lvalue. (GH222383)
+
 ### Improvements to Clang's time-trace
 
 ### Improvements to Coverage Mapping
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 485145addad01..295dfff5eae6e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9526,6 +9526,8 @@ def err_typecheck_incomplete_type_not_modifiable_lvalue : 
Error<
   "incomplete type %0 is not assignable">;
 def err_typecheck_lvalue_casts_not_supported : Error<
   "assignment to cast is illegal, lvalue casts are not supported">;
+def err_typecheck_lvalue_imag_not_modifiable_lvalue : Error<
+  "__imag operator with non-complex type operand is not assignable">;
 
 def err_typecheck_duplicate_vector_components_not_mlvalue : Error<
   "vector is not assignable (contains duplicate components)">;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 7444fe0e71fd8..8850815bed3dc 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14547,9 +14547,19 @@ static bool CheckForModifiableLvalue(Expr *E, 
SourceLocation Loc, Sema &S) {
     llvm_unreachable("did not take early return for MLV_Valid");
   case Expr::MLV_InvalidExpression:
   case Expr::MLV_MemberFunction:
-  case Expr::MLV_ClassTemporary:
+  case Expr::MLV_ClassTemporary: {
+    if (const auto *UnaryOp = dyn_cast<UnaryOperator>(E)) {
+      const Expr *Op = UnaryOp->getSubExpr()->IgnoreParens();
+      if (UnaryOp->getOpcode() == UO_Imag &&
+          !Op->getType()->isAnyComplexType()) {
+        DiagID = diag::err_typecheck_lvalue_imag_not_modifiable_lvalue;
+        break;
+      }
+    }
+
     DiagID = diag::err_typecheck_expression_not_modifiable_lvalue;
     break;
+  }
   case Expr::MLV_IncompleteType:
   case Expr::MLV_IncompleteVoidType:
     return S.RequireCompleteType(Loc, E->getType(),
diff --git a/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp 
b/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp
index e07e7b42950d6..80407be76fa6f 100644
--- a/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp
+++ b/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp
@@ -2,19 +2,19 @@
 
 void lvalue_with_imag_int() {
   int i;
-  __imag__ i = 0;   // expected-error {{expression is not assignable}}
+  __imag__ i = 0;   // expected-error {{__imag operator with non-complex type 
operand is not assignable}}
 }
 
 void lvalue_with_imag_float() {
   float i;
-  __imag__ i = 0;   // expected-error {{expression is not assignable}}
+  __imag__ i = 0;   // expected-error {{__imag operator with non-complex type 
operand is not assignable}}
 }
 
 _Complex float foo()
 {
   float f;
   __real__ f = 0;
-  __imag__ f = 0;    // expected-error {{expression is not assignable}}
+  __imag__ f = 0;    // expected-error {{__imag operator with non-complex type 
operand is not assignable}}
   return f;
 }
 
@@ -31,6 +31,6 @@ C lvalue_with_imag_float_with_typedef()
 {
   C f;
   __real__ f = 0;
-  __imag__ f = 0;   // expected-error {{expression is not assignable}}
+  __imag__ f = 0;   // expected-error {{__imag operator with non-complex type 
operand is not assignable}}
   return f;
 }

>From 376124cf023db9c0ab71f9f2b940926bb7ffa36f Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Tue, 15 Sep 2026 18:20:22 +0200
Subject: [PATCH 2/2] Improve the diagnostic

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td          | 2 +-
 clang/lib/Sema/SemaExpr.cpp                               | 1 +
 .../test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp | 8 ++++----
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 295dfff5eae6e..825d17f49790c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9527,7 +9527,7 @@ def err_typecheck_incomplete_type_not_modifiable_lvalue : 
Error<
 def err_typecheck_lvalue_casts_not_supported : Error<
   "assignment to cast is illegal, lvalue casts are not supported">;
 def err_typecheck_lvalue_imag_not_modifiable_lvalue : Error<
-  "__imag operator with non-complex type operand is not assignable">;
+  "'__imag' operator with non-complex operand type %0 is not assignable">;
 
 def err_typecheck_duplicate_vector_components_not_mlvalue : Error<
   "vector is not assignable (contains duplicate components)">;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8850815bed3dc..9e5f6a609bb50 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14553,6 +14553,7 @@ static bool CheckForModifiableLvalue(Expr *E, 
SourceLocation Loc, Sema &S) {
       if (UnaryOp->getOpcode() == UO_Imag &&
           !Op->getType()->isAnyComplexType()) {
         DiagID = diag::err_typecheck_lvalue_imag_not_modifiable_lvalue;
+        NeedType = true;
         break;
       }
     }
diff --git a/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp 
b/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp
index 80407be76fa6f..f0fbe4150f497 100644
--- a/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp
+++ b/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp
@@ -2,19 +2,19 @@
 
 void lvalue_with_imag_int() {
   int i;
-  __imag__ i = 0;   // expected-error {{__imag operator with non-complex type 
operand is not assignable}}
+  __imag__ i = 0;   // expected-error {{'__imag' operator with non-complex 
operand type 'int' is not assignable}}
 }
 
 void lvalue_with_imag_float() {
   float i;
-  __imag__ i = 0;   // expected-error {{__imag operator with non-complex type 
operand is not assignable}}
+  __imag__ i = 0;   // expected-error {{'__imag' operator with non-complex 
operand type 'float' is not assignable}}
 }
 
 _Complex float foo()
 {
   float f;
   __real__ f = 0;
-  __imag__ f = 0;    // expected-error {{__imag operator with non-complex type 
operand is not assignable}}
+  __imag__ f = 0;    // expected-error {{'__imag' operator with non-complex 
operand type 'float' is not assignable}}
   return f;
 }
 
@@ -31,6 +31,6 @@ C lvalue_with_imag_float_with_typedef()
 {
   C f;
   __real__ f = 0;
-  __imag__ f = 0;   // expected-error {{__imag operator with non-complex type 
operand is not assignable}}
+  __imag__ f = 0;   // expected-error {{'__imag' operator with non-complex 
operand type 'C' (aka 'float') is not assignable}}
   return f;
 }

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

Reply via email to