Javier-varez updated this revision to Diff 436516.
Javier-varez added a comment.

- Preseve ABI when clang is invoked with -fclang-abi-compat <= 14.
- Add test for defect report in `clang/test/CXX/drs/dr21xx.cpp`.
- Refactor ConstArg to remove if condition.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127593/new/

https://reviews.llvm.org/D127593

Files:
  clang-tools-extra/test/clang-tidy/checkers/modernize-loop-convert-const.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/drs/dr21xx.cpp
  clang/test/CXX/special/class.copy/p12-0x.cpp
  clang/test/CXX/special/class.copy/p25-0x.cpp
  clang/www/cxx_dr_status.html

Index: clang/www/cxx_dr_status.html
===================================================================
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -12840,7 +12840,7 @@
     <td><a href="https://wg21.link/cwg2171";>2171</a></td>
     <td>CD4</td>
     <td>Triviality of copy constructor with less-qualified parameter</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="unreleased" align="center">Clang 15</td>
   </tr>
   <tr class="open" id="2172">
     <td><a href="https://wg21.link/cwg2172";>2172</a></td>
Index: clang/test/CXX/special/class.copy/p25-0x.cpp
===================================================================
--- clang/test/CXX/special/class.copy/p25-0x.cpp
+++ clang/test/CXX/special/class.copy/p25-0x.cpp
@@ -31,7 +31,22 @@
 struct NonConstCopy {
   NonConstCopy &operator=(NonConstCopy &) = default;
 };
-using _ = not_trivially_assignable<NonConstCopy>;
+static_assert(__has_trivial_assign(NonConstCopy), "");
+static_assert(__is_trivially_assignable(NonConstCopy &, NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, const NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy &&), "");
+static_assert(__is_trivially_assignable(NonConstCopy &&, NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, const NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy &&), "");
+
+struct DefaultedSpecialMembers {
+  DefaultedSpecialMembers &operator=(const DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers &operator=(DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers &operator=(DefaultedSpecialMembers &&) = default;
+};
+using _ = trivially_assignable<DefaultedSpecialMembers>;
 
 // class X has no virtual functions
 struct VFn {
Index: clang/test/CXX/special/class.copy/p12-0x.cpp
===================================================================
--- clang/test/CXX/special/class.copy/p12-0x.cpp
+++ clang/test/CXX/special/class.copy/p12-0x.cpp
@@ -28,7 +28,18 @@
 struct NonConstCopy {
   NonConstCopy(NonConstCopy &) = default;
 };
-using _ = not_trivially_copyable<NonConstCopy>;
+static_assert(__has_trivial_copy(NonConstCopy), "");
+static_assert(__is_trivially_constructible(NonConstCopy, NonConstCopy &), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, const NonConstCopy &), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy &&), "");
+
+struct DefaultedSpecialMembers {
+  DefaultedSpecialMembers(const DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers(DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers(DefaultedSpecialMembers &&) = default;
+};
+using _ = trivially_copyable<DefaultedSpecialMembers>;
 
 // class X has no virtual functions
 struct VFn {
Index: clang/test/CXX/drs/dr21xx.cpp
===================================================================
--- clang/test/CXX/drs/dr21xx.cpp
+++ clang/test/CXX/drs/dr21xx.cpp
@@ -140,6 +140,33 @@
 #endif
 }
 
+namespace dr2171 { // dr2171: 15
+#if __cplusplus >= 201103L
+
+struct NonConstCopy {
+  NonConstCopy(NonConstCopy &) = default;
+  NonConstCopy &operator=(NonConstCopy &) = default;
+};
+
+static_assert(__has_trivial_copy(NonConstCopy), "");
+static_assert(__is_trivially_constructible(NonConstCopy, NonConstCopy &), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, const NonConstCopy &), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy &&), "");
+
+static_assert(__has_trivial_assign(NonConstCopy), "");
+static_assert(__is_trivially_assignable(NonConstCopy &, NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, const NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy &&), "");
+static_assert(__is_trivially_assignable(NonConstCopy &&, NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, const NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy &&), "");
+
+#endif
+} // namespace dr2171
+
 namespace dr2180 { // dr2180: yes
   class A {
     A &operator=(const A &); // expected-note 0-2{{here}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -9772,11 +9772,14 @@
 
   case CXXCopyConstructor:
   case CXXCopyAssignment: {
-    // Trivial copy operations always have const, non-volatile parameter types.
-    ConstArg = true;
     const ParmVarDecl *Param0 = MD->getParamDecl(0);
     const ReferenceType *RT = Param0->getType()->getAs<ReferenceType>();
-    if (!RT || RT->getPointeeType().getCVRQualifiers() != Qualifiers::Const) {
+
+    const bool ClangABICompat14 = Context.getLangOpts().getClangABICompat() <=
+                                  LangOptions::ClangABI::Ver14;
+    if (!RT ||
+        ((RT->getPointeeType().getCVRQualifiers() != Qualifiers::Const) &&
+         ClangABICompat14)) {
       if (Diagnose)
         Diag(Param0->getLocation(), diag::note_nontrivial_param_type)
           << Param0->getSourceRange() << Param0->getType()
@@ -9784,6 +9787,8 @@
                Context.getRecordType(RD).withConst());
       return false;
     }
+
+    ConstArg = RT->getPointeeType().isConstQualified();
     break;
   }
 
Index: clang-tools-extra/test/clang-tidy/checkers/modernize-loop-convert-const.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/modernize-loop-convert-const.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize-loop-convert-const.cpp
@@ -10,12 +10,12 @@
 };
 
 // This class is non-trivially copyable because the copy-constructor and copy
-// assignment take non-const references.
+// assignment take non-const references and are user-provided.
 struct ModifiesRightSide {
   ModifiesRightSide() = default;
-  ModifiesRightSide(ModifiesRightSide &) = default;
+  ModifiesRightSide(ModifiesRightSide &);
   bool operator<(ModifiesRightSide &) const;
-  ModifiesRightSide &operator=(ModifiesRightSide &) = default;
+  ModifiesRightSide &operator=(ModifiesRightSide &);
 };
 
 template <typename T>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to