[clang] [Clang][Sema] Improve diagnostic when using imag with non complex as lvalue (PR #223510)

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 14 12:58:41 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

<details>
<summary>Changes</summary>

Improve the Clang diagnostic when the unary `__imag` operator with a non-complex type operand is used as an lvalue

Issue #<!-- -->222383

---
Full diff: https://github.com/llvm/llvm-project/pull/223510.diff


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+2) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+11-1) 
- (modified) clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp (+4-4) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 043a0ddae2a6cd..1bbf2264998cf6 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -493,6 +493,8 @@ features cannot lower the translation-unit ABI level;
   `operator delete`, since such a delete expression never invokes the
   destructor. (#GH65524)
 
+- 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 0e09f7cfba7e1b..3e8a1479ba7f5e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9517,6 +9517,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 7186aa86fae1ee..848d662c1eb4ee 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 e07e7b42950d63..80407be76fa6f9 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;
 }

``````````

</details>


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


More information about the cfe-commits mailing list