https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/207616
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. >From 6d01117fbef1767d1410ff641d922070cea38b46 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++ (e.g. `static_cast<_Atomic(struct S)>(S{})`). When evaluating casts, `CastOperation::CastOperation` in `SemaCast.cpp` 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. Because `_Atomic` was stripped from the destination type in C++, the cast evaluation mechanism built the AST conversion targeting the underlying type `T` (resulting in a `CK_ConstructorConversion` for class types). However, the resulting `CXXStaticCastExpr` node was still created with the original type `_Atomic(T)`. This type mismatch (an atomic node wrapping a constructor conversion targeting a non-atomic struct) triggered assertions during both constant evaluation and code generation. 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 | 5 ++++- clang/test/SemaCXX/atomic-type.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 133837623a7a6..bb137a4bf19d7 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -78,7 +78,10 @@ namespace { // the qualifier. if (!S.Context.getLangOpts().ObjC && !DestType->isRecordType() && !DestType->isArrayType() && !DestType.getPointerAuth()) { - DestType = DestType.getAtomicUnqualifiedType(); + if (S.Context.getLangOpts().CPlusPlus) + 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}} + } +} + _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
