shafik updated this revision to Diff 513412.
shafik added a comment.

Fix DiagnosticSemaKinds.td , was missing an opening quote


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

https://reviews.llvm.org/D146090

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/class/class.compare/class.compare.default/p3.cpp
  clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1480,7 +1480,15 @@
     <tr>
       <td>Relaxing some constexpr restrictions</td>
       <td><a href="https://wg21.link/P2448R2";>P2448R2</a></td>
-      <td class="none" align="center">No</td>
+      <td class="partial" align="center">
+          <details>
+            <summary>Clang 17 (Partial)</summary>
+	    We do not support outside of defaulted special memeber functions the change that constexpr functions no
+            longer have to be constexpr compatible but rather support a less restricted requirements for constexpr
+            functions. Which include allowing non-literal types as return values and paremeters, allow calling of
+            non-constexpr functions and constructors.
+          </details></td>
+       </td>
     </tr>
     <tr>
       <td>Using unknown pointers and references in constant expressions</td>
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
===================================================================
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -242,6 +242,7 @@
 
 // - every constructor involved in initializing non-static data members and base
 //   class sub-objects shall be a constexpr constructor.
+// This will no longer be the case once we support P2448R2
 struct ConstexprBaseMemberCtors : Literal {
   Literal l;
 
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
===================================================================
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -41,6 +41,8 @@
   virtual constexpr int OutOfLineVirtual() const; // beforecxx20-error {{virtual function cannot be constexpr}}
 
   //  - its return type shall be a literal type;
+  // Once we support P2448R2 constexpr functions will be allowd to return non-literal types
+  // The destructor will also be allowed
   constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
   constexpr void VoidReturn() const { return; }                // beforecxx14-error {{constexpr function's return type 'void' is not a literal type}}
   constexpr ~T();                                              // beforecxx20-error {{destructor cannot be declared constexpr}}
@@ -49,6 +51,7 @@
   constexpr F NonLiteralReturn2; // ok until definition
 
   //  - each of its parameter types shall be a literal type;
+  // Once we support P2448R2 constexpr functions will be allowd to have parameters of non-literal types
   constexpr int NonLiteralParam(NonLiteral) const { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
   typedef int G(NonLiteral) const;
   constexpr G NonLiteralParam2; // ok until definition
Index: clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
+++ clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
@@ -1,7 +1,9 @@
 // RUN: %clang_cc1 -std=c++2a -verify %s
+// RUN: %clang_cc1 -std=c++2a -Wc++2b-default-comp-relaxed-constexpr -verify=expected,extension %s
 
 // This test is for [class.compare.default]p3 as modified and renumbered to p4
 // by P2002R0.
+// Also covers modifications made by P2448R2 and extension warnings
 
 namespace std {
   struct strong_ordering {
@@ -76,14 +78,13 @@
 }
 
 struct H {
-  bool operator==(const H&) const; // expected-note {{here}}
+  bool operator==(const H&) const; // extension-note {{non-constexpr comparison function declared here}}
   constexpr std::strong_ordering operator<=>(const H&) const { return std::strong_ordering::equal; }
 };
 
 struct I {
-  H h; // expected-note {{used to compare}}
-  // expected-error@+1 {{defaulted definition of three-way comparison operator cannot be declared constexpr because the corresponding implicit 'operator==' invokes a non-constexpr comparison function}}
-  constexpr std::strong_ordering operator<=>(const I&) const = default;
+  H h; // extension-note {{non-constexpr comparison function would be used to compare member 'h'}}
+  constexpr std::strong_ordering operator<=>(const I&) const = default; // extension-warning {{implicit 'operator=='  invokes a non-constexpr comparison function is a C++2b extension}}
 };
 
 struct J {
@@ -144,3 +145,19 @@
   };
   bool test_d = D() == D();
 }
+
+namespace GH61238 {
+template <typename A> struct my_struct {
+    A value; // extension-note {{non-constexpr comparison function would be used to compare member 'value'}}
+
+    constexpr friend bool operator==(const my_struct &, const my_struct &) noexcept = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
+};
+
+struct non_constexpr_type {
+    friend bool operator==(non_constexpr_type, non_constexpr_type) noexcept { // extension-note {{non-constexpr comparison function declared here}}
+        return false;
+    }
+};
+
+my_struct<non_constexpr_type> obj; // extension-note {{in instantiation of template class 'GH61238::my_struct<GH61238::non_constexpr_type>' requested here}}
+}
Index: clang/test/CXX/class/class.compare/class.compare.default/p3.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.compare.default/p3.cpp
+++ clang/test/CXX/class/class.compare/class.compare.default/p3.cpp
@@ -1,6 +1,8 @@
 // This test is for the [class.compare.default]p3 added by P2002R0
+// Also covers modifications made by P2448R2 and extension warnings
 
 // RUN: %clang_cc1 -std=c++2a -verify %s
+// RUN: %clang_cc1 -std=c++2a -Wc++2b-default-comp-relaxed-constexpr -verify=expected,extension %s
 
 namespace std {
   struct strong_ordering {
@@ -80,10 +82,10 @@
 };
 
 struct C {
-  friend bool operator==(const C&, const C&); // expected-note {{previous}} expected-note 2{{here}}
+  friend bool operator==(const C&, const C&); // expected-note {{previous}} extension-note 2{{non-constexpr comparison function declared here}}
   friend bool operator!=(const C&, const C&) = default; // expected-note {{previous}}
 
-  friend std::strong_ordering operator<=>(const C&, const C&); // expected-note {{previous}} expected-note 2{{here}}
+  friend std::strong_ordering operator<=>(const C&, const C&); // expected-note {{previous}} extension-note 2{{non-constexpr comparison function declared here}}
   friend bool operator<(const C&, const C&) = default; // expected-note {{previous}}
   friend bool operator<=(const C&, const C&) = default; // expected-note {{previous}}
   friend bool operator>(const C&, const C&) = default; // expected-note {{previous}}
@@ -127,23 +129,23 @@
 
 struct E {
   A a;
-  C c; // expected-note 2{{non-constexpr comparison function would be used to compare member 'c'}}
+  C c; // extension-note 2{{non-constexpr comparison function would be used to compare member 'c'}}
   A b;
-  friend constexpr bool operator==(const E&, const E&) = default; // expected-error {{cannot be declared constexpr because it invokes a non-constexpr comparison function}}
+  friend constexpr bool operator==(const E&, const E&) = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
   friend constexpr bool operator!=(const E&, const E&) = default;
 
-  friend constexpr std::strong_ordering operator<=>(const E&, const E&) = default; // expected-error {{cannot be declared constexpr because it invokes a non-constexpr comparison function}}
+  friend constexpr std::strong_ordering operator<=>(const E&, const E&) = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
   friend constexpr bool operator<(const E&, const E&) = default;
   friend constexpr bool operator<=(const E&, const E&) = default;
   friend constexpr bool operator>(const E&, const E&) = default;
   friend constexpr bool operator>=(const E&, const E&) = default;
 };
 
-struct E2 : A, C { // expected-note 2{{non-constexpr comparison function would be used to compare base class 'C'}}
-  friend constexpr bool operator==(const E2&, const E2&) = default; // expected-error {{cannot be declared constexpr because it invokes a non-constexpr comparison function}}
+struct E2 : A, C { // extension-note 2{{non-constexpr comparison function would be used to compare base class 'C'}}
+  friend constexpr bool operator==(const E2&, const E2&) = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
   friend constexpr bool operator!=(const E2&, const E2&) = default;
 
-  friend constexpr std::strong_ordering operator<=>(const E2&, const E2&) = default; // expected-error {{cannot be declared constexpr because it invokes a non-constexpr comparison function}}
+  friend constexpr std::strong_ordering operator<=>(const E2&, const E2&) = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
   friend constexpr bool operator<(const E2&, const E2&) = default;
   friend constexpr bool operator<=(const E2&, const E2&) = default;
   friend constexpr bool operator>(const E2&, const E2&) = default;
@@ -151,14 +153,14 @@
 };
 
 struct F {
-  friend bool operator==(const F&, const F&); // expected-note {{here}}
-  friend constexpr bool operator!=(const F&, const F&) = default; // expected-error {{cannot be declared constexpr because it invokes a non-constexpr comparison function}}
-
-  friend std::strong_ordering operator<=>(const F&, const F&); // expected-note 4{{here}}
-  friend constexpr bool operator<(const F&, const F&) = default; // expected-error {{cannot be declared constexpr because it invokes a non-constexpr comparison function}}
-  friend constexpr bool operator<=(const F&, const F&) = default; // expected-error {{cannot be declared constexpr because it invokes a non-constexpr comparison function}}
-  friend constexpr bool operator>(const F&, const F&) = default; // expected-error {{cannot be declared constexpr because it invokes a non-constexpr comparison function}}
-  friend constexpr bool operator>=(const F&, const F&) = default; // expected-error {{cannot be declared constexpr because it invokes a non-constexpr comparison function}}
+  friend bool operator==(const F&, const F&); // extension-note {{non-constexpr comparison function declared here}}
+  friend constexpr bool operator!=(const F&, const F&) = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
+
+  friend std::strong_ordering operator<=>(const F&, const F&); // extension-note 4{{non-constexpr comparison function declared here}}
+  friend constexpr bool operator<(const F&, const F&) = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
+  friend constexpr bool operator<=(const F&, const F&) = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
+  friend constexpr bool operator>(const F&, const F&) = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
+  friend constexpr bool operator>=(const F&, const F&) = default; // extension-warning {{declared constexpr but invokes a non-constexpr comparison function is a C++2b extension}}
 };
 
 // No implicit 'constexpr' if it's not the first declaration.
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -8808,12 +8808,25 @@
   //   the requirements for a constexpr function [...]
   // The only relevant requirements are that the parameter and return types are
   // literal types. The remaining conditions are checked by the analyzer.
+  //
+  // We support P2448R2 in language modes earlier than C++23 as an extension.
+  // The concept of constexpr-compatible was removed.
+  // C++23 [dcl.fct.def.default]p3 [P2448R2]
+  //  A function explicitly defaulted on its first declaration is implicitly
+  //  inline, and is implicitly constexpr if it is constexpr-suitable.
+  // C++23 [dcl.constexpr]p3
+  //   A function is constexpr-suitable if
+  //    - it is not a coroutine, and
+  //    - if the function is a constructor or destructor, its class does not
+  //      have any virtual base classes.
   if (FD->isConstexpr()) {
     if (CheckConstexprReturnType(*this, FD, CheckConstexprKind::Diagnose) &&
         CheckConstexprParameterTypes(*this, FD, CheckConstexprKind::Diagnose) &&
         !Info.Constexpr) {
       Diag(FD->getBeginLoc(),
-           diag::err_incorrect_defaulted_comparison_constexpr)
+           getLangOpts().CPlusPlus2b
+               ? diag::warn_cxx2b_compat_defaulted_comparison_constexpr_mismatch
+               : diag::ext_defaulted_comparison_constexpr_mismatch)
           << FD->isImplicit() << (int)DCK << FD->isConsteval();
       DefaultedComparisonAnalyzer(*this, RD, FD, DCK,
                                   DefaultedComparisonAnalyzer::ExplainConstexpr)
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9416,12 +9416,21 @@
   "%select{|member|base class}0 %1 declared here">;
 def note_defaulted_comparison_cannot_deduce_callee : Note<
   "selected 'operator<=>' for %select{|member|base class}0 %1 declared here">;
-def err_incorrect_defaulted_comparison_constexpr : Error<
+def ext_defaulted_comparison_constexpr_mismatch : Extension<
   "defaulted definition of %select{%sub{select_defaulted_comparison_kind}1|"
-  "three-way comparison operator}0 "
-  "cannot be declared %select{constexpr|consteval}2 because "
-  "%select{it|the corresponding implicit 'operator=='}0 "
-  "invokes a non-constexpr comparison function">;
+  "three-way comparison operator}0 that is "
+  "declared %select{constexpr|consteval}2 but"
+  "%select{|for which the corresponding implicit 'operator==' }0 "
+  "invokes a non-constexpr comparison function is a C++2b extension">,
+  InGroup<CXX2bDefCompCallsNonConstexpr>;
+def warn_cxx2b_compat_defaulted_comparison_constexpr_mismatch : Warning<
+  "defaulted definition of %select{%sub{select_defaulted_comparison_kind}1|"
+  "three-way comparison operator}0 that is "
+  "declared %select{constexpr|consteval}2 but"
+  "%select{|for which the corresponding implicit 'operator==' }0 "
+  "invokes a non-constexpr comparison function is incompatible with C++ "
+  "standards before C++2b">,
+  InGroup<CXXPre2bCompat>, DefaultIgnore;
 def note_defaulted_comparison_not_constexpr : Note<
   "non-constexpr comparison function would be used to compare "
   "%select{|member %1|base class %1}0">;
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -228,6 +228,7 @@
                  DiagCategory<"Deprecations">;
 
 def CXX20Designator : DiagGroup<"c++20-designator">;
+def CXX2bDefCompCallsNonConstexpr : DiagGroup<"c++2b-default-comp-relaxed-constexpr">;
 // Allow -Wno-c99-designator to be used to turn off all warnings on valid C99
 // designators (including the warning controlled by -Wc++20-designator).
 def C99Designator : DiagGroup<"c99-designator", [CXX20Designator]>;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -100,6 +100,12 @@
   and `P2579R0 Mitigation strategies for P2036 <https://wg21.link/P2579R0>`_.
   These proposals modify how variables captured in lambdas can appear in trailing return type
   expressions and how their types are deduced therein, in all C++ language versions.
+- Implemented partial support for `P2448R2: Relaxing some constexpr restrictions <https://wg21.link/p2448r2>`_
+  Explicitly defaulted functions no longer have to be constexpr-compatible but merely constexpr suitable.
+  We do not support outside of defaulted special memeber functions the change that constexpr functions no
+  longer have to be constexpr compatible but rather support a less restricted requirements for constexpr
+  functions. Which include allowing non-literal types as return values and paremeters, allow calling of
+  non-constexpr functions and constructors.
 
 Resolutions to C++ Defect Reports
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to