https://github.com/AZero13 updated 
https://github.com/llvm/llvm-project/pull/207616

>From d4842c23d721dfb03eee6721c2ecb0fb44d378dd Mon Sep 17 00:00:00 2001
From: AZero13 <[email protected]>
Date: Sun, 5 Jul 2026 17:50:56 -0400
Subject: [PATCH] [clang][SemaCXX] Fix crash when using static_cast to _Atomic
 types in C++

This PR fixes a compiler crash (assertion failure) in both the constant 
evaluator (ExprConstant.cpp) and LLVM CodeGen (CGExprAgg.cpp) when evaluating a 
static_cast to an _Atomic type in C++.

When evaluating casts, CastOperation::CastOperation in was unconditionally 
stripping the _Atomic qualifier from the destination type using 
getAtomicUnqualifiedType(). This behavior is correct for C23 (under C23 
6.5.4p6, where cast expressions yield the non-atomic version of the type), but 
it is incorrect for C++ where _Atomic(T) is treated as a distinct type wrapper.

Modify CastOperation::CastOperation to only strip the _Atomic qualifier in C 
mode. In C++ mode, we preserve the _Atomic wrapper, ensuring that 
InitializationSequence properly evaluates the target type as _Atomic(T) and 
adds the implicit CK_NonAtomicToAtomic conversion step.

Fixes #207610.
---
 clang/lib/Sema/SemaCast.cpp        | 12 +++++++++++-
 clang/test/Sema/atomic-type.c      |  4 ++++
 clang/test/SemaCXX/atomic-type.cpp |  9 +++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 133837623a7a6..2f67087a365a2 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -78,7 +78,17 @@ namespace {
       // the qualifier.
       if (!S.Context.getLangOpts().ObjC && !DestType->isRecordType() &&
           !DestType->isArrayType() && !DestType.getPointerAuth()) {
-        DestType = DestType.getAtomicUnqualifiedType();
+        if (S.Context.getLangOpts().CPlusPlus) {
+          // Note that in C++, _Atomic(T) is a distinct type, not a
+          // cv-qualifier, so it is not stripped.
+          DestType = DestType.getUnqualifiedType();
+        } else {
+          DestType = DestType.getAtomicUnqualifiedType();
+        }
+
+        // Ensure ResultType matches the stripped DestType (e.g., dropping
+        // _Atomic in C)
+        ResultType = DestType.getNonLValueExprType(S.Context);
       }
 
       if (const BuiltinType *placeholder =
diff --git a/clang/test/Sema/atomic-type.c b/clang/test/Sema/atomic-type.c
index 3f171e4000d93..96c9342f8049a 100644
--- a/clang/test/Sema/atomic-type.c
+++ b/clang/test/Sema/atomic-type.c
@@ -20,3 +20,7 @@ _Atomic(struct ErrorS) error2; // expected-error {{_Atomic 
cannot be applied to
 _Atomic(int[10]) error3; // expected-error {{_Atomic cannot be applied to 
array type}}
 _Atomic(const int) error4; // expected-error {{_Atomic cannot be applied to 
qualified type}}
 _Atomic(_Atomic(int)) error5; // expected-error {{_Atomic cannot be applied to 
atomic type}}
+
+void test_cast_to_atomic(void) {
+  _Static_assert(_Generic((_Atomic int)12, _Atomic int: 1, int: 0) == 0, "cast 
to atomic drops _Atomic");
+}
diff --git a/clang/test/SemaCXX/atomic-type.cpp 
b/clang/test/SemaCXX/atomic-type.cpp
index 3200a59bc86a2..b8f8f184da643 100644
--- a/clang/test/SemaCXX/atomic-type.cpp
+++ b/clang/test/SemaCXX/atomic-type.cpp
@@ -111,3 +111,12 @@ namespace non_trivially_copyable {
   _Atomic S s;  // expected-error {{_Atomic cannot be applied to type 'S' 
which is not trivially copyable}} \
                 // expected-warning {{'_Atomic' is a C11 extension}}
 }
+
+namespace static_cast_crash {
+  struct S { char a; };
+  void static_cast_non_atomic_to_atomic() {
+    _Atomic struct S a; // expected-warning {{'_Atomic' is a C11 extension}}
+    a = static_cast<_Atomic(struct S)>(S()); // expected-warning {{'_Atomic' 
is a C11 extension}}
+  }
+}
+

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

Reply via email to