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

Reply via email to