[clang] [clang][SemaCXX] Fix crash when using static_cast to _Atomic types in C++ (PR #207616)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 5 14:57:48 PDT 2026
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/207616
>From 78410a24bfa8d4598c80184007e365e7f293f043 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
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 | 8 +++++++-
clang/test/SemaCXX/atomic-type.cpp | 9 +++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 133837623a7a6..0d0b20a4395f2 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -78,7 +78,13 @@ 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();
+ }
}
if (const BuiltinType *placeholder =
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}}
+ }
+}
+
More information about the cfe-commits
mailing list