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
