Skip to content

Commit 63a82dd

Browse files
committed
[C11] Allow casting to an _Atomic-qualified type
We were failing to strip off atomic qualification when forming the cast destination type, but properly stripping off cvr qualification. Now we accept atomic, qualified, or unqualified destination types. Note: the semantics of the cast still drop the qualifier, so such a cast does not result in an atomic rvalue. Fixes #39596
1 parent 2fce50e commit 63a82dd

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ C Language Changes
112112
added. (`#53562 <https://github.com/llvm/llvm-project/issues/53562>`_)
113113
- Fixed a bug that prevented initialization of an ``_Atomic``-qualified pointer
114114
from a null pointer constant.
115+
- Fixed a bug that prevented casting to an ``_Atomic``-qualified type.
116+
(`#39596 <https://github.com/llvm/llvm-project/issues/39596>`_)
115117

116118
C2x Feature Support
117119
^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaCast.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,13 @@ namespace {
6565
// If a pr-value initially has the type cv-T, where T is a
6666
// cv-unqualified non-class, non-array type, the type of the
6767
// expression is adjusted to T prior to any further analysis.
68+
// C2x 6.5.4p6:
69+
// Preceding an expression by a parenthesized type name converts the
70+
// value of the expression to the unqualified, non-atomic version of
71+
// the named type.
6872
if (!S.Context.getLangOpts().ObjC && !DestType->isRecordType() &&
6973
!DestType->isArrayType()) {
70-
DestType = DestType.getUnqualifiedType();
74+
DestType = DestType.getAtomicUnqualifiedType();
7175
}
7276

7377
if (const BuiltinType *placeholder =

clang/test/Sema/atomic-expr.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,14 @@ _Atomic(int *) aip3 = &ai; /* expected-warning {{incompatible pointer types init
205205
// Test the behavior when converting the null pointer constant to an atomic
206206
// function pointer.
207207
_Atomic(int (*)(char)) afp = (void *)0;
208+
209+
void func_18(void) {
210+
// Ensure we can cast to atomic scalar types.
211+
data2 = (_Atomic int)0;
212+
(void)(_Atomic(int *))0;
213+
214+
// But that we correctly reject casts to atomic aggregate types.
215+
struct S { int a; } s;
216+
struct T { int a; };
217+
(void)(_Atomic struct T)s; // expected-error {{used type 'struct T' where arithmetic or pointer type is required}}
218+
}

0 commit comments

Comments
 (0)