Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -82,7 +82,9 @@ alias, target) identifier instead of only processing one such ``#pragma weak`` per identifier. Fixes `Issue 28985 `_. - +- Assignment expressions in C11 and later mode now properly strip the _Atomic + qualifier when determining the type of the assignment expression. Fixes + `Issue 48742 `_. - Unevaluated lambdas in dependant contexts no longer result in clang crashing. This fixes Issues `50376 `_, `51414 `_, Index: clang/include/clang/AST/Type.h =================================================================== --- clang/include/clang/AST/Type.h +++ clang/include/clang/AST/Type.h @@ -931,6 +931,10 @@ /// The resulting type might still be qualified if it's sugar for an array /// type. To strip qualifiers even from within a sugared array type, use /// ASTContext::getUnqualifiedArrayType. + /// + /// Note: In C, the _Atomic qualifier is special (see C2x 6.2.5p29 for + /// details), and it is not stripped by this function. Use + /// getAtomicUnqualifiedType() to strip qualifiers including _Atomic. inline QualType getUnqualifiedType() const; /// Retrieve the unqualified variant of the given type, removing as little Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -13644,8 +13644,7 @@ // is converted to the type of the assignment expression (above). // C++ 5.17p1: the type of the assignment expression is that of its left // operand. - return (getLangOpts().CPlusPlus - ? LHSType : LHSType.getUnqualifiedType()); + return getLangOpts().CPlusPlus ? LHSType : LHSType.getAtomicUnqualifiedType(); } // Only ignore explicit casts to void. Index: clang/test/Sema/atomic-expr.c =================================================================== --- clang/test/Sema/atomic-expr.c +++ clang/test/Sema/atomic-expr.c @@ -61,3 +61,17 @@ int func_14 (void) { return data1 == 0; } + +void func_15(void) { + // Ensure that the result of an assignment expression properly strips the + // _Atomic qualifier; Issue 48742. + _Atomic int x; + int y = (x = 2); + int z = (int)(x = 2); + y = (x = 2); + z = (int)(x = 2); + y = (x += 2); + + _Static_assert(__builtin_types_compatible_p(__typeof__(x = 2), int), "incorrect"); + _Static_assert(__builtin_types_compatible_p(__typeof__(x += 2), int), "incorrect"); +}