[PATCH] D122496: [C11] Correct the resulting type for an assignment expression

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 25 11:58:33 PDT 2022


aaron.ballman created this revision.
aaron.ballman added reviewers: eli.friedman, jyknight, erichkeane, clang-language-wg.
Herald added a project: All.
aaron.ballman requested review of this revision.
Herald added a project: clang.

In C, assignment expressions result in an rvalue whose type is the type of the lhs of the assignment after it undergoes lvalue to rvalue conversion. lvalue to rvalue conversion in C strips all qualifiers including `_Atomic`.

We used `getUnqualifiedType()` which does not strip the `_Atomic` qualifier when we should have used `getAtomicUnqualifiedType()`. This corrects the usage and adds some comments to `getUnqualifiedType()` to make it more clear that it does not strip `_Atomic` and that's on purpose (see C11 6.2.5p27).

This addresses Issue 48742.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122496

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/Type.h
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Sema/atomic-expr.c


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");
+}
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/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/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 <https://github.com/llvm/llvm-project/issues/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 <https://github.com/llvm/llvm-project/issues/48742>`_.
 - Unevaluated lambdas in dependant contexts no longer result in clang crashing.
   This fixes Issues `50376 <https://github.com/llvm/llvm-project/issues/50376>`_,
   `51414 <https://github.com/llvm/llvm-project/issues/51414>`_,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D122496.418287.patch
Type: text/x-patch
Size: 2798 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220325/d476344d/attachment.bin>


More information about the cfe-commits mailing list