Skip to content

Conversation

@AmrDeveloper
Copy link
Member

@AmrDeveloper AmrDeveloper commented Dec 14, 2025

Fixed a crash when explicitly casting between atomic complex types

resolve: #172208

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Dec 14, 2025
@llvmbot
Copy link
Member

llvmbot commented Dec 14, 2025

@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

Changes

Fixed a crash when explicitly casting between atomic complex types

resolve: #172163


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

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+1)
  • (modified) clang/lib/CodeGen/CGExprComplex.cpp (+5)
  • (modified) clang/test/CodeGen/complex.c (+29)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index feaf92ad4415f..b6ff1734b78f8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -800,6 +800,7 @@ Crash and bug fixes
   containing a single colon. (#GH167905)
 - Fixed a crash when parsing malformed #pragma clang loop vectorize_width(4,8,16)
   by diagnosing invalid comma-separated argument lists. (#GH166325)
+- Fixed a crash when explicitly casting between atomic complex types. (#GH172208)
 
 Improvements
 ^^^^^^^^^^^^
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index e5815ef1130dc..151b9473eb39c 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -515,7 +515,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 91fc9dda72f72..c789d6e7c3ed7 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -593,3 +593,32 @@ 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;
+}

containing a single colon. (#GH167905)
- Fixed a crash when parsing malformed #pragma clang loop vectorize_width(4,8,16)
by diagnosing invalid comma-separated argument lists. (#GH166325)
- Fixed a crash when explicitly casting between atomic complex types. (#GH172208)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this reads like the crash only occurs if both source and destination are atomic complex types, but I think the crash occurs when either source or destination are atomic complex. Maybe something like:
"Fixed a crash when explicitly casting a complex type to or from an atomic complex type."?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, makes sense, also I should add test cases for that too :D, Thanks for the comment, I will update the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Clang] crashes with casting between _Atomic _Complex types

3 participants