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

>From 874f2e9f657851417189d26c0fa2a32ff0f10398 Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Sat, 13 Dec 2025 22:39:45 +0100
Subject: [PATCH 1/4] [clang] Fixed a crash when explicitly casting between
 atomic complex types

---
 clang/docs/ReleaseNotes.rst         |  8 ++++++--
 clang/lib/CodeGen/CGExprComplex.cpp |  5 +++++
 clang/test/CodeGen/complex.c        | 30 +++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 688f0a2c2bb75..025e87864e5ef 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -579,10 +579,14 @@ Code Completion
 Static Analyzer
 ---------------
 
+Crash and bug fixes
+^^^^^^^^^^^^^^^^^^^
+
+- Fixed a crash when explicitly casting a complex type to or from an atomic 
complex type. (#GH172208)
+
 .. comment:
   This is for the Static Analyzer.
   Using the caret `^^^` underlining for subsections:
-    - Crash and bug fixes
     - New checkers and features
     - Improvements
     - Moved checkers
@@ -631,4 +635,4 @@ tree.
 
 If you have any questions or comments about Clang, please feel free to
 contact us on the `Discourse forums (Clang Frontend category)
-<https://discourse.llvm.org/c/clang/6>`_.
+<https://discourse.llvm.org/c/clang/6>`_.
\ No newline at end of file
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp 
b/clang/lib/CodeGen/CGExprComplex.cpp
index 92129a041fd8e..83c5fa7c6e11f 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -507,7 +507,12 @@ ComplexPairTy 
ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
                                                            QualType DestType,
                                                            SourceLocation Loc) 
{
   // Get the src/dest element type.
+  if (SrcType->isAtomicType())
+    SrcType = SrcType->castAs<AtomicType>()->getValueType();
   SrcType = SrcType->castAs<ComplexType>()->getElementType();
+
+  if (DestType->isAtomicType())
+    DestType = DestType->castAs<AtomicType>()->getValueType();
   DestType = DestType->castAs<ComplexType>()->getElementType();
 
   // C99 6.3.1.6: When a value of complex type is converted to another
diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index a7654dcb76e32..7ef9fe8b33105 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -593,6 +593,36 @@ void imag_on_scalar_with_type_promotion() {
   _Float16 _Complex a;
   _Float16 b = __real__(__imag__ a);
 }
+
+// CHECK-LABEL: define dso_local void 
@explicit_cast_atomic_complex_to_atomic_complex(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[A:%.*]] = alloca { float, float }, align 8
+// CHECK-NEXT:    [[B:%.*]] = alloca { i32, i32 }, align 8
+// CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca { float, float }, align 8
+// CHECK-NEXT:    [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float 
}, ptr [[A]], i32 0, i32 0
+// CHECK-NEXT:    [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float 
}, ptr [[A]], i32 0, i32 1
+// CHECK-NEXT:    store float 2.000000e+00, ptr [[A_REALP]], align 8
+// CHECK-NEXT:    store float 0.000000e+00, ptr [[A_IMAGP]], align 4
+// CHECK-NEXT:    [[ATOMIC_LOAD:%.*]] = load atomic i64, ptr [[A]] seq_cst, 
align 8
+// CHECK-NEXT:    store i64 [[ATOMIC_LOAD]], ptr [[ATOMIC_TEMP]], align 8
+// CHECK-NEXT:    [[ATOMIC_TEMP_REALP:%.*]] = getelementptr inbounds nuw { 
float, float }, ptr [[ATOMIC_TEMP]], i32 0, i32 0
+// CHECK-NEXT:    [[ATOMIC_TEMP_REAL:%.*]] = load float, ptr 
[[ATOMIC_TEMP_REALP]], align 8
+// CHECK-NEXT:    [[ATOMIC_TEMP_IMAGP:%.*]] = getelementptr inbounds nuw { 
float, float }, ptr [[ATOMIC_TEMP]], i32 0, i32 1
+// CHECK-NEXT:    [[ATOMIC_TEMP_IMAG:%.*]] = load float, ptr 
[[ATOMIC_TEMP_IMAGP]], align 4
+// CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[ATOMIC_TEMP_REAL]] to i32
+// CHECK-NEXT:    [[CONV1:%.*]] = fptosi float [[ATOMIC_TEMP_IMAG]] to i32
+// CHECK-NEXT:    [[B_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, 
ptr [[B]], i32 0, i32 0
+// CHECK-NEXT:    [[B_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, 
ptr [[B]], i32 0, i32 1
+// CHECK-NEXT:    store i32 [[CONV]], ptr [[B_REALP]], align 8
+// CHECK-NEXT:    store i32 [[CONV1]], ptr [[B_IMAGP]], align 4
+// CHECK-NEXT:    ret void
+//
+void explicit_cast_atomic_complex_to_atomic_complex() {
+  _Atomic _Complex float a = 2.0f;
+  _Atomic _Complex int b = (_Atomic _Complex int)a;
+}
+
 //.
 // CHECK: [[PROF2]] = !{!"branch_weights", i32 1, i32 1048575}
 //.

>From 25fd4a074030c28a2f99299175cfd4a105080414 Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Sun, 14 Dec 2025 20:56:22 +0100
Subject: [PATCH 2/4] Update releasenotes and add more test cases

---
 clang/test/CodeGen/complex.c | 57 +++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index 7ef9fe8b33105..6616ca4b19a26 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -623,6 +623,61 @@ void explicit_cast_atomic_complex_to_atomic_complex() {
   _Atomic _Complex int b = (_Atomic _Complex int)a;
 }
 
+// CHECK-LABEL: define dso_local void @explicit_cast_atomic_complex_to_complex(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[A:%.*]] = alloca { float, float }, align 8
+// CHECK-NEXT:    [[B:%.*]] = alloca { i32, i32 }, align 4
+// CHECK-NEXT:    [[ATOMIC_TEMP:%.*]] = alloca { float, float }, align 8
+// CHECK-NEXT:    [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float 
}, ptr [[A]], i32 0, i32 0
+// CHECK-NEXT:    [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float 
}, ptr [[A]], i32 0, i32 1
+// CHECK-NEXT:    store float 2.000000e+00, ptr [[A_REALP]], align 8
+// CHECK-NEXT:    store float 0.000000e+00, ptr [[A_IMAGP]], align 4
+// CHECK-NEXT:    [[ATOMIC_LOAD:%.*]] = load atomic i64, ptr [[A]] seq_cst, 
align 8
+// CHECK-NEXT:    store i64 [[ATOMIC_LOAD]], ptr [[ATOMIC_TEMP]], align 8
+// CHECK-NEXT:    [[ATOMIC_TEMP_REALP:%.*]] = getelementptr inbounds nuw { 
float, float }, ptr [[ATOMIC_TEMP]], i32 0, i32 0
+// CHECK-NEXT:    [[ATOMIC_TEMP_REAL:%.*]] = load float, ptr 
[[ATOMIC_TEMP_REALP]], align 8
+// CHECK-NEXT:    [[ATOMIC_TEMP_IMAGP:%.*]] = getelementptr inbounds nuw { 
float, float }, ptr [[ATOMIC_TEMP]], i32 0, i32 1
+// CHECK-NEXT:    [[ATOMIC_TEMP_IMAG:%.*]] = load float, ptr 
[[ATOMIC_TEMP_IMAGP]], align 4
+// CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[ATOMIC_TEMP_REAL]] to i32
+// CHECK-NEXT:    [[CONV1:%.*]] = fptosi float [[ATOMIC_TEMP_IMAG]] to i32
+// CHECK-NEXT:    [[B_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, 
ptr [[B]], i32 0, i32 0
+// CHECK-NEXT:    [[B_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, 
ptr [[B]], i32 0, i32 1
+// CHECK-NEXT:    store i32 [[CONV]], ptr [[B_REALP]], align 4
+// CHECK-NEXT:    store i32 [[CONV1]], ptr [[B_IMAGP]], align 4
+// CHECK-NEXT:    ret void
+//
+void explicit_cast_atomic_complex_to_complex() {
+  _Atomic _Complex float a = 2.0f;
+  _Complex int b = (_Complex int)a;
+}
+
+// CHECK-LABEL: define dso_local void @explicit_cast_complex_to_atomic_complex(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[A:%.*]] = alloca { float, float }, align 4
+// CHECK-NEXT:    [[B:%.*]] = alloca { i32, i32 }, align 8
+// CHECK-NEXT:    [[A_REALP:%.*]] = getelementptr inbounds nuw { float, float 
}, ptr [[A]], i32 0, i32 0
+// CHECK-NEXT:    [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float 
}, ptr [[A]], i32 0, i32 1
+// CHECK-NEXT:    store float 2.000000e+00, ptr [[A_REALP]], align 4
+// CHECK-NEXT:    store float 0.000000e+00, ptr [[A_IMAGP]], align 4
+// CHECK-NEXT:    [[A_REALP1:%.*]] = getelementptr inbounds nuw { float, float 
}, ptr [[A]], i32 0, i32 0
+// CHECK-NEXT:    [[A_REAL:%.*]] = load float, ptr [[A_REALP1]], align 4
+// CHECK-NEXT:    [[A_IMAGP2:%.*]] = getelementptr inbounds nuw { float, float 
}, ptr [[A]], i32 0, i32 1
+// CHECK-NEXT:    [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP2]], align 4
+// CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[A_REAL]] to i32
+// CHECK-NEXT:    [[CONV3:%.*]] = fptosi float [[A_IMAG]] to i32
+// CHECK-NEXT:    [[B_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, 
ptr [[B]], i32 0, i32 0
+// CHECK-NEXT:    [[B_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, 
ptr [[B]], i32 0, i32 1
+// CHECK-NEXT:    store i32 [[CONV]], ptr [[B_REALP]], align 8
+// CHECK-NEXT:    store i32 [[CONV3]], ptr [[B_IMAGP]], align 4
+// CHECK-NEXT:    ret void
+//
+void explicit_cast_complex_to_atomic_complex() {
+  _Complex float a = 2.0f;
+  _Atomic _Complex int b = (_Atomic _Complex int)a;
+}
+
 //.
 // CHECK: [[PROF2]] = !{!"branch_weights", i32 1, i32 1048575}
-//.
+//.
\ No newline at end of file

>From 3650b8740fe74dfd6519218ce10ed7ba972872ef Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Wed, 1 Apr 2026 22:57:01 +0200
Subject: [PATCH 3/4] Use getAtomicUnqualifiedType

---
 clang/lib/CodeGen/CGExprComplex.cpp | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprComplex.cpp 
b/clang/lib/CodeGen/CGExprComplex.cpp
index 83c5fa7c6e11f..a97441d3b63c4 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -507,13 +507,12 @@ ComplexPairTy 
ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
                                                            QualType DestType,
                                                            SourceLocation Loc) 
{
   // Get the src/dest element type.
-  if (SrcType->isAtomicType())
-    SrcType = SrcType->castAs<AtomicType>()->getValueType();
-  SrcType = SrcType->castAs<ComplexType>()->getElementType();
-
-  if (DestType->isAtomicType())
-    DestType = DestType->castAs<AtomicType>()->getValueType();
-  DestType = DestType->castAs<ComplexType>()->getElementType();
+  SrcType = SrcType.getAtomicUnqualifiedType()
+                ->castAs<ComplexType>()
+                ->getElementType();
+  DestType = DestType.getAtomicUnqualifiedType()
+                 ->castAs<ComplexType>()
+                 ->getElementType();
 
   // C99 6.3.1.6: When a value of complex type is converted to another
   // complex type, both the real and imaginary parts follow the conversion

>From 8b9f53a144ff58d0cec73975f07727465c71081b Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Thu, 2 Apr 2026 21:48:19 +0200
Subject: [PATCH 4/4] Add missing new line at end of file

---
 clang/docs/ReleaseNotes.rst  | 3 ++-
 clang/test/CodeGen/complex.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 025e87864e5ef..e9a3909d1c9f3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -635,4 +635,5 @@ tree.
 
 If you have any questions or comments about Clang, please feel free to
 contact us on the `Discourse forums (Clang Frontend category)
-<https://discourse.llvm.org/c/clang/6>`_.
\ No newline at end of file
+<https://discourse.llvm.org/c/clang/6>`_.
+
diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index 6616ca4b19a26..932e9afc1d0b8 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -680,4 +680,5 @@ void explicit_cast_complex_to_atomic_complex() {
 
 //.
 // CHECK: [[PROF2]] = !{!"branch_weights", i32 1, i32 1048575}
-//.
\ No newline at end of file
+//.
+

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

Reply via email to