llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) <details> <summary>Changes</summary> Clang accepts `__real int/float` as an RValue because it's equal to the scalar value itself, so the assignment will work fine, but it's not the case for `__imag` because, for int and float, there is no imaginary part to assign a value to it, so in the sema we can reject this case, similar to GCC. Fixes: #<!-- -->119498 --- Full diff: https://github.com/llvm/llvm-project/pull/218270.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.md (+1) - (modified) clang/lib/AST/ExprClassification.cpp (+6-1) - (added) clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp (+35) ``````````diff diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index ca0dbfa2af229..e541f5aa3f1e5 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -440,6 +440,7 @@ features cannot lower the translation-unit ABI level; - Fixed a crash when declaring a member template within a local class inside an OpenMP region. (#GH216052) - Fixed a bug where repeated #imports of modular headers in non-modular compilation were translated to #pragma clang module import. (#GH216924) - Fixed an assertion when `#pragma omp declare simd` or `#pragma omp declare variant` is followed by another OpenMP declarative directive containing a qualified identifier. (#GH217204) +- Fixed an ICE hat occurred when using `__imag int/float` as rvalue in assignment. (#GH119498) #### Bug Fixes to Compiler Builtins diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index eebae17d7b948..a80bd2ab50001 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -283,7 +283,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { return ClassifyMemberExpr(Ctx, cast<MemberExpr>(E)); case Expr::UnaryOperatorClass: - switch (cast<UnaryOperator>(E)->getOpcode()) { + switch (auto UnaryOp = cast<UnaryOperator>(E)->getOpcode()) { // C++ [expr.unary.op]p1: The unary * operator performs indirection: // [...] the result is an lvalue referring to the object or function // to which the expression points. @@ -304,6 +304,11 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { if (isa<ObjCPropertyRefExpr>(Op)) return Cl::CL_SubObjCPropertySetting; + + // _Imag with non-complex operand is not a valid l-value + if (UnaryOp == UO_Imag && !Op->getType()->isAnyComplexType()) + return Cl::CL_PRValue; + return Cl::CL_LValue; } diff --git a/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp b/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp new file mode 100644 index 0000000000000..b1ea9b4473b3e --- /dev/null +++ b/clang/test/SemaCXX/imag-lvalue-with-non-complex-operand.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void lvalue_with_imag_int() { + int i; + __imag__ i = 0; // expected-error {{expression is not assignable}} +} + +void lvalue_with_imag_float() { + float i; + __imag__ i = 0; // expected-error {{expression is not assignable}} +} + +_Complex float foo() // expected-note {{previous definition is here}} +{ + float f; + __real__ f = 0; + __imag__ f = 0; // expected-error {{expression is not assignable}} + return f; +} + +_Complex float baz() +{ + float f; + __real__ f = 0; + __imag__ } // expected-error {{expected expression}} + + +typedef _Complex float C; +C foo() // expected-error {{redefinition of 'foo'}} +{ + C f; + __real__ f = 0; + __imag__ f = 0; + return f; +} `````````` </details> https://github.com/llvm/llvm-project/pull/218270 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
