[PATCH] D128750: [C++20] Implement P2113R0: Changes to the Partial Ordering of Constrained Functions

2022-08-30 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

I looked at the new `Concept auto` changes, they seem fine.

Thanks a LOT @ychen for working on this, it's been a very interesting patch to 
me :)
I'll let @mizvekov accept since he is much more experienced than me in those 
areas.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128750

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133044: [Frontend] Restore Preprocessor::getPredefines()

2022-08-31 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a subscriber: kristof.beyls.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

A patch from May removed Preprocessor::getPredefines() from Clang's API, 
probably as a cleanup because
this method was unused in the LLVM codebase.

However, it was/is used by a small number of third-party tools and is pretty 
harmless, so this patch adds it back
and documents why it's here.

The issue was raised in https://github.com/llvm/llvm-project/issues/57483, it 
would be nice to be able to
land it into Clang 15 as it breaks those third-party tools and we can't easily 
add it back in bug fix releases.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133044

Files:
  clang/include/clang/Lex/Preprocessor.h


Index: clang/include/clang/Lex/Preprocessor.h
===
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -1375,6 +1375,10 @@
   StringRef getLastMacroWithSpelling(SourceLocation Loc,
  ArrayRef Tokens) const;
 
+  /// Get the predefines for this processor.
+  /// Used by some third-party tools to inspect and add predefines.
+  const std::string &getPredefines() const { return Predefines; }
+
   /// Set the predefines for this Preprocessor.
   ///
   /// These predefines are automatically injected when parsing the main file.


Index: clang/include/clang/Lex/Preprocessor.h
===
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -1375,6 +1375,10 @@
   StringRef getLastMacroWithSpelling(SourceLocation Loc,
  ArrayRef Tokens) const;
 
+  /// Get the predefines for this processor.
+  /// Used by some third-party tools to inspect and add predefines.
+  const std::string &getPredefines() const { return Predefines; }
+
   /// Set the predefines for this Preprocessor.
   ///
   /// These predefines are automatically injected when parsing the main file.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133044: [Frontend] Restore Preprocessor::getPredefines()

2022-08-31 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 457070.
royjacobson edited the summary of this revision.
royjacobson added a comment.

Add a link to github issue.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133044

Files:
  clang/include/clang/Lex/Preprocessor.h


Index: clang/include/clang/Lex/Preprocessor.h
===
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -1375,6 +1375,11 @@
   StringRef getLastMacroWithSpelling(SourceLocation Loc,
  ArrayRef Tokens) const;
 
+  /// Get the predefines for this processor.
+  /// Used by some third-party tools to inspect and add predefines (see
+  /// https://github.com/llvm/llvm-project/issues/57483).
+  const std::string &getPredefines() const { return Predefines; }
+
   /// Set the predefines for this Preprocessor.
   ///
   /// These predefines are automatically injected when parsing the main file.


Index: clang/include/clang/Lex/Preprocessor.h
===
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -1375,6 +1375,11 @@
   StringRef getLastMacroWithSpelling(SourceLocation Loc,
  ArrayRef Tokens) const;
 
+  /// Get the predefines for this processor.
+  /// Used by some third-party tools to inspect and add predefines (see
+  /// https://github.com/llvm/llvm-project/issues/57483).
+  const std::string &getPredefines() const { return Predefines; }
+
   /// Set the predefines for this Preprocessor.
   ///
   /// These predefines are automatically injected when parsing the main file.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133044: [Frontend] Restore Preprocessor::getPredefines()

2022-08-31 Thread Roy Jacobson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbb9dedce5d01: [Frontend] Restore 
Preprocessor::getPredefines() (authored by royjacobson).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133044

Files:
  clang/include/clang/Lex/Preprocessor.h


Index: clang/include/clang/Lex/Preprocessor.h
===
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -1375,6 +1375,11 @@
   StringRef getLastMacroWithSpelling(SourceLocation Loc,
  ArrayRef Tokens) const;
 
+  /// Get the predefines for this processor.
+  /// Used by some third-party tools to inspect and add predefines (see
+  /// https://github.com/llvm/llvm-project/issues/57483).
+  const std::string &getPredefines() const { return Predefines; }
+
   /// Set the predefines for this Preprocessor.
   ///
   /// These predefines are automatically injected when parsing the main file.


Index: clang/include/clang/Lex/Preprocessor.h
===
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -1375,6 +1375,11 @@
   StringRef getLastMacroWithSpelling(SourceLocation Loc,
  ArrayRef Tokens) const;
 
+  /// Get the predefines for this processor.
+  /// Used by some third-party tools to inspect and add predefines (see
+  /// https://github.com/llvm/llvm-project/issues/57483).
+  const std::string &getPredefines() const { return Predefines; }
+
   /// Set the predefines for this Preprocessor.
   ///
   /// These predefines are automatically injected when parsing the main file.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133262: [clang] Represent __make_integer_seq as alias template in the AST

2022-09-03 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

There are some known bugs about how we handle this built-in in the AST- #42102, 
#51928, #54993. Is it possible that your patch solves them? It would be great 
if it does, I hit one of them in the wild a while back.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133262

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133262: [clang] Fixes how we represent / emulate builtin templates

2022-09-08 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D133262#3775375 , @mizvekov wrote:

> @royjacobson I decided to do a complete job here and fix all those issues 
> except #54993. Can you confirm?
>
> I also applied the same idea to `type_pack_element` as I saw a crash related 
> to that in the wild.

That's amazing to hear, thanks for looking at it! I haven't had time to check 
it yet, but could you add the snippets from the bug reports as regression tests?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133262

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133262: [clang] Fixes how we represent / emulate builtin templates

2022-09-08 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D133262#3778555 , @mizvekov wrote:

> The snippets from the bug reports are using libc++ and 
> std::make_integer_sequence directly, which we avoid in these kinds of 
> regression tests, we tend to make very reduced test cases that compile 
> standalone.
>
> But I believe I included reductions that should show we fixed the same 
> problem, unless I missed some specific case.

I haven't seen something similar enough to the default template argument case 
from 42102, so it would be nice to add that one. `std::make_integer_sequence` 
is just a type alias template to the builtin, so you can do

  template  struct A {};
  
  // GH42102
  
  template
  using make_index_sequence = __make_integer_seq;
  
  template >
  struct FooList;
  template 
  struct FooList> { };
  
  template 
  void foobar(FooList) { }
  
  void test() { 
foobar(FooList<5>{});
  }
  
  // GH51928
  
  template 
  struct X;
  
  template 
  struct X> {
  };
  
  X> x;

to get unittests without libc++.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133262

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-11 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson updated this revision to Diff 459334.
royjacobson added a comment.
royjacobson updated this revision to Diff 459349.
royjacobson updated this revision to Diff 459355.
royjacobson retitled this revision from "[Clang] Implement static operator()" 
to "[Clang] P1169R4: static operator()".
royjacobson edited the summary of this revision.
royjacobson added a reviewer: clang-language-wg.
royjacobson published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

missing newline


royjacobson added a comment.

Fix the tests, add a CodeGen test.


royjacobson added a comment.

Fix diagnosing static operators that are not call.


Implements 'P1169R4: static operator()' from C++2b.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133659

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/OperatorKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/CXX/over/over.oper/over.literal/p7.cpp
  clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
  clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
  clang/test/Parser/cxx2b-lambdas.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1481,7 +1481,7 @@
 
   static operator()
   https://wg21.link/P1169R4";>P1169R4
-  No
+  Clang 16
 
 
   Extended floating-point types and standard names
Index: clang/test/Parser/cxx2b-lambdas.cpp
===
--- clang/test/Parser/cxx2b-lambdas.cpp
+++ clang/test/Parser/cxx2b-lambdas.cpp
@@ -38,3 +38,16 @@
 auto XL4 = [] requires true {}; // expected-error{{expected body}}
 auto XL5 = [] requires true requires true {}; // expected-error{{expected body}}
 auto XL6 = [] requires true noexcept requires true {}; // expected-error{{expected body}}
+
+auto XL7 = []() static static {}; // expected-error {{cannot appear multiple times}}
+auto XL8 = []() static mutable {}; // expected-error {{cannot be both mutable and static}}
+
+auto XL9 = [] static {};
+auto XL10 = []() static {};
+
+void static_captures() {
+  int x;
+  auto SC1 = [&]() static {}; // expected-error {{a static lambda cannot capture}}
+  auto SC2 = [&x]() static {}; // expected-error {{a static lambda cannot capture}}
+  auto SC3 = [=]() static {}; // expected-error {{a static lambda cannot capture}}
+}
Index: clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,cxx20
+// RUN: %clang_cc1 -std=c++2b %s -verify=expected,cxx2b
+
+//cxx2b-no-diagnostics
+
+auto L1 = [] constexpr {}; // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
+auto L2 = []() static {}; // cxx20-warning {{static lambdas is a C++2b extension}}
+auto L3 = [] static {}; // cxx20-warning {{static lambdas is a C++2b extension}} // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
Index: clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -o - | FileCheck %s
+
+struct Functor {
+  static int operator()(int x, int y) {
+return x + y;
+  }
+};
+
+auto GetALambda() {
+  return [](int x, int y) static {
+return x + y;
+  };
+}
+
+void CallsTheLambda() {
+  GetALambda()(1, 2);
+}
+
+// CHECK:  define dso_local void @_Z14CallsTheLambdav() {{.*}} {
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   %call = call noundef i32 @"_ZZ10GetALambdavEN3$_0clEii"(i32 noundef 1, i32 noundef 2)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
+
+void call_static_call_operator() {
+  Functor f;
+  f(101, 102);
+  f.operator()(201, 202);
+  Functor{}(301, 302);
+}
+
+// CHECK:  define dso_local void @_Z25call_static_call_operatorv() {{.*}} {
+// CHECK-NEXT: entry:
+// CHECK:%call = call noundef i32 @_ZN7FunctorclEii(i32 noundef 101, i32 noundef 102)
+// CHECK-NEXT:   %call1 = call noundef i32 @_ZN7FunctorclEii(i32 noundef 201, i32 noundef 202)
+// CHECK-NEXT:   %call2 = call noundef i32 @_ZN7FunctorclEii(i32 noundef 301, i32 noundef 302)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
Index: clang/test/CXX/over/over.oper/over.literal/p7.cpp
===

[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-11 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 459361.
royjacobson edited the summary of this revision.
royjacobson added a comment.

Fix codegen test on windows, rebase on main.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/OperatorKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/CXX/over/over.oper/over.literal/p7.cpp
  clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
  clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
  clang/test/Parser/cxx2b-lambdas.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1481,7 +1481,7 @@
 
   static operator()
   https://wg21.link/P1169R4";>P1169R4
-  No
+  Clang 16
 
 
   Extended floating-point types and standard names
Index: clang/test/Parser/cxx2b-lambdas.cpp
===
--- clang/test/Parser/cxx2b-lambdas.cpp
+++ clang/test/Parser/cxx2b-lambdas.cpp
@@ -38,3 +38,16 @@
 auto XL4 = [] requires true {}; // expected-error{{expected body}}
 auto XL5 = [] requires true requires true {}; // expected-error{{expected body}}
 auto XL6 = [] requires true noexcept requires true {}; // expected-error{{expected body}}
+
+auto XL7 = []() static static {}; // expected-error {{cannot appear multiple times}}
+auto XL8 = []() static mutable {}; // expected-error {{cannot be both mutable and static}}
+
+auto XL9 = [] static {};
+auto XL10 = []() static {};
+
+void static_captures() {
+  int x;
+  auto SC1 = [&]() static {}; // expected-error {{a static lambda cannot capture}}
+  auto SC2 = [&x]() static {}; // expected-error {{a static lambda cannot capture}}
+  auto SC3 = [=]() static {}; // expected-error {{a static lambda cannot capture}}
+}
Index: clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,cxx20
+// RUN: %clang_cc1 -std=c++2b %s -verify=expected,cxx2b
+
+//cxx2b-no-diagnostics
+
+auto L1 = [] constexpr {}; // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
+auto L2 = []() static {}; // cxx20-warning {{static lambdas is a C++2b extension}}
+auto L3 = [] static {}; // cxx20-warning {{static lambdas is a C++2b extension}} // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
Index: clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s
+
+struct Functor {
+  static int operator()(int x, int y) {
+return x + y;
+  }
+};
+
+auto GetALambda() {
+  return [](int x, int y) static {
+return x + y;
+  };
+}
+
+void CallsTheLambda() {
+  GetALambda()(1, 2);
+}
+
+// CHECK:  define {{.*}}CallsTheLambda{{.*}}
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   %call = call noundef i32 {{.*}}(i32 noundef 1, i32 noundef 2)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
+
+void call_static_call_operator() {
+  Functor f;
+  f(101, 102);
+  f.operator()(201, 202);
+  Functor{}(301, 302);
+}
+
+// CHECK:  define {{.*}}call_static_call_operator{{.*}}
+// CHECK-NEXT: entry:
+// CHECK:{{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 101, i32 noundef 102)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 201, i32 noundef 202)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 301, i32 noundef 302)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
Index: clang/test/CXX/over/over.oper/over.literal/p7.cpp
===
--- clang/test/CXX/over/over.oper/over.literal/p7.cpp
+++ clang/test/CXX/over/over.oper/over.literal/p7.cpp
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 -std=c++11 %s -verify
-// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11
+// RUN: %clang_cc1 -std=c++2b %s -verify=expected,cxx2b
+
+//cxx2b-no-diagnostics
+
 
 constexpr int operator "" _a(const char *c) {
   return c[0];
@@ -15,3 +18,8 @@
   operator "" _puts("f

[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-11 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson marked 2 inline comments as done.
royjacobson added a comment.

Wow, thanks for the quick review!

In D133659#3783008 , @cor3ntin wrote:

> Thanks a lot for working on that!
>
> I think this is the right direction but i would like to see more tests.
> Notably:
>
> - converting a lambda with a static operator to a pointer

Turns out I had a bug in the conversion function generation, thanks for the 
suggestion! Fixed it and added tests.

> - tests in dependant contexts

Added some tests for that, but I'm not sure how to judge if I have good 
coverage of all the possible edge cases, so more suggestions are welcome :)

> - classes having both static and non-static `operator()` . especially the 
> example in 
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1169r4.html#overload-resolution
>  deserves a test.

I _think_ you can't do that - 
https://stackoverflow.com/questions/5365689/c-overload-static-function-with-non-static-function.

The example from the paper is about disambiguating the 
conversion-to-function-pointer call from the operator(), which is kind-of 
already tested because otherwise you wouldn't be able to call a static lambda 
at all. I added it as an explicit test, though.

> - unevaluated lambda tests / constexpr tests

I'm not sure I understand what you mean by unevaluated lambdas, could you 
elaborate? I added some constexpr/eval tests.

> There is the question of whether we'd want the call operator to be implicitly 
> static but I'm don't think it's currently allowed, it may have abi impact and 
> it doesn't to be dealt with in this PR so that should not hold us.
> The other question is whether we want to make static operator() an extension 
> in older language modes. I don;t see a reason to prohibit that (with a 
> warning)

I thought I made it an extension, but apparently it was only for the static 
lambdas, just because that's how most of the other lambda extensions were 
implemented :)
I don't have a strong opinion about this. But I realized that without 
backporting the overload resolution changes, this will not be useful for 
lambdas.
So just to be consistent right now I made it an error for both - we can always 
change that to a warning pretty easily.




Comment at: clang/lib/Sema/SemaLambda.cpp:954-955
 //   by mutable. It is neither virtual nor declared volatile. [...]
-if (!FTI.hasMutableQualifier()) {
+if (!FTI.hasMutableQualifier() &&
+ParamInfo.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) 
{
   FTI.getOrCreateMethodQualifiers().SetTypeQual(DeclSpec::TQ_const,

cor3ntin wrote:
> Do we actually need that check ? It should be diagnosed already.
It's not about diagnosing, it's preventing declaring the operator 'const' if 
it's static.




Comment at: clang/test/CXX/over/over.oper/over.literal/p7.cpp:23-25
+struct Functor {
+  static int operator()(int a, int b);  // cxx11-error {{cannot be a static 
member function}}
+};

cor3ntin wrote:
> This doesn't really seem to be the right file for this test - I'd expect that 
> to be in a test file where we do sema check on operators, not literal 
> operators.
> Do you need help looking for a better place?
Oops, this is the wrong p7 indeed :)

thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-11 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 459387.
royjacobson marked an inline comment as done.
royjacobson added a comment.

Fix conversion to function pointer, add more tests and apply Corentin's wording.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/OperatorKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/CXX/over/over.match/over.match.best/over.best.ics/p6.cpp
  clang/test/CXX/over/over.oper/p7.cpp
  clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
  clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
  clang/test/Parser/cxx2b-lambdas.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1481,7 +1481,7 @@
 
   static operator()
   https://wg21.link/P1169R4";>P1169R4
-  No
+  Clang 16
 
 
   Extended floating-point types and standard names
Index: clang/test/Parser/cxx2b-lambdas.cpp
===
--- clang/test/Parser/cxx2b-lambdas.cpp
+++ clang/test/Parser/cxx2b-lambdas.cpp
@@ -38,3 +38,16 @@
 auto XL4 = [] requires true {}; // expected-error{{expected body}}
 auto XL5 = [] requires true requires true {}; // expected-error{{expected body}}
 auto XL6 = [] requires true noexcept requires true {}; // expected-error{{expected body}}
+
+auto XL7 = []() static static {}; // expected-error {{cannot appear multiple times}}
+auto XL8 = []() static mutable {}; // expected-error {{cannot be both mutable and static}}
+
+auto XL9 = [] static {};
+auto XL10 = []() static {};
+
+void static_captures() {
+  int x;
+  auto SC1 = [&]() static {}; // expected-error {{a static lambda cannot have any captures}}
+  auto SC2 = [&x]() static {}; // expected-error {{a static lambda cannot have any captures}}
+  auto SC3 = [=]() static {}; // expected-error {{a static lambda cannot have any captures}}
+}
Index: clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,cxx20
+// RUN: %clang_cc1 -std=c++2b %s -verify=expected,cxx2b
+
+//cxx2b-no-diagnostics
+
+auto L1 = [] constexpr {}; // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
+auto L2 = []() static {}; // cxx20-error {{static lambdas is a C++2b extension}}
+auto L3 = [] static {}; // cxx20-error {{static lambdas is a C++2b extension}} // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
Index: clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s
+
+struct Functor {
+  static int operator()(int x, int y) {
+return x + y;
+  }
+};
+
+auto GetALambda() {
+  return [](int x, int y) static {
+return x + y;
+  };
+}
+
+void CallsTheLambda() {
+  GetALambda()(1, 2);
+}
+
+// CHECK:  define {{.*}}CallsTheLambda{{.*}}
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   %call = call noundef i32 {{.*}}(i32 noundef 1, i32 noundef 2)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
+
+void call_static_call_operator() {
+  Functor f;
+  f(101, 102);
+  f.operator()(201, 202);
+  Functor{}(301, 302);
+}
+
+// CHECK:  define {{.*}}call_static_call_operator{{.*}}
+// CHECK-NEXT: entry:
+// CHECK:{{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 101, i32 noundef 102)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 201, i32 noundef 202)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 301, i32 noundef 302)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
+
+struct FunctorConsteval {
+  consteval static int operator()(int x, int y) {
+  return x + y;
+  }
+};
+
+struct FunctorConstexpr {
+  constexpr static int operator()(int x, int y) {
+  return x + y;
+  }
+};
+
+constexpr auto my_lambda = []() constexpr {
+  return 3;
+};
+
+void test_consteval_constexpr() {
+  int x = 0;
+  int y = FunctorConstexpr{}(x, 2);
+  constexpr int z1 = FunctorConsteval{}(2, 2);
+  constexpr int z2 = FunctorC

[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-12 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 459413.
royjacobson added a comment.

Fix test after warning text change


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/OperatorKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/CXX/over/over.match/over.match.best/over.best.ics/p6.cpp
  clang/test/CXX/over/over.oper/p7.cpp
  clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
  clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
  clang/test/Parser/cxx2b-lambdas.cpp
  clang/test/SemaCXX/overloaded-operator-decl.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1481,7 +1481,7 @@
 
   static operator()
   https://wg21.link/P1169R4";>P1169R4
-  No
+  Clang 16
 
 
   Extended floating-point types and standard names
Index: clang/test/SemaCXX/overloaded-operator-decl.cpp
===
--- clang/test/SemaCXX/overloaded-operator-decl.cpp
+++ clang/test/SemaCXX/overloaded-operator-decl.cpp
@@ -51,7 +51,7 @@
 
 namespace PR14120 {
   struct A {
-static void operator()(int& i) { ++i; } // expected-error{{overloaded 'operator()' cannot be a static member function}}
+static void operator()(int& i) { ++i; } // expected-error{{overloaded 'operator()' cannot be declared static}}
   };
   void f() {
 int i = 0;
Index: clang/test/Parser/cxx2b-lambdas.cpp
===
--- clang/test/Parser/cxx2b-lambdas.cpp
+++ clang/test/Parser/cxx2b-lambdas.cpp
@@ -38,3 +38,16 @@
 auto XL4 = [] requires true {}; // expected-error{{expected body}}
 auto XL5 = [] requires true requires true {}; // expected-error{{expected body}}
 auto XL6 = [] requires true noexcept requires true {}; // expected-error{{expected body}}
+
+auto XL7 = []() static static {}; // expected-error {{cannot appear multiple times}}
+auto XL8 = []() static mutable {}; // expected-error {{cannot be both mutable and static}}
+
+auto XL9 = [] static {};
+auto XL10 = []() static {};
+
+void static_captures() {
+  int x;
+  auto SC1 = [&]() static {}; // expected-error {{a static lambda cannot have any captures}}
+  auto SC2 = [&x]() static {}; // expected-error {{a static lambda cannot have any captures}}
+  auto SC3 = [=]() static {}; // expected-error {{a static lambda cannot have any captures}}
+}
Index: clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,cxx20
+// RUN: %clang_cc1 -std=c++2b %s -verify=expected,cxx2b
+
+//cxx2b-no-diagnostics
+
+auto L1 = [] constexpr {}; // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
+auto L2 = []() static {}; // cxx20-error {{static lambdas is a C++2b extension}}
+auto L3 = [] static {}; // cxx20-error {{static lambdas is a C++2b extension}} // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
Index: clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s
+
+struct Functor {
+  static int operator()(int x, int y) {
+return x + y;
+  }
+};
+
+auto GetALambda() {
+  return [](int x, int y) static {
+return x + y;
+  };
+}
+
+void CallsTheLambda() {
+  GetALambda()(1, 2);
+}
+
+// CHECK:  define {{.*}}CallsTheLambda{{.*}}
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   %call = call noundef i32 {{.*}}(i32 noundef 1, i32 noundef 2)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
+
+void call_static_call_operator() {
+  Functor f;
+  f(101, 102);
+  f.operator()(201, 202);
+  Functor{}(301, 302);
+}
+
+// CHECK:  define {{.*}}call_static_call_operator{{.*}}
+// CHECK-NEXT: entry:
+// CHECK:{{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 101, i32 noundef 102)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 201, i32 noundef 202)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 

[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-12 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 459414.
royjacobson added a comment.

format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/OperatorKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/CXX/over/over.match/over.match.best/over.best.ics/p6.cpp
  clang/test/CXX/over/over.oper/p7.cpp
  clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
  clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
  clang/test/Parser/cxx2b-lambdas.cpp
  clang/test/SemaCXX/overloaded-operator-decl.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1481,7 +1481,7 @@
 
   static operator()
   https://wg21.link/P1169R4";>P1169R4
-  No
+  Clang 16
 
 
   Extended floating-point types and standard names
Index: clang/test/SemaCXX/overloaded-operator-decl.cpp
===
--- clang/test/SemaCXX/overloaded-operator-decl.cpp
+++ clang/test/SemaCXX/overloaded-operator-decl.cpp
@@ -51,7 +51,7 @@
 
 namespace PR14120 {
   struct A {
-static void operator()(int& i) { ++i; } // expected-error{{overloaded 'operator()' cannot be a static member function}}
+static void operator()(int& i) { ++i; } // expected-error{{overloaded 'operator()' cannot be declared static}}
   };
   void f() {
 int i = 0;
Index: clang/test/Parser/cxx2b-lambdas.cpp
===
--- clang/test/Parser/cxx2b-lambdas.cpp
+++ clang/test/Parser/cxx2b-lambdas.cpp
@@ -38,3 +38,16 @@
 auto XL4 = [] requires true {}; // expected-error{{expected body}}
 auto XL5 = [] requires true requires true {}; // expected-error{{expected body}}
 auto XL6 = [] requires true noexcept requires true {}; // expected-error{{expected body}}
+
+auto XL7 = []() static static {}; // expected-error {{cannot appear multiple times}}
+auto XL8 = []() static mutable {}; // expected-error {{cannot be both mutable and static}}
+
+auto XL9 = [] static {};
+auto XL10 = []() static {};
+
+void static_captures() {
+  int x;
+  auto SC1 = [&]() static {}; // expected-error {{a static lambda cannot have any captures}}
+  auto SC2 = [&x]() static {}; // expected-error {{a static lambda cannot have any captures}}
+  auto SC3 = [=]() static {}; // expected-error {{a static lambda cannot have any captures}}
+}
Index: clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,cxx20
+// RUN: %clang_cc1 -std=c++2b %s -verify=expected,cxx2b
+
+//cxx2b-no-diagnostics
+
+auto L1 = [] constexpr {}; // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
+auto L2 = []() static {}; // cxx20-error {{static lambdas is a C++2b extension}}
+auto L3 = [] static {}; // cxx20-error {{static lambdas is a C++2b extension}} // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
Index: clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s
+
+struct Functor {
+  static int operator()(int x, int y) {
+return x + y;
+  }
+};
+
+auto GetALambda() {
+  return [](int x, int y) static {
+return x + y;
+  };
+}
+
+void CallsTheLambda() {
+  GetALambda()(1, 2);
+}
+
+// CHECK:  define {{.*}}CallsTheLambda{{.*}}
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   %call = call noundef i32 {{.*}}(i32 noundef 1, i32 noundef 2)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
+
+void call_static_call_operator() {
+  Functor f;
+  f(101, 102);
+  f.operator()(201, 202);
+  Functor{}(301, 302);
+}
+
+// CHECK:  define {{.*}}call_static_call_operator{{.*}}
+// CHECK-NEXT: entry:
+// CHECK:{{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 101, i32 noundef 102)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 201, i32 noundef 202)
+// CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 301, i32 noundef 302)
+// CH

[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-12 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson marked 6 inline comments as done.
royjacobson added inline comments.



Comment at: clang/lib/Parse/ParseExprCXX.cpp:1265
+  if (Intro.hasLambdaCapture())
+P.Diag(StaticLoc, diag::err_static_lambda_captures);
+}

cor3ntin wrote:
> We might want to add a note showing where the capture list is.
I added a note, but the captures list is always just before the static 
specifier, so I'm not sure how useful it is. WDYT?



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-12 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 459525.
royjacobson marked an inline comment as done.
royjacobson added a comment.

Add note in diagnostic.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/OperatorKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/CXX/over/over.match/over.match.best/over.best.ics/p6.cpp
  clang/test/CXX/over/over.oper/p7.cpp
  clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
  clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
  clang/test/Parser/cxx2b-lambdas.cpp
  clang/test/SemaCXX/overloaded-operator-decl.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1481,7 +1481,7 @@
 
   static operator()
   https://wg21.link/P1169R4";>P1169R4
-  No
+  Clang 16
 
 
   Extended floating-point types and standard names
Index: clang/test/SemaCXX/overloaded-operator-decl.cpp
===
--- clang/test/SemaCXX/overloaded-operator-decl.cpp
+++ clang/test/SemaCXX/overloaded-operator-decl.cpp
@@ -51,7 +51,7 @@
 
 namespace PR14120 {
   struct A {
-static void operator()(int& i) { ++i; } // expected-error{{overloaded 'operator()' cannot be a static member function}}
+static void operator()(int& i) { ++i; } // expected-error{{overloaded 'operator()' cannot be declared static}}
   };
   void f() {
 int i = 0;
Index: clang/test/Parser/cxx2b-lambdas.cpp
===
--- clang/test/Parser/cxx2b-lambdas.cpp
+++ clang/test/Parser/cxx2b-lambdas.cpp
@@ -38,3 +38,16 @@
 auto XL4 = [] requires true {}; // expected-error{{expected body}}
 auto XL5 = [] requires true requires true {}; // expected-error{{expected body}}
 auto XL6 = [] requires true noexcept requires true {}; // expected-error{{expected body}}
+
+auto XL7 = []() static static {}; // expected-error {{cannot appear multiple times}}
+auto XL8 = []() static mutable {}; // expected-error {{cannot be both mutable and static}}
+
+auto XL9 = [] static {};
+auto XL10 = []() static {};
+
+void static_captures() {
+  int x;
+  auto SC1 = [&]() static {}; // expected-error {{a static lambda cannot have any captures}} // expected-note {{captures declared here}}
+  auto SC2 = [&x]() static {}; // expected-error {{a static lambda cannot have any captures}} // expected-note {{captures declared here}}
+  auto SC3 = [=]() static {}; // expected-error {{a static lambda cannot have any captures}} // expected-note {{captures declared here}}
+}
Index: clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
===
--- /dev/null
+++ clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,cxx20
+// RUN: %clang_cc1 -std=c++2b %s -verify=expected,cxx2b
+
+//cxx2b-no-diagnostics
+
+auto L1 = [] constexpr {}; // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
+auto L2 = []() static {}; // cxx20-error {{static lambdas is a C++2b extension}}
+auto L3 = [] static {}; // cxx20-error {{static lambdas is a C++2b extension}} // cxx20-warning {{lambda without a parameter clause is a C++2b extension}}
Index: clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s
+
+struct Functor {
+  static int operator()(int x, int y) {
+return x + y;
+  }
+};
+
+auto GetALambda() {
+  return [](int x, int y) static {
+return x + y;
+  };
+}
+
+void CallsTheLambda() {
+  GetALambda()(1, 2);
+}
+
+// CHECK:  define {{.*}}CallsTheLambda{{.*}}
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   %call = call noundef i32 {{.*}}(i32 noundef 1, i32 noundef 2)
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
+
+void call_static_call_operator() {
+  Functor f;
+  f(101, 102);
+  f.operator()(201, 202);
+  Functor{}(301, 302);
+}
+
+// CHECK:  define {{.*}}call_static_call_operator{{.*}}
+// CHECK-NEXT: entry:
+// CHECK:{{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 101, i32 noundef 102)
+// CHE

[PATCH] D133659: [Clang] P1169R4: static operator()

2022-09-14 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 460155.
royjacobson added a comment.

Add tests required by reviewerd.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133659

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/OperatorKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/CXX/over/over.match/over.match.best/over.best.ics/p6.cpp
  clang/test/CXX/over/over.oper/p7.cpp
  clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp
  clang/test/Parser/cxx2b-lambdas-ext-warns.cpp
  clang/test/Parser/cxx2b-lambdas.cpp
  clang/test/SemaCXX/lambda-unevaluated.cpp
  clang/test/SemaCXX/overloaded-operator-decl.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1481,7 +1481,7 @@
 
   static operator()
   https://wg21.link/P1169R4";>P1169R4
-  No
+  Clang 16
 
 
   Extended floating-point types and standard names
Index: clang/test/SemaCXX/overloaded-operator-decl.cpp
===
--- clang/test/SemaCXX/overloaded-operator-decl.cpp
+++ clang/test/SemaCXX/overloaded-operator-decl.cpp
@@ -51,7 +51,7 @@
 
 namespace PR14120 {
   struct A {
-static void operator()(int& i) { ++i; } // expected-error{{overloaded 'operator()' cannot be a static member function}}
+static void operator()(int& i) { ++i; } // expected-error{{overloaded 'operator()' cannot be declared static}}
   };
   void f() {
 int i = 0;
Index: clang/test/SemaCXX/lambda-unevaluated.cpp
===
--- clang/test/SemaCXX/lambda-unevaluated.cpp
+++ clang/test/SemaCXX/lambda-unevaluated.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++20 %s -verify
+// RUN: %clang_cc1 -std=c++2b %s -verify
 
 
 template  struct Nothing {};
@@ -120,3 +121,28 @@
 void foo(decltype(+[](T) {}) lambda, T param);
 static_assert(!__is_same(decltype(foo), void));
 } // namespace GH51641
+
+#if __cplusplus > 202002L
+namespace StaticLambdas {
+template  struct Nothing {};
+Nothing<[]() static { return 0; }()> nothing;
+
+template  struct NothingT {};
+Nothing<[]() static { return 0; }> nothingT;
+
+template 
+concept True = [] static { return true; }();
+static_assert(True);
+
+static_assert(sizeof([] static { return 0; }));
+static_assert(sizeof([] static { return 0; }()));
+
+void f()  noexcept(noexcept([] static { return 0; }()));
+
+using a = decltype([] static { return 0; });
+using b = decltype([] static { return 0; }());
+using c = decltype([]() static noexcept(noexcept([] { return 0; }())) { return 0; });
+using d = decltype(sizeof([] static { return 0; }));
+
+}
+#endif
Index: clang/test/Parser/cxx2b-lambdas.cpp
===
--- clang/test/Parser/cxx2b-lambdas.cpp
+++ clang/test/Parser/cxx2b-lambdas.cpp
@@ -38,3 +38,25 @@
 auto XL4 = [] requires true {}; // expected-error{{expected body}}
 auto XL5 = [] requires true requires true {}; // expected-error{{expected body}}
 auto XL6 = [] requires true noexcept requires true {}; // expected-error{{expected body}}
+
+auto XL7 = []() static static {}; // expected-error {{cannot appear multiple times}}
+auto XL8 = []() static mutable {}; // expected-error {{cannot be both mutable and static}}
+auto XL9 = []() static consteval {};
+auto XL10 = []() static constexpr {};
+
+auto XL11 = [] static {};
+auto XL12 = []() static {};
+auto XL13 = []() static extern {};  // expected-error {{expected body of lambda expression}}
+auto XL14 = []() extern {};  // expected-error {{expected body of lambda expression}}
+
+
+void static_captures() {
+  int x;
+  auto SC1 = [&]() static {}; // expected-error {{a static lambda cannot have any captures}} // expected-note {{captures declared here}}
+  auto SC4 = [x]() static {}; // expected-error {{a static lambda cannot have any captures}} // expected-note {{captures declared here}}
+  auto SC2 = [&x]() static {}; // expected-error {{a static lambda cannot have any captures}} // expected-note {{captures declared here}}
+  auto SC3 = [y=x]() static {}; // expected-error {{a static lambda cannot have any captures}} // expected-note {{captures declared here}}
+  auto SC5 = [&y = x]() static {}; // expected-error {{a static lambda cannot have any captures}} // expected-note {{captures declared here}}
+  auto SC6 = [=]() static {}; // expected-error {{a static lambda cannot have any ca

[PATCH] D128750: [c++20] Implement P2113R0: Changes to the Partial Ordering of Constrained Functions

2022-07-03 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson requested changes to this revision.
royjacobson added a comment.
This revision now requires changes to proceed.

Thanks for working on this! I like the approach, but two comments:

I would like more tests for the different forms of template argument deduction. 
Some suggestions for things to test: template template arguments, 'auto' in 
abbreviated function templates, argument packs, non-type template parameters. 
We should at least test that we find the more constrained function when the 
parameters are equal.

I'm also a bit concerned that we're deviating from the standard here w.r.t. to 
the 'reordering' checks for reversed candidates. I support this - I think your 
version makes more sense than what the standard says to do here - but if 
someone could check with the committee (I don't have reflector access myself) 
that we're not breaking some important use case by doing it this way, I think 
it's a good idea.




Comment at: clang/docs/ReleaseNotes.rst:134-138
 - Overload resolution for constrained function templates could use the partial
   order of constraints to select an overload, even if the parameter types of
   the functions were different. It now diagnoses this case correctly as an
   ambiguous call and an error. Fixes
   `Issue 53640 `_.

You can remove this bullet from when I partially implemented this paper :)



Comment at: clang/lib/Sema/SemaTemplate.cpp:7810
+   TemplateParameterList *Old) {
+  SmallVector IterIdxs(Old->size());
+  std::iota(IterIdxs.begin(), IterIdxs.end(), 0);

Consider adding



Comment at: clang/lib/Sema/SemaTemplateDeduction.cpp:5119
-  while (--NumParams > 0) {
-if (Function->getParamDecl(NumParams - 1)->isParameterPack())
-  return false;

Curious, why was this removed?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128750

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129170: [Sema] Add deprecation warnings for some compiler provided __has_* type traits

2022-07-05 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Some compiler provided type traits like __has_trivial_constructor have been 
documented
as deprecated for quite some time.
Still, some people apparently still use them, even though mixing them with 
concepts
and with deleted functions leads to weird results. There's also disagreement 
about some
edge cases between GCC (which Clang claims to follow) and MSVC.

This patch adds deprecation warnings for the usage of those builtins, except 
for __has_trivial_destructor
which doesn't have a GCC alternative.

I made the warning on by default, so I had to silence it for some tests but 
it's not too many.

Some (decade old) history of issues with those builtins:
https://github.com/llvm/llvm-project/issues/18187
https://github.com/llvm/llvm-project/issues/18559
https://github.com/llvm/llvm-project/issues/22161
https://github.com/llvm/llvm-project/issues/33063

The abseil usage of them that triggered me to add this warning:
https://github.com/abseil/abseil-cpp/issues/1201

Weird interaction of those builtins with C++20's conditionally trivial special 
member functions:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106085


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129170

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/dcl.decl/dcl.init/p5.cpp
  clang/test/CXX/drs/dr18xx.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/test/CXX/special/class.ctor/p5-0x.cpp
  clang/test/Modules/cxx-decls.cpp
  clang/test/SemaCXX/cxx0x-defaulted-functions.cpp
  clang/test/SemaCXX/cxx11-crashes.cpp
  clang/test/SemaCXX/deprecated-builtins.cpp
  clang/test/SemaCXX/sizeless-1.cpp
  clang/test/SemaCXX/trivial-constructor.cpp
  clang/test/SemaCXX/trivial-destructor.cpp
  clang/test/SemaCXX/type-traits.cpp
  clang/test/SemaObjCXX/arc-type-traits.mm
  clang/test/SemaObjCXX/objc-weak-type-traits.mm

Index: clang/test/SemaObjCXX/objc-weak-type-traits.mm
===
--- clang/test/SemaObjCXX/objc-weak-type-traits.mm
+++ clang/test/SemaObjCXX/objc-weak-type-traits.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-has-builtins
 // expected-no-diagnostics
 
 // Check the results of the various type-trait query functions on
Index: clang/test/SemaObjCXX/arc-type-traits.mm
===
--- clang/test/SemaObjCXX/arc-type-traits.mm
+++ clang/test/SemaObjCXX/arc-type-traits.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-has-builtins
 // expected-no-diagnostics
 
 // Check the results of the various type-trait query functions on
Index: clang/test/SemaCXX/type-traits.cpp
===
--- clang/test/SemaCXX/type-traits.cpp
+++ clang/test/SemaCXX/type-traits.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fms-extensions -Wno-microsoft %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fms-extensions -Wno-microsoft %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -Wno-deprecated-has-builtins -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -Wno-deprecated-has-builtins -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -Wno-deprecated-has-builtins -fms-extensions -Wno-microsoft %s
 
 #define T(b) (b) ? 1 : -1
 #define F(b) (b) ? -1 : 1
Index: clang/test/SemaCXX/trivial-destructor.cpp
===
--- clang/test/SemaCXX/trivial-destructor.cpp
+++ clang/test/SemaCXX/trivial-destructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-has-builtins
 // expected-no-diagnostics
 struct T1 {
 };
Index: clang/test/SemaCXX/trivial-constructor.cpp
===
--- clang/test/SemaCXX/trivial-constructor.cpp
+++ clang/test/SemaCXX/trivial-constructor.cpp
@@ -1,4 +1

[PATCH] D129170: [Sema] Add deprecation warnings for some compiler provided __has_* type traits

2022-07-06 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 442680.
royjacobson added a comment.

Address CR comments.
Make the switch case slightly more concise.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129170

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/dcl.decl/dcl.init/p5.cpp
  clang/test/CXX/drs/dr18xx.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/test/CXX/special/class.ctor/p5-0x.cpp
  clang/test/Modules/cxx-decls.cpp
  clang/test/SemaCXX/cxx0x-defaulted-functions.cpp
  clang/test/SemaCXX/cxx11-crashes.cpp
  clang/test/SemaCXX/deprecated-builtins.cpp
  clang/test/SemaCXX/sizeless-1.cpp
  clang/test/SemaCXX/trivial-constructor.cpp
  clang/test/SemaCXX/trivial-destructor.cpp
  clang/test/SemaCXX/type-traits.cpp
  clang/test/SemaObjCXX/arc-type-traits.mm
  clang/test/SemaObjCXX/objc-weak-type-traits.mm

Index: clang/test/SemaObjCXX/objc-weak-type-traits.mm
===
--- clang/test/SemaObjCXX/objc-weak-type-traits.mm
+++ clang/test/SemaObjCXX/objc-weak-type-traits.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-builtins
 // expected-no-diagnostics
 
 // Check the results of the various type-trait query functions on
Index: clang/test/SemaObjCXX/arc-type-traits.mm
===
--- clang/test/SemaObjCXX/arc-type-traits.mm
+++ clang/test/SemaObjCXX/arc-type-traits.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-builtins
 // expected-no-diagnostics
 
 // Check the results of the various type-trait query functions on
Index: clang/test/SemaCXX/type-traits.cpp
===
--- clang/test/SemaCXX/type-traits.cpp
+++ clang/test/SemaCXX/type-traits.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fms-extensions -Wno-microsoft %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fms-extensions -Wno-microsoft %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s
 
 #define T(b) (b) ? 1 : -1
 #define F(b) (b) ? -1 : 1
Index: clang/test/SemaCXX/trivial-destructor.cpp
===
--- clang/test/SemaCXX/trivial-destructor.cpp
+++ clang/test/SemaCXX/trivial-destructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-builtins
 // expected-no-diagnostics
 struct T1 {
 };
Index: clang/test/SemaCXX/trivial-constructor.cpp
===
--- clang/test/SemaCXX/trivial-constructor.cpp
+++ clang/test/SemaCXX/trivial-constructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-builtins
 // expected-no-diagnostics
 struct T1 {
 };
Index: clang/test/SemaCXX/sizeless-1.cpp
===
--- clang/test/SemaCXX/sizeless-1.cpp
+++ clang/test/SemaCXX/sizeless-1.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++98 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++11 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++17 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=gnu++17 %s
+// RUN: %clang_cc1

[PATCH] D129170: [Sema] Add deprecation warnings for some compiler provided __has_* type traits

2022-07-06 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson marked 9 inline comments as done and 2 inline comments as done.
royjacobson added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticGroups.td:190
 : DiagGroup<"deprecated-dynamic-exception-spec">;
+def DeprecatedHasBuiltins : DiagGroup<"deprecated-has-builtins">;
 def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;

aaron.ballman wrote:
> I wonder if we want to rename this to `deprecated-builtins` so it applies to 
> any builtin we elect to deprecate, not just ones that start with `has`. WDYT?
Sounds good to me, updated it.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:5561
+def warn_deprecated_has_builtins : Warning<
+  "the %0 compiler builtin is deprecated from C++11 onwards. Use %1 instead.">,
+  InGroup;

aaron.ballman wrote:
> erichkeane wrote:
> > cor3ntin wrote:
> > > Should we say something like "and will be removed in the future"?
> > > 
> > > "%0 is deprecated from C++11 onward. Use %1 instead." might be sufficient
> > > 
> > > 
> > Diagnostics arent sentences. Also, we wouldn't say "C++11 onward", we can 
> > just say C++11. I might suggest:
> > 
> > `builtin %0 is deprecated in C++11, use %1 instead`
> > 
> > BUT @aaron.ballman always does great at this level of bikeshedding.
> > 
> I think we might want to rename this to `warn_deprecated_builtin` and make it 
> slightly more general. I think we want to drop the mention of C++11 because 
> the documentation says these are deprecated (not deprecated in a specific 
> version) and the replacement APIs are all available pre C++11 anyway (at 
> least in Clang). How about: `builtin %0 is deprecated; use %1 instead`?
Took Aaron's version at the end.



Comment at: clang/lib/Sema/SemaExprCXX.cpp:5400-5401
+SourceLocation KWLoc) {
+  if (!S.getLangOpts().CPlusPlus11)
+return;
+

aaron.ballman wrote:
> I think we should always warn on these, not just in C++11.
I'm not convinced we should. My reasoning is that we need a pretty good reason 
to start issuing warnings for 20 years old code. The usage of those builtins 
with deleted functions after C++11 is pretty broken which is a pretty good 
reason, but for earlier language versions they work 'fine' and if people want 
to use C++03 I prefer leaving them at peace :)

People on C++03 are also probably using pretty old versions of libstdc++ and/or 
boost type_traits, so this could have some impact.

WDYT?




Comment at: clang/lib/Sema/SemaExprCXX.cpp:5426-5428
+case UTT_HasTrivialDefaultConstructor:
+  Replacement = TT_IsTriviallyConstructible;
+  break;

aaron.ballman wrote:
> This one is not documented as being deprecated (or documented at all). I 
> think it's reasonable to deprecate it, but it should probably be documented 
> in the language extensions page.
It's the `__has_trivial_constructor` builtin that unfortunately has a different 
enum name (it's named after the internal CXXRecordDecl it calls, I think).



Comment at: clang/lib/Sema/SemaExprCXX.cpp:5433
+// FIXME: GCC don't implement __is_trivially_destructible: Warning for this
+//   might be too noisy for now.
+// case UTT_HasTrivialDestructor:

aaron.ballman wrote:
> I'd like to know how plausible that "might" is -- Clang flags it as being 
> deprecated, so it seems very reasonable to diagnose it as such. These 
> diagnostics won't be triggered from system headers by default anyway, so I'm 
> not certain if this will be too noisy in practice.
It's used in libstdc++'s type_traits and in boost's type_traits (but we will 
start warning on boost's type_traits anyway). So it's even if by default people 
are not going to see it I think it's used widely enough to be problematic and 
we shouldn't warn on this for now.

I added the libstdc++ part to the comment as well.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129170

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129170: [Sema] Add deprecation warnings for some compiler provided __has_* type traits

2022-07-07 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson marked 3 inline comments as done.
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaExprCXX.cpp:5400-5401
+SourceLocation KWLoc) {
+  if (!S.getLangOpts().CPlusPlus11)
+return;
+

erichkeane wrote:
> royjacobson wrote:
> > aaron.ballman wrote:
> > > I think we should always warn on these, not just in C++11.
> > I'm not convinced we should. My reasoning is that we need a pretty good 
> > reason to start issuing warnings for 20 years old code. The usage of those 
> > builtins with deleted functions after C++11 is pretty broken which is a 
> > pretty good reason, but for earlier language versions they work 'fine' and 
> > if people want to use C++03 I prefer leaving them at peace :)
> > 
> > People on C++03 are also probably using pretty old versions of libstdc++ 
> > and/or boost type_traits, so this could have some impact.
> > 
> > WDYT?
> > 
> warnings don't get emitted for code in header files, so at least that part 
> isn't a concern.  
Any header files, or just system headers?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129170

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129170: [Sema] Add deprecation warnings for some compiler provided __has_* type traits

2022-07-08 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaExprCXX.cpp:5400-5401
+SourceLocation KWLoc) {
+  if (!S.getLangOpts().CPlusPlus11)
+return;
+

aaron.ballman wrote:
> erichkeane wrote:
> > royjacobson wrote:
> > > erichkeane wrote:
> > > > royjacobson wrote:
> > > > > aaron.ballman wrote:
> > > > > > I think we should always warn on these, not just in C++11.
> > > > > I'm not convinced we should. My reasoning is that we need a pretty 
> > > > > good reason to start issuing warnings for 20 years old code. The 
> > > > > usage of those builtins with deleted functions after C++11 is pretty 
> > > > > broken which is a pretty good reason, but for earlier language 
> > > > > versions they work 'fine' and if people want to use C++03 I prefer 
> > > > > leaving them at peace :)
> > > > > 
> > > > > People on C++03 are also probably using pretty old versions of 
> > > > > libstdc++ and/or boost type_traits, so this could have some impact.
> > > > > 
> > > > > WDYT?
> > > > > 
> > > > warnings don't get emitted for code in header files, so at least that 
> > > > part isn't a concern.  
> > > Any header files, or just system headers?
> > Sorry, yes, Phab is a mess on a cell phone... in things included as System 
> > Headers.
> Agreed with Erich -- warnings in system headers (but not regular headers) are 
> silenced by default, you need to pass `-Wsystem-headers` to enable them.
To clarify my position, I think about those builtins as an unofficial part of 
the C++03 standard and I think we should support them as long as we support 
C++03.

Do you think that's reasonable?

I agree we should update the documentation in this case.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129170

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D123182: [Concepts] Fix issue #53640

2022-04-05 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Constraints were used for overload resolution tie breaking even when it was not 
allowed
because the functions had different parameter types.

Fixes GitHub issue https://github.com/llvm/llvm-project/issues/53640


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5152,9 +5152,12 @@
  TemplatePartialOrderingContext TPOC,
  unsigned NumCallArguments1,
  unsigned NumCallArguments2,
- bool Reversed) {
+ bool Reversed,
+ bool AllowOrderingByConstraints) {
 
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2953,15 +2953,21 @@
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
 /// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, exactly one of FT1 and FT2 is an overload
+/// candidate with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *ArgPos, bool Reversed) {
+  assert(OldType->getNumParams() == NewType->getNumParams() &&
+ "Can't compare parameters of functions with different number of parameters!");
+  for (FunctionProtoType::param_type_iterator
+   O = OldType->param_type_begin(),
+   N = (Reversed ? NewType->param_type_end() - 1
+ : NewType->param_type_begin()),
+   E = OldType->param_type_end();
+   O && (O != E); ++O, (Reversed ? --N : ++N)) {
 // Ignore address spaces in pointee type. This is to disallow overloading
 // on __ptr32/__ptr64 address spaces.
 QualType Old = Context.removePtrSizeAddrSpace(O->getUnqualifiedType());
@@ -9811,6 +9817,26 @@
   if (Cand1IsSpecialization != Cand2IsSpecialization)
 return Cand2IsSpecialization;
 
+  // We're allowed to use constraints partial ordering only if the functions
+  // have the same parameter

[PATCH] D123182: [Concepts] Fix issue #53640

2022-04-05 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 420708.
royjacobson added a comment.

Fixed missing doc for new argument


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5143,6 +5143,9 @@
 /// candidate with a reversed parameter order. In this case, the corresponding
 /// P/A pairs between FT1 and FT2 are reversed.
 ///
+/// \param AllowOrderingByConstraints If \c is false, don't check whether one
+/// of the templates is more constrained than the other. Default is true.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
 FunctionTemplateDecl *
@@ -5152,9 +5155,12 @@
  TemplatePartialOrderingContext TPOC,
  unsigned NumCallArguments1,
  unsigned NumCallArguments2,
- bool Reversed) {
+ bool Reversed,
+ bool AllowOrderingByConstraints) {
 
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2953,15 +2953,21 @@
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
 /// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, exactly one of FT1 and FT2 is an overload
+/// candidate with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *ArgPos, bool Reversed) {
+  assert(OldType->getNumParams() == NewType->getNumParams() &&
+ "Can't compare parameters of functions with different number of parameters!");
+  for (FunctionProtoType::param_type_iterator
+   O = OldType->param_type_begin(),
+   N = (Reversed ? NewType->param_type_end() - 1
+ : NewType->param_type_begin()),
+   E = OldType->param_type_end();
+   O && (O != E); ++O, (Reversed ? --N : ++N)) {
 // Ignore address spaces in pointee type. This is to disallow overloading
 // on __ptr32/__ptr64 address spaces.
 QualType Old = Context.removePtrSizeAddrSpace(O->getUn

[PATCH] D128750: [c++20] Implement P2113R0: Changes to the Partial Ordering of Constrained Functions

2022-07-26 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D128750#3663161 , @ychen wrote:

> In D128750#3662898 , @royjacobson 
> wrote:
>
>> but in your example with T/U/V we have 3 template parameters that we could 
>> reorder in 6 different ways.
>
> But, any reordering of the 6 that does not have consecutive U and V  is not 
> valid. Because in the other template, T/U is consecutive and used by X 
> in that order. I don't think it is allowed to change the template parameter 
> references in the function parameters.

Sorry for taking the time to answer!
I'm still not sure why it wouldn't be allowed to change template parameter 
freely. The standard just says 'reordering of the associated 
template-parameter-list'. I understand it to mean any permutation of them until 
they match the order of the other function's template parameters (which doesn't 
even to be the candidate that generated this reversed candidate). I don't 
understand why U,V must be consecutive - might be I'm missing something, but 
all forms seem to be valid templates? https://godbolt.org/z/E8Y3Ez3TY

Also, in case it was understood otherwise - I still think this is reasonable 
and I don't think we should wait until someone gets an answer from CWG  - my 
request for changes is because I want to see better tests coverage.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128750

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130058: [Clang] Diagnose ill-formed constant expression when setting a non fixed enum to a value outside the range of the enumeration values

2022-07-27 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/test/SemaCXX/constant-expression-cxx11.cpp:2420
+  constexpr E1 x2 = static_cast(8); // expected-error {{must be 
initialized by a constant expression}}
+  // expected-note@-1 {{integer value 8 is outside the valid range of values 
[-8, 8) for this enumeration type}}
+

aaron.ballman wrote:
> tahonermann wrote:
> > erichkeane wrote:
> > > aaron.ballman wrote:
> > > > erichkeane wrote:
> > > > > aaron.ballman wrote:
> > > > > > erichkeane wrote:
> > > > > > > Are we ok with how subtle the `[N, M)` syntax is here?
> > > > > > FWIW, I pulled this from diagnostics like: 
> > > > > > https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/DiagnosticSemaKinds.td#L9904
> > > > > >  and 
> > > > > > https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/DiagnosticSemaKinds.td#L11541
> > > > > Those aren't particularly high quality diagnostics, the first is for 
> > > > > builtin ranges (and builtins have notoriously bad diagnostics), the 
> > > > > 2nd is for the matrix type, which is only slightly better.
> > > > > 
> > > > > That said, if you are ok with it, I'm ok, just somewhat afraid it'll 
> > > > > be a touch confusing.
> > > > Yeah, it's not the best diagnostic, to be sure. The trouble is that 
> > > > spelling it out makes it worse IMO: `integer value %0 is outside the 
> > > > valid range of values %1 (inclusive) and %2 (exclusive) for this 
> > > > enumeration type`
> > > Ok then, I can't think of anything better really (PERHAPS something that 
> > > says, `integer value %0 is outside of the valid range of values (%1 - %2 
> > > inclusive) for this enumeration type`, so I'm ok living with it until 
> > > someone proposes better in a followup patch.
> > > 
> > > 
> > I've never cared for the `[` vs `(` notation to indicate inclusivity vs 
> > exclusivity. All I see are unbalanced tokens and I can never remember which 
> > brace means what; I have to look it up every time and it isn't an easy 
> > search, especially for people that aren't already somewhat familiar with 
> > the notation; you have to know to search for something like "range 
> > inclusive exclusive notation". I urge use of the more elaborate diagnostic.
> I'm fine with being more verbose in the diagnostic so long as it doesn't go 
> overboard. I don't really like the wording Erich suggested because it can be 
> misinterpreted as both values being inclusive. I can hold my nose at what we 
> have above. We're inconsistent in how we report this kind of information and 
> it seems like someday we should improve this whole class of diagnostics (ones 
> with ranges) to have a consistent display to the user. (CC @cjdb for 
> awareness for his project, nothing actionable though.)
Maybe `[%1 <= x < %2]`? Feels a bit clumsy, but it disambiguates


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

https://reviews.llvm.org/D130058

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130936: [SemaCXX] Validate destructor is valid for dependent classes

2022-08-01 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson updated this revision to Diff 449130.
royjacobson added a comment.
royjacobson retitled this revision from "[SemaCXX] Fix destructor name 
accepts-invalid bug." to "[SemaCXX] Validate destructor is valid for dependent 
classes".
royjacobson edited the summary of this revision.
royjacobson added reviewers: erichkeane, shafik.
royjacobson published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fix the C++20 check


We didn't check that a destructor's name matches the directly enclosing class 
if the class was dependent.
I enabled the check we already had for non-dependent types, which seems to 
work. Added appropriate tests.

Fixes GitHub issue #56772


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130936

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaCXX/member-class-11.cpp


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
 
 struct rdar9677163 {
   struct Y { ~Y(); };
@@ -6,3 +8,22 @@
   Y::~Y() { } // expected-error{{non-friend class member '~Y' cannot have a 
qualified name}}
   ~Z(); // expected-error{{expected the class name after '~' to name the 
enclosing class}}
 };
+
+namespace GH56772 {
+
+template
+struct A {
+  ~A();
+};
+#if __cplusplus >= 202002L
+// FIXME: This isn't valid in C++20 and later.
+#endif
+
+struct B;
+
+template
+struct C {
+  ~B(); // expected-error {{expected the class name after '~' to name the 
enclosing class}}
+};
+
+}
\ No newline at end of file
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11496,17 +11496,12 @@
   CXXRecordDecl *Record = Destructor->getParent();
   QualType ClassType = Context.getTypeDeclType(Record);
 
-  // FIXME: Shouldn't we be able to perform this check even when the class
-  // type is dependent? Both gcc and edg can handle that.
-  if (!ClassType->isDependentType()) {
-DeclarationName Name
-  = Context.DeclarationNames.getCXXDestructorName(
-Context.getCanonicalType(ClassType));
-if (NewFD->getDeclName() != Name) {
-  Diag(NewFD->getLocation(), diag::err_destructor_name);
-  NewFD->setInvalidDecl();
-  return Redeclaration;
-}
+  DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
+  Context.getCanonicalType(ClassType));
+  if (NewFD->getDeclName() != Name) {
+Diag(NewFD->getLocation(), diag::err_destructor_name);
+NewFD->setInvalidDecl();
+return Redeclaration;
   }
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
 
 struct rdar9677163 {
   struct Y { ~Y(); };
@@ -6,3 +8,22 @@
   Y::~Y() { } // expected-error{{non-friend class member '~Y' cannot have a qualified name}}
   ~Z(); // expected-error{{expected the class name after '~' to name the enclosing class}}
 };
+
+namespace GH56772 {
+
+template
+struct A {
+  ~A();
+};
+#if __cplusplus >= 202002L
+// FIXME: This isn't valid in C++20 and later.
+#endif
+
+struct B;
+
+template
+struct C {
+  ~B(); // expected-error {{expected the class name after '~' to name the enclosing class}}
+};
+
+}
\ No newline at end of file
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11496,17 +11496,12 @@
   CXXRecordDecl *Record = Destructor->getParent();
   QualType ClassType = Context.getTypeDeclType(Record);
 
-  // FIXME: Shouldn't we be able to perform this check even when the class
-  // type is dependent? Both gcc and edg can handle that.
-  if (!ClassType->isDependentType()) {
-DeclarationName Name
-  = Context.DeclarationNames.getCXXDestructorName(
-Context.getCanonicalType(ClassType));
-if (NewFD->getDeclName() != Name) {
-  Diag(NewFD->getLocation(), diag::err_destructor_name);
-  NewFD->setInvalidDecl();
-  return Redeclaration;
-}
+  DeclarationNa

[PATCH] D130936: [SemaCXX] Validate destructor is valid for dependent classes

2022-08-02 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 449344.
royjacobson edited the summary of this revision.
royjacobson added a comment.

Add newline and release notes.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130936

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaCXX/member-class-11.cpp


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
 
 struct rdar9677163 {
   struct Y { ~Y(); };
@@ -6,3 +8,22 @@
   Y::~Y() { } // expected-error{{non-friend class member '~Y' cannot have a 
qualified name}}
   ~Z(); // expected-error{{expected the class name after '~' to name the 
enclosing class}}
 };
+
+namespace GH56772 {
+
+template
+struct A {
+  ~A();
+};
+#if __cplusplus >= 202002L
+// FIXME: This isn't valid in C++20 and later.
+#endif
+
+struct B;
+
+template
+struct C {
+  ~B(); // expected-error {{expected the class name after '~' to name the 
enclosing class}}
+};
+
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11496,17 +11496,12 @@
   CXXRecordDecl *Record = Destructor->getParent();
   QualType ClassType = Context.getTypeDeclType(Record);
 
-  // FIXME: Shouldn't we be able to perform this check even when the class
-  // type is dependent? Both gcc and edg can handle that.
-  if (!ClassType->isDependentType()) {
-DeclarationName Name
-  = Context.DeclarationNames.getCXXDestructorName(
-Context.getCanonicalType(ClassType));
-if (NewFD->getDeclName() != Name) {
-  Diag(NewFD->getLocation(), diag::err_destructor_name);
-  NewFD->setInvalidDecl();
-  return Redeclaration;
-}
+  DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
+  Context.getCanonicalType(ClassType));
+  if (NewFD->getDeclName() != Name) {
+Diag(NewFD->getLocation(), diag::err_destructor_name);
+NewFD->setInvalidDecl();
+return Redeclaration;
   }
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -52,6 +52,8 @@
 - Fixes an accepts-invalid bug in C when using a ``_Noreturn`` function
   specifier on something other than a function declaration. This fixes
   `Issue 56800 `_.
+- Fix `#56772 `_ - invalid
+  destructor names were incorrectly accepted on template classes.
 
 Improvements to Clang's diagnostics
 ^^^


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
 
 struct rdar9677163 {
   struct Y { ~Y(); };
@@ -6,3 +8,22 @@
   Y::~Y() { } // expected-error{{non-friend class member '~Y' cannot have a qualified name}}
   ~Z(); // expected-error{{expected the class name after '~' to name the enclosing class}}
 };
+
+namespace GH56772 {
+
+template
+struct A {
+  ~A();
+};
+#if __cplusplus >= 202002L
+// FIXME: This isn't valid in C++20 and later.
+#endif
+
+struct B;
+
+template
+struct C {
+  ~B(); // expected-error {{expected the class name after '~' to name the enclosing class}}
+};
+
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11496,17 +11496,12 @@
   CXXRecordDecl *Record = Destructor->getParent();
   QualType ClassType = Context.getTypeDeclType(Record);
 
-  // FIXME: Shouldn't we be able to perform this check even when the class
-  // type is dependent? Both gcc and edg can handle that.
-  if (!ClassType->isDependentType()) {
-DeclarationName Name
-  = Context.DeclarationNames.getCXXDestructorName(
-Context.getCanonicalType(ClassType));
-if (NewFD->getDeclName() != Name) {
-  Diag(NewFD->getLocation(), diag::err_destructor_name);
-  NewFD->setInvalidDecl();
-  return Redeclar

[PATCH] D130936: [SemaCXX] Validate destructor is valid for dependent classes

2022-08-02 Thread Roy Jacobson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG508c431ed9ab: [SemaCXX] Validate destructor is valid for 
dependent classes (authored by royjacobson).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130936

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaCXX/member-class-11.cpp


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
 
 struct rdar9677163 {
   struct Y { ~Y(); };
@@ -6,3 +8,22 @@
   Y::~Y() { } // expected-error{{non-friend class member '~Y' cannot have a 
qualified name}}
   ~Z(); // expected-error{{expected the class name after '~' to name the 
enclosing class}}
 };
+
+namespace GH56772 {
+
+template
+struct A {
+  ~A();
+};
+#if __cplusplus >= 202002L
+// FIXME: This isn't valid in C++20 and later.
+#endif
+
+struct B;
+
+template
+struct C {
+  ~B(); // expected-error {{expected the class name after '~' to name the 
enclosing class}}
+};
+
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11496,17 +11496,12 @@
   CXXRecordDecl *Record = Destructor->getParent();
   QualType ClassType = Context.getTypeDeclType(Record);
 
-  // FIXME: Shouldn't we be able to perform this check even when the class
-  // type is dependent? Both gcc and edg can handle that.
-  if (!ClassType->isDependentType()) {
-DeclarationName Name
-  = Context.DeclarationNames.getCXXDestructorName(
-Context.getCanonicalType(ClassType));
-if (NewFD->getDeclName() != Name) {
-  Diag(NewFD->getLocation(), diag::err_destructor_name);
-  NewFD->setInvalidDecl();
-  return Redeclaration;
-}
+  DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
+  Context.getCanonicalType(ClassType));
+  if (NewFD->getDeclName() != Name) {
+Diag(NewFD->getLocation(), diag::err_destructor_name);
+NewFD->setInvalidDecl();
+return Redeclaration;
   }
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -52,6 +52,8 @@
 - Fixes an accepts-invalid bug in C when using a ``_Noreturn`` function
   specifier on something other than a function declaration. This fixes
   `Issue 56800 `_.
+- Fix `#56772 `_ - invalid
+  destructor names were incorrectly accepted on template classes.
 
 Improvements to Clang's diagnostics
 ^^^


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
 
 struct rdar9677163 {
   struct Y { ~Y(); };
@@ -6,3 +8,22 @@
   Y::~Y() { } // expected-error{{non-friend class member '~Y' cannot have a qualified name}}
   ~Z(); // expected-error{{expected the class name after '~' to name the enclosing class}}
 };
+
+namespace GH56772 {
+
+template
+struct A {
+  ~A();
+};
+#if __cplusplus >= 202002L
+// FIXME: This isn't valid in C++20 and later.
+#endif
+
+struct B;
+
+template
+struct C {
+  ~B(); // expected-error {{expected the class name after '~' to name the enclosing class}}
+};
+
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11496,17 +11496,12 @@
   CXXRecordDecl *Record = Destructor->getParent();
   QualType ClassType = Context.getTypeDeclType(Record);
 
-  // FIXME: Shouldn't we be able to perform this check even when the class
-  // type is dependent? Both gcc and edg can handle that.
-  if (!ClassType->isDependentType()) {
-DeclarationName Name
-  = Context.DeclarationNames.getCXXDestructorName(
-Context.getCanonicalType(ClassType));
-if (NewFD->getDeclName() != Name) {
-  Diag(NewFD->getLocation(), diag::err_destructor_name);
-  NewFD->setInvali

[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-08-04 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 450072.
royjacobson added a comment.

Rebase on main and re-target LLVM16 in cxx_status


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/AST/DeclCXX.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/conditionally-trivial-smfs.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constrained-special-member-functions.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -927,7 +927,7 @@
   

 https://wg21.link/p0848r3";>P0848R3
-No
+Clang 16
   
   
 https://wg21.link/p1616r1";>P1616R1
Index: clang/test/SemaCXX/constrained-special-member-functions.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constrained-special-member-functions.cpp
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s
+
+template 
+concept C0 = (N == 0);
+template 
+concept C1 = (N == 1);
+template 
+concept C2 = (N == 2);
+
+// Checks are indexed by:
+// Definition:
+//  1. Explicitly defaulted definition
+//  2. Deleted definition
+//  3. User provided definition
+// We have a less constrained user provided method that should not disable
+// the (copyable) triviality of the type.
+
+// Note that because Clang does not implement DRs 1496 and 1734, we say some
+// classes are trivial when the SMFs are deleted.
+
+template 
+struct DefaultConstructorChecker {
+DefaultConstructorChecker() requires C0 = default;
+DefaultConstructorChecker() requires C1 = delete;
+DefaultConstructorChecker() requires C2;
+DefaultConstructorChecker();
+};
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
+static_assert(__is_trivial(DefaultConstructorChecker<0>));
+// FIXME: DR1496
+static_assert(__is_trivial(DefaultConstructorChecker<1>));
+static_assert(!__is_trivial(DefaultConstructorChecker<2>));
+static_assert(!__is_trivial(DefaultConstructorChecker<3>));
+
+template 
+struct CopyConstructorChecker {
+CopyConstructorChecker(const CopyConstructorChecker&) requires C0 = default;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C1 = delete;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C2;
+CopyConstructorChecker(const CopyConstructorChecker&);
+};
+
+static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));
+static_assert(!__is_trivial(CopyConstructorChecker<0>));
+static_assert(!__is_trivial(CopyConstructorChecker<1>));
+static_assert(!__is_trivial(CopyConstructorChecker<2>));
+static_assert(!__is_trivial(CopyConstructorChecker<3>));
+
+template 
+struct MoveConstructorChecker {
+MoveConstructorChecker(MoveConstructorChecker&&) requires C0 = default;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C1 = delete;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C2;
+MoveConstructorChecker(MoveConstructorChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));
+static_assert(!__is_trivial(MoveConstructorChecker<0>));
+static_assert(!__is_trivial(MoveConstructorChecker<1>));
+static_assert(!__is_trivial(MoveConstructorChecker<2>));
+static_assert(!__is_trivial(MoveConstructorChecker<3>));
+
+template 
+struct MoveAssignmentChecker {
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0 = default;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1 = delete;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));
+// FIXME: DR1734.
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>));
+static_assert(__is_trivial(MoveAssignmentChecker<0>));
+// FIX

[PATCH] D130689: [LLVM] Update C++ standard to 17

2022-08-07 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

This seems to have been more disruptive than expected, since an existing 
CMakeCache.txt can make LLVM compile in previous C++14 configuration. This 
seems to make some of the bots fail in a way that makes the patches making use 
of C++17 features seem at fault.

See:
https://github.com/llvm/llvm-project/commit/ede96de751224487aea122af8bfb4e82bc54840b#commitcomment-80507826
https://reviews.llvm.org/rG32fd0b7fd5ab

How would you feel about adding something like

  #if defined(__cplusplus) && __cplusplus < 201703L
  #error "LLVM requires at least C++17"
  #endif

to some central header, to make this switch more visible?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130689

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130689: [LLVM] Update C++ standard to 17

2022-08-07 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D130689#3705145 , @thieta wrote:

> In D130689#3705131 , @royjacobson 
> wrote:
>
>> This seems to have been more disruptive than expected, since an existing 
>> CMakeCache.txt can make LLVM compile in previous C++14 configuration. This 
>> seems to make some of the bots fail in a way that makes the patches making 
>> use of C++17 features seem at fault.
>>
>> See:
>> https://github.com/llvm/llvm-project/commit/ede96de751224487aea122af8bfb4e82bc54840b#commitcomment-80507826
>> https://reviews.llvm.org/rG32fd0b7fd5ab
>>
>> How would you feel about adding something like
>>
>>   #if defined(__cplusplus) && __cplusplus < 201703L
>>   #error "LLVM requires at least C++17"
>>   #endif
>>
>> to some central header, to make this switch more visible?
>
> I am not opposed to that directly. But this seems a bit dangerous where bots 
> retain the cmakecache - there must be other cases where we can't really 
> protect in this way.
>
> Another approach would be to unset CMAKE_CXX_STANDARD if it's below 17 in 
> cmake directly.
>
> But in general - I am not a huge fan of CI / bots trying to keep the cache 
> around - many weird issues can arise from this.

This affects people on their work branches as well, and it's not obvious that 
it's a configuration error and not a broken master.

The CMake approach sounds cleaner to me, but I don't know CMake well enough to 
do it - if you could post a follow up patch I think it would be quite helpful.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130689

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130689: [LLVM] Update C++ standard to 17

2022-08-09 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D130689#3709834 , @thieta wrote:

> In D130689#3709742 , @aaron.ballman 
> wrote:
>
>> One thing I think would be a definite improvement is to have done an RFC on 
>> Discourse for these changes so that downstreams have a chance to weigh in on 
>> the impact. The patch was put up on Jul 28 and landed about a week later 
>> without any notification to the rest of the community who might not be 
>> watching cfe-commits -- that's a very fast turnaround and very little 
>> notification for such a significant change.
>
> Yeah this is on me. Honestly I didn't expect it to be that much of a problem 
> but rather the toolchain requirement we posted as part of it would be the big 
> hurdle where bot owners would have to upgrade to get the right versions. But 
> lesson learned  and we should add some more delays in the policy here: 
> https://llvm.org/docs/DeveloperPolicy.html#id23 and cover the C++ standards 
> upgrade.

Two points I want to add that I think would've been useful as well -

1. In addition to the toolchain soft errors, add a version check + #warning to 
some llvm header. This would be useful as it is more visible than the CMake 
warning and it could show up for cases where LLVM is used as a library+headers 
and not built from sources.
2. Delay actual usage of new language features until after the next release. 
Currently I see people pushing lots of cleanup commits that could hurt bug 
backports. It also has the benefit of making the transition more gradual.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130689

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131541: [Sema] Fix friend destructor declarations after D130936

2022-08-09 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

I accidentally broke friend destructor declarations in D130936 
.
Fix it by checking that destructor names match the class name only for
non-friends.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131541

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaCXX/member-class-11.cpp


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -26,4 +26,20 @@
   ~B(); // expected-error {{expected the class name after '~' to name the 
enclosing class}}
 };
 
+template 
+struct D {
+  friend T::S::~S();
+private:
+  static constexpr int secret = 42;
+};
+
+struct Q {
+  struct S { ~S(); };
+};
+
+Q::S::~S() {
+  void foo(int);
+  foo(D::secret);
+}
+
 }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11515,15 +11515,17 @@
   CheckConstructor(Constructor);
 } else if (CXXDestructorDecl *Destructor =
 dyn_cast(NewFD)) {
-  CXXRecordDecl *Record = Destructor->getParent();
-  QualType ClassType = Context.getTypeDeclType(Record);
-
-  DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
-  Context.getCanonicalType(ClassType));
-  if (NewFD->getDeclName() != Name) {
-Diag(NewFD->getLocation(), diag::err_destructor_name);
-NewFD->setInvalidDecl();
-return Redeclaration;
+  if (NewFD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None) {
+CXXRecordDecl *Record = Destructor->getParent();
+QualType ClassType = Context.getTypeDeclType(Record);
+
+DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
+Context.getCanonicalType(ClassType));
+if (NewFD->getDeclName() != Name) {
+  Diag(NewFD->getLocation(), diag::err_destructor_name);
+  NewFD->setInvalidDecl();
+  return Redeclaration;
+}
   }
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -26,4 +26,20 @@
   ~B(); // expected-error {{expected the class name after '~' to name the enclosing class}}
 };
 
+template 
+struct D {
+  friend T::S::~S();
+private:
+  static constexpr int secret = 42;
+};
+
+struct Q {
+  struct S { ~S(); };
+};
+
+Q::S::~S() {
+  void foo(int);
+  foo(D::secret);
+}
+
 }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11515,15 +11515,17 @@
   CheckConstructor(Constructor);
 } else if (CXXDestructorDecl *Destructor =
 dyn_cast(NewFD)) {
-  CXXRecordDecl *Record = Destructor->getParent();
-  QualType ClassType = Context.getTypeDeclType(Record);
-
-  DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
-  Context.getCanonicalType(ClassType));
-  if (NewFD->getDeclName() != Name) {
-Diag(NewFD->getLocation(), diag::err_destructor_name);
-NewFD->setInvalidDecl();
-return Redeclaration;
+  if (NewFD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None) {
+CXXRecordDecl *Record = Destructor->getParent();
+QualType ClassType = Context.getTypeDeclType(Record);
+
+DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
+Context.getCanonicalType(ClassType));
+if (NewFD->getDeclName() != Name) {
+  Diag(NewFD->getLocation(), diag::err_destructor_name);
+  NewFD->setInvalidDecl();
+  return Redeclaration;
+}
   }
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131541: [Sema] Fix friend destructor declarations after D130936

2022-08-10 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 451376.
royjacobson added a comment.

Don't regress on invalid (non-dependent) friend destructor declarations.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131541

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaCXX/member-class-11.cpp


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -26,4 +26,35 @@
   ~B(); // expected-error {{expected the class name after '~' to name the 
enclosing class}}
 };
 
+template 
+struct D {
+  friend T::S::~S();
+private:
+  static constexpr int secret = 42;
+};
+
+// FIXME: We should diagnose here.
+template 
+struct E {
+  friend T::S::~V();
+};
+
+struct Q {
+  struct S { ~S(); };
+};
+
+Q::S::~S() {
+  void foo(int);
+  foo(D::secret);
+}
+
+struct X {
+  ~X();
+};
+struct Y;
+
+struct Z {
+  friend X::~Y(); // expected-error {{expected the class name after '~' to 
name the enclosing class}}
+};
+
 }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11514,16 +11514,21 @@
 if (CXXConstructorDecl *Constructor = dyn_cast(NewFD)) 
{
   CheckConstructor(Constructor);
 } else if (CXXDestructorDecl *Destructor =
-dyn_cast(NewFD)) {
-  CXXRecordDecl *Record = Destructor->getParent();
-  QualType ClassType = Context.getTypeDeclType(Record);
-
-  DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
-  Context.getCanonicalType(ClassType));
-  if (NewFD->getDeclName() != Name) {
-Diag(NewFD->getLocation(), diag::err_destructor_name);
-NewFD->setInvalidDecl();
-return Redeclaration;
+   dyn_cast(NewFD)) {
+  // FIXME: We still don't diagnose on this case
+  // template 
+  // struct A { friend T::S::~V(); };
+  if (NewFD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None ||
+  !NewFD->isDependentContext()) {
+QualType ClassType = Destructor->getThisObjectType();
+
+DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
+Context.getCanonicalType(ClassType));
+if (NewFD->getDeclName() != Name) {
+  Diag(NewFD->getLocation(), diag::err_destructor_name);
+  NewFD->setInvalidDecl();
+  return Redeclaration;
+}
   }
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())


Index: clang/test/SemaCXX/member-class-11.cpp
===
--- clang/test/SemaCXX/member-class-11.cpp
+++ clang/test/SemaCXX/member-class-11.cpp
@@ -26,4 +26,35 @@
   ~B(); // expected-error {{expected the class name after '~' to name the enclosing class}}
 };
 
+template 
+struct D {
+  friend T::S::~S();
+private:
+  static constexpr int secret = 42;
+};
+
+// FIXME: We should diagnose here.
+template 
+struct E {
+  friend T::S::~V();
+};
+
+struct Q {
+  struct S { ~S(); };
+};
+
+Q::S::~S() {
+  void foo(int);
+  foo(D::secret);
+}
+
+struct X {
+  ~X();
+};
+struct Y;
+
+struct Z {
+  friend X::~Y(); // expected-error {{expected the class name after '~' to name the enclosing class}}
+};
+
 }
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11514,16 +11514,21 @@
 if (CXXConstructorDecl *Constructor = dyn_cast(NewFD)) {
   CheckConstructor(Constructor);
 } else if (CXXDestructorDecl *Destructor =
-dyn_cast(NewFD)) {
-  CXXRecordDecl *Record = Destructor->getParent();
-  QualType ClassType = Context.getTypeDeclType(Record);
-
-  DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
-  Context.getCanonicalType(ClassType));
-  if (NewFD->getDeclName() != Name) {
-Diag(NewFD->getLocation(), diag::err_destructor_name);
-NewFD->setInvalidDecl();
-return Redeclaration;
+   dyn_cast(NewFD)) {
+  // FIXME: We still don't diagnose on this case
+  // template 
+  // struct A { friend T::S::~V(); };
+  if (NewFD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None ||
+  !NewFD->isDependentContext()) {
+QualType ClassType = Destructor->getThisObjectType();
+
+DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
+Context.getCanonicalType(ClassType));
+if (NewFD->getDeclName() != Name) {
+  Diag(NewFD->getLocation(), diag::err_destructor_name);
+  NewFD->setInvalidDecl();
+  return Redeclaration;
+}
   }
 } else if (auto *Guide = dyn_cast(NewFD)) {
  

[PATCH] D131541: [Sema] Fix friend destructor declarations after D130936

2022-08-10 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a subscriber: hubert.reinterpretcast.
royjacobson added a comment.

Hi @hubert.reinterpretcast, thanks for the quick catch!

I have posted this initial patch, but it still misses the case

  template 
  struct E {
friend T::S::~V();
  };

Something goes wrong there that I haven't figured out yet. Do you think I 
should land this as-is to fix the master?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131541

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121646: [Concepts] Fix an assertion failure while diagnosing constrained function candidates

2022-03-14 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
royjacobson added a reviewer: erichkeane.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

See: https://github.com/llvm/llvm-project/issues/54379

I tried to see if I can reuse `ResolveAddressOfOverloadedFunction` for explicit 
function instantiation and so I managed to hit this ICE.

Bug was the diagnostic required an argument (%0) and specific code path didn't 
pass an argument.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121646

Files:
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaTemplate/concepts.cpp


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -208,3 +208,17 @@
 return (int*)nullptr; // FIXME: should error
   }
 }
+
+namespace PR54379 {
+template 
+struct A {
+  static void f() requires (N == 0) { return; } // expected-note {{candidate 
template ignored: constraints not satisfied}} expected-note {{evaluated to 
false}}
+  static void f() requires (N == 1) { return; } // expected-note {{candidate 
template ignored: constraints not satisfied}} expected-note {{evaluated to 
false}}
+};
+void (*f1)() = A<2>::f; // expected-error {{address of overloaded function 'f' 
does not match required type}}
+
+struct B {
+  template  static void f() requires (N2 == 0) { return; }  // 
expected-note {{candidate template ignored: constraints not satisfied [with N2 
= 1]}} expected-note {{evaluated to false}}
+};
+void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' 
does not match required type}}
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -10256,10 +10256,19 @@
   return false;
 if (!Satisfaction.IsSatisfied) {
   if (Complain) {
-if (InOverloadResolution)
+if (InOverloadResolution) {
+  SmallString<128> TemplateArgString;
+  TemplateArgString.clear();
+  if (FunctionTemplateDecl *FunTmpl = FD->getPrimaryTemplate()) {
+TemplateArgString += " ";
+TemplateArgString += S.getTemplateArgumentBindingsText(
+  FunTmpl->getTemplateParameters(), 
*FD->getTemplateSpecializationArgs());
+  }
+
   S.Diag(FD->getBeginLoc(),
- diag::note_ovl_candidate_unsatisfied_constraints);
-else
+ diag::note_ovl_candidate_unsatisfied_constraints)
+  << TemplateArgString;
+} else
   S.Diag(Loc, diag::err_addrof_function_constraints_not_satisfied)
   << FD;
 S.DiagnoseUnsatisfiedConstraint(Satisfaction);


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -208,3 +208,17 @@
 return (int*)nullptr; // FIXME: should error
   }
 }
+
+namespace PR54379 {
+template 
+struct A {
+  static void f() requires (N == 0) { return; } // expected-note {{candidate template ignored: constraints not satisfied}} expected-note {{evaluated to false}}
+  static void f() requires (N == 1) { return; } // expected-note {{candidate template ignored: constraints not satisfied}} expected-note {{evaluated to false}}
+};
+void (*f1)() = A<2>::f; // expected-error {{address of overloaded function 'f' does not match required type}}
+
+struct B {
+  template  static void f() requires (N2 == 0) { return; }  // expected-note {{candidate template ignored: constraints not satisfied [with N2 = 1]}} expected-note {{evaluated to false}}
+};
+void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' does not match required type}}
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -10256,10 +10256,19 @@
   return false;
 if (!Satisfaction.IsSatisfied) {
   if (Complain) {
-if (InOverloadResolution)
+if (InOverloadResolution) {
+  SmallString<128> TemplateArgString;
+  TemplateArgString.clear();
+  if (FunctionTemplateDecl *FunTmpl = FD->getPrimaryTemplate()) {
+TemplateArgString += " ";
+TemplateArgString += S.getTemplateArgumentBindingsText(
+  FunTmpl->getTemplateParameters(), *FD->getTemplateSpecializationArgs());
+  }
+
   S.Diag(FD->getBeginLoc(),
- diag::note_ovl_candidate_unsatisfied_constraints);
-else
+ diag::note_ovl_candidate_unsatisfied_constraints)
+  << TemplateArgString;
+} else
   S.Diag(Loc, diag::err_addrof_function_constraints_not_satisfie

[PATCH] D121646: [Concepts] Fix an assertion failure while diagnosing constrained function candidates

2022-03-14 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D121646#3380893 , @erichkeane 
wrote:

> This seems acceptable to me. Though, I wonder if 
> `getTemplateArgumentBindingsText` should produce the leading space, that way 
> we could just pass the result of it directly, rather than have to create a 
> SmallString everywhere.  WDYT?

There are other places (outside SemaOverload) that use this function and don't 
need a space, though.
I thought about just putting the space in the diagnostic itself, but then 
sometimes you don't get template arguments and it fails.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121646

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121646: [Concepts] Fix an assertion failure while diagnosing constrained function candidates

2022-03-14 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 415251.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121646

Files:
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaTemplate/concepts.cpp


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -208,3 +208,17 @@
 return (int*)nullptr; // FIXME: should error
   }
 }
+
+namespace PR54379 {
+template 
+struct A {
+  static void f() requires (N == 0) { return; } // expected-note {{candidate 
template ignored: constraints not satisfied}} expected-note {{evaluated to 
false}}
+  static void f() requires (N == 1) { return; } // expected-note {{candidate 
template ignored: constraints not satisfied}} expected-note {{evaluated to 
false}}
+};
+void (*f1)() = A<2>::f; // expected-error {{address of overloaded function 'f' 
does not match required type}}
+
+struct B {
+  template  static void f() requires (N2 == 0) { return; }  // 
expected-note {{candidate template ignored: constraints not satisfied [with N2 
= 1]}} expected-note {{evaluated to false}}
+};
+void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' 
does not match required type}}
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -10256,10 +10256,19 @@
   return false;
 if (!Satisfaction.IsSatisfied) {
   if (Complain) {
-if (InOverloadResolution)
+if (InOverloadResolution) {
+  SmallString<128> TemplateArgString;
+  if (FunctionTemplateDecl *FunTmpl = FD->getPrimaryTemplate()) {
+TemplateArgString += " ";
+TemplateArgString += S.getTemplateArgumentBindingsText(
+FunTmpl->getTemplateParameters(),
+*FD->getTemplateSpecializationArgs());
+  }
+
   S.Diag(FD->getBeginLoc(),
- diag::note_ovl_candidate_unsatisfied_constraints);
-else
+ diag::note_ovl_candidate_unsatisfied_constraints)
+  << TemplateArgString;
+} else
   S.Diag(Loc, diag::err_addrof_function_constraints_not_satisfied)
   << FD;
 S.DiagnoseUnsatisfiedConstraint(Satisfaction);


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -208,3 +208,17 @@
 return (int*)nullptr; // FIXME: should error
   }
 }
+
+namespace PR54379 {
+template 
+struct A {
+  static void f() requires (N == 0) { return; } // expected-note {{candidate template ignored: constraints not satisfied}} expected-note {{evaluated to false}}
+  static void f() requires (N == 1) { return; } // expected-note {{candidate template ignored: constraints not satisfied}} expected-note {{evaluated to false}}
+};
+void (*f1)() = A<2>::f; // expected-error {{address of overloaded function 'f' does not match required type}}
+
+struct B {
+  template  static void f() requires (N2 == 0) { return; }  // expected-note {{candidate template ignored: constraints not satisfied [with N2 = 1]}} expected-note {{evaluated to false}}
+};
+void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' does not match required type}}
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -10256,10 +10256,19 @@
   return false;
 if (!Satisfaction.IsSatisfied) {
   if (Complain) {
-if (InOverloadResolution)
+if (InOverloadResolution) {
+  SmallString<128> TemplateArgString;
+  if (FunctionTemplateDecl *FunTmpl = FD->getPrimaryTemplate()) {
+TemplateArgString += " ";
+TemplateArgString += S.getTemplateArgumentBindingsText(
+FunTmpl->getTemplateParameters(),
+*FD->getTemplateSpecializationArgs());
+  }
+
   S.Diag(FD->getBeginLoc(),
- diag::note_ovl_candidate_unsatisfied_constraints);
-else
+ diag::note_ovl_candidate_unsatisfied_constraints)
+  << TemplateArgString;
+} else
   S.Diag(Loc, diag::err_addrof_function_constraints_not_satisfied)
   << FD;
 S.DiagnoseUnsatisfiedConstraint(Satisfaction);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121646: [Concepts] Fix an assertion failure while diagnosing constrained function candidates

2022-03-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D121646#3382243 , @erichkeane 
wrote:

> In D121646#3380902 , @royjacobson 
> wrote:
>
>> In D121646#3380893 , @erichkeane 
>> wrote:
>>
>>> This seems acceptable to me. Though, I wonder if 
>>> `getTemplateArgumentBindingsText` should produce the leading space, that 
>>> way we could just pass the result of it directly, rather than have to 
>>> create a SmallString everywhere.  WDYT?
>>
>> There are other places (outside SemaOverload) that use this function and 
>> don't need a space, though.
>> I thought about just putting the space in the diagnostic itself, but then 
>> sometimes you don't get template arguments and it fails.
>
> I see.  I was hoping that wasn't the case!  OK, LGTM.  Let me know if you 
> need me to commit this for you.

Yes, thank you :)
(with author as "Roy Jacobson ")


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121646

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121965: Add validation for number of arguments of __builtin_memcpy_inline

2022-03-17 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

__builtin_memcpy_inline doesn't use the usual builtin argument validation code,
so it crashed when receiving wrong number of argument. Add the missing 
validation
check.

Open issue: https://github.com/llvm/llvm-project/issues/52949


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121965

Files:
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/builtins-memcpy-inline.cpp


Index: clang/test/Sema/builtins-memcpy-inline.cpp
===
--- clang/test/Sema/builtins-memcpy-inline.cpp
+++ clang/test/Sema/builtins-memcpy-inline.cpp
@@ -42,3 +42,8 @@
   __builtin_memcpy_inline(ptr, a, 5);
   __builtin_memcpy_inline(a, ptr, 5);
 }
+
+void test_memcpy_inline_num_args(void *dst, void *src) {
+ __builtin_memcpy_inline(); // expected-error {{too few arguments to function 
call}}
+ __builtin_memcpy_inline(dst, src, 4, NULL); // expected-error {{too many 
arguments to function call}}
+}
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1679,7 +1679,10 @@
 if ((ICEArguments & (1 << ArgNo)) == 0) continue;
 
 llvm::APSInt Result;
-if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))
+// If we don't have enough arguments, continue so we can issue better
+// diagnostic in checkArgCount(...)
+if (ArgNo < TheCall->getNumArgs() &&
+SemaBuiltinConstantArg(TheCall, ArgNo, Result))
   return true;
 ICEArguments &= ~(1 << ArgNo);
   }
@@ -1943,6 +1946,8 @@
   case Builtin::BI__builtin_nontemporal_store:
 return SemaBuiltinNontemporalOverloaded(TheCallResult);
   case Builtin::BI__builtin_memcpy_inline: {
+if (checkArgCount(*this, TheCall, 3))
+  return ExprError();
 auto ArgArrayConversionFailed = [&](unsigned Arg) {
   ExprResult ArgExpr =
   DefaultFunctionArrayLvalueConversion(TheCall->getArg(Arg));


Index: clang/test/Sema/builtins-memcpy-inline.cpp
===
--- clang/test/Sema/builtins-memcpy-inline.cpp
+++ clang/test/Sema/builtins-memcpy-inline.cpp
@@ -42,3 +42,8 @@
   __builtin_memcpy_inline(ptr, a, 5);
   __builtin_memcpy_inline(a, ptr, 5);
 }
+
+void test_memcpy_inline_num_args(void *dst, void *src) {
+ __builtin_memcpy_inline(); // expected-error {{too few arguments to function call}}
+ __builtin_memcpy_inline(dst, src, 4, NULL); // expected-error {{too many arguments to function call}}
+}
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -1679,7 +1679,10 @@
 if ((ICEArguments & (1 << ArgNo)) == 0) continue;
 
 llvm::APSInt Result;
-if (SemaBuiltinConstantArg(TheCall, ArgNo, Result))
+// If we don't have enough arguments, continue so we can issue better
+// diagnostic in checkArgCount(...)
+if (ArgNo < TheCall->getNumArgs() &&
+SemaBuiltinConstantArg(TheCall, ArgNo, Result))
   return true;
 ICEArguments &= ~(1 << ArgNo);
   }
@@ -1943,6 +1946,8 @@
   case Builtin::BI__builtin_nontemporal_store:
 return SemaBuiltinNontemporalOverloaded(TheCallResult);
   case Builtin::BI__builtin_memcpy_inline: {
+if (checkArgCount(*this, TheCall, 3))
+  return ExprError();
 auto ArgArrayConversionFailed = [&](unsigned Arg) {
   ExprResult ArgExpr =
   DefaultFunctionArrayLvalueConversion(TheCall->getArg(Arg));
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121965: Add validation for number of arguments of __builtin_memcpy_inline

2022-03-18 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

@gchatelet

In D121965#3391714 , @gchatelet wrote:

> Thx!

Thanks, will you be able to commit this for me as "Roy Jacobson 
"? I don't have write access :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121965

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-19 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Placeholder types were not checked for constraint satisfaction when modified by 
references.
GitHub issue #54443


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122083

Files:
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaTemplate/concepts.cpp


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 
'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 
'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not 
satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -222,3 +222,26 @@
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' 
does not match required type}}
 }
+
+namespace PR54443 {
+
+template 
+struct is_same { static constexpr bool value = false; };
+
+template 
+struct is_same { static constexpr bool value = true; };
+
+template 
+concept same_as = is_same::value; // expected-note-re 4 {{because {{.*}} 
evaluated to false}}
+
+int const &f();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does 
not satisfy 'same_as'}}
+same_as auto &i2 = f();
+same_as auto &&i3 = f(); // expected-error {{deduced type 'const 
int &' does not satisfy 'same_as'}}
+
+same_as auto i4 = f(); // expected-error {{deduced type 'int' 
does not satisfy 'same_as'}}
+same_as auto &i5 = f(); // expected-error {{deduced type 'const 
int' does not satisfy 'same_as'}}
+same_as auto &&i6 = f();
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,7 +4769,8 @@
   return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs()) {
+  if (const auto *AT =
+  Type.getType().getNonReferenceType()->getAs()) {
 if (AT->isConstrained() && !IgnoreConstraints) {
   auto ConstraintsResult =
   CheckDeducedPlaceholderConstraints(*this, *AT,


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -222,3 +222,26 @@
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' does not match required type}}
 }
+
+namespace PR54443 {
+
+template 
+struct is_same { static constexpr bool value = false; };
+
+template 
+struct is_same { static constexpr bool value = true; };
+
+template 
+concept same_as = is_same::value; // expected-note-re 4 {{because {{.*}} evaluated to false}}
+
+int const &f();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i2 = f();
+same_as auto &&i3 = f(); // expected-error {{deduced type 'const int &' does not satisfy 'same_as'}}
+
+same_as auto i4 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i5 = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto &&i6 = f();
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,7 +4769,8 @@
   return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs()) {
+  if (const auto *AT =
+  Type.getType().getNonReferenceType()->getAs()) {
 if (AT->isConstrained() && !IgnoreConstraints) {
   auto ConstraintsResult =
   CheckDeducedPlaceholderCo

[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-20 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 416803.
royjacobson edited the summary of this revision.
royjacobson added a comment.

I noticed issue #53911 which is very similar so I fixed it as well.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122083

Files:
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaTemplate/concepts.cpp


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 
'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 
'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not 
satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' 
evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
+return (void*)nullptr;
   }
-  C auto *f2() {
-return (int*)nullptr; // FIXME: should error
+  C auto *f2() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
+  }
+  C auto *f3() { // expected-error {{deduced type 'int' does not satisfy 
'C'}}
+return (int*)nullptr;
   }
 }
 
@@ -222,3 +225,26 @@
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' 
does not match required type}}
 }
+
+namespace PR54443 {
+
+template 
+struct is_same { static constexpr bool value = false; };
+
+template 
+struct is_same { static constexpr bool value = true; };
+
+template 
+concept same_as = is_same::value; // expected-note-re 4 {{because {{.*}} 
evaluated to false}}
+
+int const &f();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does 
not satisfy 'same_as'}}
+same_as auto &i2 = f();
+same_as auto &&i3 = f(); // expected-error {{deduced type 'const 
int &' does not satisfy 'same_as'}}
+
+same_as auto i4 = f(); // expected-error {{deduced type 'int' 
does not satisfy 'same_as'}}
+same_as auto &i5 = f(); // expected-error {{deduced type 'const 
int' does not satisfy 'same_as'}}
+same_as auto &&i6 = f();
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,12 +4769,14 @@
   return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs()) {
+  QualType MaybeAuto = Type.getType().getNonReferenceType();
+  while (MaybeAuto->isPointerType()) {
+MaybeAuto = MaybeAuto->getPointeeType();
+  }
+  if (const auto *AT = MaybeAuto->getAs()) {
 if (AT->isConstrained() && !IgnoreConstraints) {
-  auto ConstraintsResult =
-  CheckDeducedPlaceholderConstraints(*this, *AT,
- Type.getContainedAutoTypeLoc(),
- DeducedType);
+  auto ConstraintsResult = CheckDeducedPlaceholderConstraints(
+  *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType);
   if (ConstraintsResult != DAR_Succeeded)
 return ConstraintsResult;
 }


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type '

[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 417591.
royjacobson added a comment.

Remove the curly brackets from one line loop.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122083

Files:
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaTemplate/concepts.cpp


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 
'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 
'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not 
satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' 
evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
+return (void*)nullptr;
   }
-  C auto *f2() {
-return (int*)nullptr; // FIXME: should error
+  C auto *f2() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
+  }
+  C auto *f3() { // expected-error {{deduced type 'int' does not satisfy 
'C'}}
+return (int*)nullptr;
   }
 }
 
@@ -222,3 +225,26 @@
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' 
does not match required type}}
 }
+
+namespace PR54443 {
+
+template 
+struct is_same { static constexpr bool value = false; };
+
+template 
+struct is_same { static constexpr bool value = true; };
+
+template 
+concept same_as = is_same::value; // expected-note-re 4 {{because {{.*}} 
evaluated to false}}
+
+int const &f();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does 
not satisfy 'same_as'}}
+same_as auto &i2 = f();
+same_as auto &&i3 = f(); // expected-error {{deduced type 'const 
int &' does not satisfy 'same_as'}}
+
+same_as auto i4 = f(); // expected-error {{deduced type 'int' 
does not satisfy 'same_as'}}
+same_as auto &i5 = f(); // expected-error {{deduced type 'const 
int' does not satisfy 'same_as'}}
+same_as auto &&i6 = f();
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,12 +4769,13 @@
   return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs()) {
+  QualType MaybeAuto = Type.getType().getNonReferenceType();
+  while (MaybeAuto->isPointerType())
+MaybeAuto = MaybeAuto->getPointeeType();
+  if (const auto *AT = MaybeAuto->getAs()) {
 if (AT->isConstrained() && !IgnoreConstraints) {
-  auto ConstraintsResult =
-  CheckDeducedPlaceholderConstraints(*this, *AT,
- Type.getContainedAutoTypeLoc(),
- DeducedType);
+  auto ConstraintsResult = CheckDeducedPlaceholderConstraints(
+  *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType);
   if (ConstraintsResult != DAR_Succeeded)
 return ConstraintsResult;
 }


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
+return (void*)nullptr;
   }
-  C auto *f2() 

[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson marked an inline comment as done.
royjacobson added a comment.

In D122083#3402289 , @erichkeane 
wrote:

> Can you add some tests for the OTHER forms of 'auto' as well?  We have 
> `decltype(auto)` and `auto_type`, and I want to make sure whatever we do with 
> those 'looks right'.

Can we have constraints on `__auto_type`? As far as I understand it, it's a C 
extension with very limited C++ support.
About decltype(auto) - we can't have `*`/`&` modifiers with it, and that's 
already covered by tests like p7-cxx14.

So (I think?) it's always invalid code and it fails earlier during parsing.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122083

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 417602.
royjacobson added a comment.

Add test for auto**& combination


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122083

Files:
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
+return (void*)nullptr;
   }
-  C auto *f2() {
-return (int*)nullptr; // FIXME: should error
+  C auto *f2() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
+  }
+  C auto *f3() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
   }
 }
 
@@ -222,3 +225,34 @@
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' does not match required type}}
 }
+
+namespace PR54443 {
+
+template 
+struct is_same { static constexpr bool value = false; };
+
+template 
+struct is_same { static constexpr bool value = true; };
+
+template 
+concept same_as = is_same::value; // expected-note-re 4 {{because {{.*}} evaluated to false}}
+
+int const &f();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i2 = f();
+same_as auto &&i3 = f(); // expected-error {{deduced type 'const int &' does not satisfy 'same_as'}}
+
+same_as auto i4 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i5 = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto &&i6 = f();
+
+template 
+concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
+
+int **const &g();
+
+C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&j2 = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}}
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,12 +4769,13 @@
   return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs()) {
+  QualType MaybeAuto = Type.getType().getNonReferenceType();
+  while (MaybeAuto->isPointerType())
+MaybeAuto = MaybeAuto->getPointeeType();
+  if (const auto *AT = MaybeAuto->getAs()) {
 if (AT->isConstrained() && !IgnoreConstraints) {
-  auto ConstraintsResult =
-  CheckDeducedPlaceholderConstraints(*this, *AT,
- Type.getContainedAutoTypeLoc(),
- DeducedType);
+  auto ConstraintsResult = CheckDeducedPlaceholderConstraints(
+  *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType);
   if (ConstraintsResult != DAR_Succeeded)
 return ConstraintsResult;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D122083#3402445 , @erichkeane 
wrote:

> 1 more test I'd like to see that doesn't seem covered (ref to ptr),

Added, good idea.

> AND according to @aaron.ballman we need "Release Notes" for this.  Otherwise 
> LGTM.  Do you have commit rights yet?

Yeah, I got commit rights :)
This should go into "Bug Fixes" section in `clang/docs/ReleaseNotes.rst`, 
right? Or "C++20 Feature Support"?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122083

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 417618.
royjacobson added a comment.

Added release notes.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122083

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
+return (void*)nullptr;
   }
-  C auto *f2() {
-return (int*)nullptr; // FIXME: should error
+  C auto *f2() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
+  }
+  C auto *f3() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
   }
 }
 
@@ -222,3 +225,34 @@
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' does not match required type}}
 }
+
+namespace PR54443 {
+
+template 
+struct is_same { static constexpr bool value = false; };
+
+template 
+struct is_same { static constexpr bool value = true; };
+
+template 
+concept same_as = is_same::value; // expected-note-re 4 {{because {{.*}} evaluated to false}}
+
+int const &f();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i2 = f();
+same_as auto &&i3 = f(); // expected-error {{deduced type 'const int &' does not satisfy 'same_as'}}
+
+same_as auto i4 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i5 = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto &&i6 = f();
+
+template 
+concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
+
+int **const &g();
+
+C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&j2 = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}}
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,12 +4769,13 @@
   return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs()) {
+  QualType MaybeAuto = Type.getType().getNonReferenceType();
+  while (MaybeAuto->isPointerType())
+MaybeAuto = MaybeAuto->getPointeeType();
+  if (const auto *AT = MaybeAuto->getAs()) {
 if (AT->isConstrained() && !IgnoreConstraints) {
-  auto ConstraintsResult =
-  CheckDeducedPlaceholderConstraints(*this, *AT,
- Type.getContainedAutoTypeLoc(),
- DeducedType);
+  auto ConstraintsResult = CheckDeducedPlaceholderConstraints(
+  *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType);
   if (ConstraintsResult != DAR_Succeeded)
 return ConstraintsResult;
 }
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -61,6 +61,10 @@
   size expression. This was fixed and ``::getArraySize()`` will now always
   either return ``None`` or a ``llvm::Optional`` wrapping a valid ``Expr*``.
   This fixes `Issue 53742 `_.
+- Placeholder constraints, as in `Concept auto x = f();`, were not checked when modifiers
+  like ``auto&`` or ``auto**`` were added. These constraints are now checked.
+  This fixes  `Issue 53911 `_
+  and  `Issue 54443 `_.
 
 Improvements to Clang's diagnostics
 ^^^
_

[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 417624.
royjacobson added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122083

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
+return (void*)nullptr;
   }
-  C auto *f2() {
-return (int*)nullptr; // FIXME: should error
+  C auto *f2() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
+  }
+  C auto *f3() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
   }
 }
 
@@ -222,3 +225,34 @@
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' does not match required type}}
 }
+
+namespace PR54443 {
+
+template 
+struct is_same { static constexpr bool value = false; };
+
+template 
+struct is_same { static constexpr bool value = true; };
+
+template 
+concept same_as = is_same::value; // expected-note-re 4 {{because {{.*}} evaluated to false}}
+
+int const &f();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i2 = f();
+same_as auto &&i3 = f(); // expected-error {{deduced type 'const int &' does not satisfy 'same_as'}}
+
+same_as auto i4 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i5 = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto &&i6 = f();
+
+template 
+concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
+
+int **const &g();
+
+C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&j2 = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}}
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,12 +4769,13 @@
   return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs()) {
+  QualType MaybeAuto = Type.getType().getNonReferenceType();
+  while (MaybeAuto->isPointerType())
+MaybeAuto = MaybeAuto->getPointeeType();
+  if (const auto *AT = MaybeAuto->getAs()) {
 if (AT->isConstrained() && !IgnoreConstraints) {
-  auto ConstraintsResult =
-  CheckDeducedPlaceholderConstraints(*this, *AT,
- Type.getContainedAutoTypeLoc(),
- DeducedType);
+  auto ConstraintsResult = CheckDeducedPlaceholderConstraints(
+  *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType);
   if (ConstraintsResult != DAR_Succeeded)
 return ConstraintsResult;
 }
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -65,6 +65,10 @@
   fixes `Issue 53044 `_.
 - Allow `-Wno-gnu` to silence GNU extension diagnostics for pointer arithmetic
   diagnostics. Fixes `Issue 5 `_.
+- Placeholder constraints, as in `Concept auto x = f();`, were not checked when modifiers
+  like ``auto&`` or ``auto**`` were added. These constraints are now checked.
+  This fixes  `Issue 53911 `_
+  and  `Issue 54443 `_.
 
 Improvements to Clang's diagnostics
 ^^^

[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-23 Thread Roy Jacobson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG94fd00f41ebd: [Concepts] Fix placeholder constraints when 
references are involved (authored by royjacobson).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122083

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
+return (void*)nullptr;
   }
-  C auto *f2() {
-return (int*)nullptr; // FIXME: should error
+  C auto *f2() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
+  }
+  C auto *f3() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
   }
 }
 
@@ -222,3 +225,34 @@
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' does not match required type}}
 }
+
+namespace PR54443 {
+
+template 
+struct is_same { static constexpr bool value = false; };
+
+template 
+struct is_same { static constexpr bool value = true; };
+
+template 
+concept same_as = is_same::value; // expected-note-re 4 {{because {{.*}} evaluated to false}}
+
+int const &f();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i2 = f();
+same_as auto &&i3 = f(); // expected-error {{deduced type 'const int &' does not satisfy 'same_as'}}
+
+same_as auto i4 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto &i5 = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto &&i6 = f();
+
+template 
+concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
+
+int **const &g();
+
+C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&j2 = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}}
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,12 +4769,13 @@
   return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs()) {
+  QualType MaybeAuto = Type.getType().getNonReferenceType();
+  while (MaybeAuto->isPointerType())
+MaybeAuto = MaybeAuto->getPointeeType();
+  if (const auto *AT = MaybeAuto->getAs()) {
 if (AT->isConstrained() && !IgnoreConstraints) {
-  auto ConstraintsResult =
-  CheckDeducedPlaceholderConstraints(*this, *AT,
- Type.getContainedAutoTypeLoc(),
- DeducedType);
+  auto ConstraintsResult = CheckDeducedPlaceholderConstraints(
+  *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType);
   if (ConstraintsResult != DAR_Succeeded)
 return ConstraintsResult;
 }
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -65,6 +65,10 @@
   fixes `Issue 53044 `_.
 - Allow `-Wno-gnu` to silence GNU extension diagnostics for pointer arithmetic
   diagnostics. Fixes `Issue 5 `_.
+- Placeholder constraints, as in `Concept auto x = f();`, were not checked when modifiers
+  like ``auto&`` or ``auto**`` were added. These constraints are now checked.
+  This fixes  `Issue 53911 `_
+  and  `Issue 54443 

[PATCH] D123182: [Concepts] Fix issue #53640

2022-04-11 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 422030.
royjacobson added a comment.

Formatting + clarify docs a bit


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5143,18 +5143,20 @@
 /// candidate with a reversed parameter order. In this case, the corresponding
 /// P/A pairs between FT1 and FT2 are reversed.
 ///
+/// \param AllowOrderingByConstraints If \c is false, don't check whether one
+/// of the templates is more constrained than the other. Default is true.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
-FunctionTemplateDecl *
-Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2,
- bool Reversed) {
-
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
+FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
+TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
+unsigned NumCallArguments2, bool Reversed,
+bool AllowOrderingByConstraints) {
+
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2952,16 +2952,24 @@
 }
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
-/// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// for equality of their parameter types. Caller has already checked that
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, the parameters of `NewType` will be compared in
+/// reverse order. That's useful if one of the functions is being used as a C++20
+/// synthesized operator overload with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *ArgPos, bool Reversed) {
+  assert(OldType->getNumParams() == NewType->getNumParams() &&
+ "Can't compare parameters of functions with dif

[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-11 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaOverload.cpp:2958
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, exactly one of FT1 and FT2 is an overload
+/// candidate with a reversed parameter order.

erichkeane wrote:
> I don't really get what you mean for 'Reversed', can you better clarify?  
> Both in comments, and here?
I tried to modify the documentation a bit, I hope it's more understandable :)

C++20 added 'synthesized reverse operator overloads'. We support them in the 
overload resolution code by just remembering if we use a candidate with reverse 
order.

I need this here so the example in p6 with `operator==` works. It's a pretty 
annoying and weird corner case, but if it's explicitly in one of the standard's 
examples I might as well support it...

(BTW, GCC just don't implement this: 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105174)



Comment at: clang/lib/Sema/SemaOverload.cpp:9829
+  bool CanCompareConstraints = false;
+  if (Cand1.Function && Cand2.Function && Cand1.Function->hasPrototype() &&
+  Cand2.Function->hasPrototype()) {

erichkeane wrote:
> Since the point of this is to just calculate the CanCompareConstraints, I 
> think it should be a separate function called below where it is used.  
Do you mean as in a separate `Sema` function? Or a local lambda?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 423116.
royjacobson marked an inline comment as not done.
royjacobson added a comment.

Update for look inside FunctionParamTypesAreEqual to be index based and simpler.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5143,18 +5143,20 @@
 /// candidate with a reversed parameter order. In this case, the corresponding
 /// P/A pairs between FT1 and FT2 are reversed.
 ///
+/// \param AllowOrderingByConstraints If \c is false, don't check whether one
+/// of the templates is more constrained than the other. Default is true.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
-FunctionTemplateDecl *
-Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2,
- bool Reversed) {
-
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
+FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
+TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
+unsigned NumCallArguments2, bool Reversed,
+bool AllowOrderingByConstraints) {
+
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2952,24 +2952,30 @@
 }
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
-/// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// for equality of their parameter types. Caller has already checked that
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, the parameters of `NewType` will be compared in
+/// reverse order. That's useful if one of the functions is being used as a C++20
+/// synthesized operator overload with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *ArgPos, bool Reversed) {
+  assert(OldType->get

[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaOverload.cpp:2967
+ "parameters!");
+  for (FunctionProtoType::param_type_iterator
+   O = OldType->param_type_begin(),

erichkeane wrote:
> Thanks for the clarification on 'Reversed'.  The comment makes it more clear.
> 
> This whole 'for' header is... really tough to mentally parse, even BEFORE 
> this, and now it is even worse with 'Reversed' involved.  I would prefer that 
> the iterators be initialized ahead of time.  Additionally, can we use 
> `reverse_iterator` for the 'NewType' instead of branching on `Reversed` here? 
>  
> 
> Any other suggestions you have to simplify this loop would also be 
> appreciated.  I might ALSO consider using 'zip' here?
I made it index based which IMO is easier to understand now.

I thought reverse_iterator would be annoying because I would need to make the 
code a template since it's a different type.

Also - ping about the comment in isBetterOverloadCandidate :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 423120.
royjacobson added a comment.

Split the 'can compare constraints' code into a static function.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5143,18 +5143,20 @@
 /// candidate with a reversed parameter order. In this case, the corresponding
 /// P/A pairs between FT1 and FT2 are reversed.
 ///
+/// \param AllowOrderingByConstraints If \c is false, don't check whether one
+/// of the templates is more constrained than the other. Default is true.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
-FunctionTemplateDecl *
-Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2,
- bool Reversed) {
-
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
+FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
+TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
+unsigned NumCallArguments2, bool Reversed,
+bool AllowOrderingByConstraints) {
+
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2952,24 +2952,30 @@
 }
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
-/// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// for equality of their parameter types. Caller has already checked that
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, the parameters of `NewType` will be compared in
+/// reverse order. That's useful if one of the functions is being used as a C++20
+/// synthesized operator overload with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *ArgPos, bool Reversed) {
+  assert(OldType->getNumParams() == NewType->getNumParams() &&
+ "Can't compare

[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson marked 2 inline comments as done.
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaOverload.cpp:9829
+  bool CanCompareConstraints = false;
+  if (Cand1.Function && Cand2.Function && Cand1.Function->hasPrototype() &&
+  Cand2.Function->hasPrototype()) {

erichkeane wrote:
> royjacobson wrote:
> > erichkeane wrote:
> > > Since the point of this is to just calculate the CanCompareConstraints, I 
> > > think it should be a separate function called below where it is used.  
> > Do you mean as in a separate `Sema` function? Or a local lambda?
> Just a static function is fine, basically its a whole lot of work happening 
> in this function for a single result, so I'm suggesting splitting off the 
> calculation for `CanCompareConstraints` into its own function, so you get:
> 
> `bool CanCompareConstrants = new_function(...);`
Done


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 423169.
royjacobson marked an inline comment as done.
royjacobson added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5143,18 +5143,20 @@
 /// candidate with a reversed parameter order. In this case, the corresponding
 /// P/A pairs between FT1 and FT2 are reversed.
 ///
+/// \param AllowOrderingByConstraints If \c is false, don't check whether one
+/// of the templates is more constrained than the other. Default is true.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
-FunctionTemplateDecl *
-Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2,
- bool Reversed) {
-
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
+FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
+TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
+unsigned NumCallArguments2, bool Reversed,
+bool AllowOrderingByConstraints) {
+
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2945,24 +2945,30 @@
 }
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
-/// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// for equality of their parameter types. Caller has already checked that
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, the parameters of `NewType` will be compared in
+/// reverse order. That's useful if one of the functions is being used as a C++20
+/// synthesized operator overload with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *ArgPos, bool Reversed) {
+  assert(OldType->getNumParams() == NewType->getNumParams() &&
+ "Can't compare parameters 

[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-16 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 423229.
royjacobson added a comment.

Rebase again (HEAD CI was broken)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5143,18 +5143,20 @@
 /// candidate with a reversed parameter order. In this case, the corresponding
 /// P/A pairs between FT1 and FT2 are reversed.
 ///
+/// \param AllowOrderingByConstraints If \c is false, don't check whether one
+/// of the templates is more constrained than the other. Default is true.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
-FunctionTemplateDecl *
-Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2,
- bool Reversed) {
-
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
+FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
+TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
+unsigned NumCallArguments2, bool Reversed,
+bool AllowOrderingByConstraints) {
+
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2952,24 +2952,30 @@
 }
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
-/// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// for equality of their parameter types. Caller has already checked that
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, the parameters of `NewType` will be compared in
+/// reverse order. That's useful if one of the functions is being used as a C++20
+/// synthesized operator overload with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *ArgPos, bool Reversed) {
+  assert(OldType->getNumParams() == NewType->getNumParams() &&
+ "Can't compare parameters of functions with d

[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-16 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

Thanks @erichkeane! I will land this on Monday if there are no further comments 
and the CI looks good.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-19 Thread Roy Jacobson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG454d1df9423c: [Concepts] Fix overload resolution bug with 
constrained candidates (authored by royjacobson).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5143,18 +5143,20 @@
 /// candidate with a reversed parameter order. In this case, the corresponding
 /// P/A pairs between FT1 and FT2 are reversed.
 ///
+/// \param AllowOrderingByConstraints If \c is false, don't check whether one
+/// of the templates is more constrained than the other. Default is true.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
-FunctionTemplateDecl *
-Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2,
- bool Reversed) {
-
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
+FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
+TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
+unsigned NumCallArguments2, bool Reversed,
+bool AllowOrderingByConstraints) {
+
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2945,24 +2945,30 @@
 }
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
-/// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// for equality of their parameter types. Caller has already checked that
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, the parameters of `NewType` will be compared in
+/// reverse order. That's useful if one of the functions is being used as a C++20
+/// synthesized operator overload with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *A

[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-19 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a subscriber: Mordante.
royjacobson added a comment.

So, it seems like this broke one of `basic_arg_format`'s private constructors.. 
Sorry for that.

  //format_arg.h:167
  explicit basic_format_arg(_Tp __v) noexcept
requires(same_as<_Tp, char_type> ||
 (same_as<_Tp, char> && same_as)) []
  
  //format_arg.h:248
  explicit basic_format_arg(const _Tp& __v) [...]

This is now ambiguous when calling `basic_format_arg(char)` because the 
argument type is different and comparing constraints is not allowed. @Mordante 
could you maybe take a look? I've reverted in the meantime.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 424747.
royjacobson added a comment.

Rebase after fix.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5143,18 +5143,20 @@
 /// candidate with a reversed parameter order. In this case, the corresponding
 /// P/A pairs between FT1 and FT2 are reversed.
 ///
+/// \param AllowOrderingByConstraints If \c is false, don't check whether one
+/// of the templates is more constrained than the other. Default is true.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
-FunctionTemplateDecl *
-Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2,
- bool Reversed) {
-
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
+FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
+TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
+unsigned NumCallArguments2, bool Reversed,
+bool AllowOrderingByConstraints) {
+
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2945,24 +2945,30 @@
 }
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
-/// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// for equality of their parameter types. Caller has already checked that
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, the parameters of `NewType` will be compared in
+/// reverse order. That's useful if one of the functions is being used as a C++20
+/// synthesized operator overload with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *ArgPos, bool Reversed) {
+  assert(OldType->getNumParams() == NewType->getNumParams() &&
+ "Can't compare parameters of functions with different number 

[PATCH] D123182: [Concepts] Fix overload resolution bug with constrained candidates

2022-04-23 Thread Roy Jacobson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG807e418413a0: [Concepts] Fix overload resolution bug with 
constrained candidates (authored by royjacobson).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123182

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp

Index: clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+struct A;
+struct B;
+
+template  constexpr bool True = true;
+template  concept C = True;
+
+void f(C auto &, auto &) = delete;
+template  void f(Q &, C auto &);
+
+void g(struct A *ap, struct B *bp) {
+  f(*ap, *bp);
+}
+
+template  struct X {};
+
+template  bool operator==(X, V) = delete;
+templatebool operator==(T, X);
+
+bool h() {
+  return X{} == 0;
+}
+
+namespace PR53640 {
+
+template 
+concept C = true;
+
+template 
+void f(T t) {} // expected-note {{candidate function [with T = int]}}
+
+template 
+void f(const T &t) {} // expected-note {{candidate function [with T = int]}}
+
+int g() {
+  f(0); // expected-error {{call to 'f' is ambiguous}}
+}
+
+struct S {
+  template  explicit S(T) noexcept requires C {} // expected-note {{candidate constructor}}
+  template  explicit S(const T &) noexcept {}   // expected-note {{candidate constructor}}
+};
+
+int h() {
+  S s(4); // expected-error-re {{call to constructor of {{.*}} is ambiguous}}
+}
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5143,18 +5143,20 @@
 /// candidate with a reversed parameter order. In this case, the corresponding
 /// P/A pairs between FT1 and FT2 are reversed.
 ///
+/// \param AllowOrderingByConstraints If \c is false, don't check whether one
+/// of the templates is more constrained than the other. Default is true.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
-FunctionTemplateDecl *
-Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC,
- unsigned NumCallArguments1,
- unsigned NumCallArguments2,
- bool Reversed) {
-
-  auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * {
+FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
+FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
+TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
+unsigned NumCallArguments2, bool Reversed,
+bool AllowOrderingByConstraints) {
+
+  auto JudgeByConstraints = [&]() -> FunctionTemplateDecl * {
+if (!AllowOrderingByConstraints)
+  return nullptr;
 llvm::SmallVector AC1, AC2;
 FT1->getAssociatedConstraints(AC1);
 FT2->getAssociatedConstraints(AC2);
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2945,24 +2945,30 @@
 }
 
 /// FunctionParamTypesAreEqual - This routine checks two function proto types
-/// for equality of their argument types. Caller has already checked that
-/// they have same number of arguments.  If the parameters are different,
+/// for equality of their parameter types. Caller has already checked that
+/// they have same number of parameters.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
+/// If `Reversed` is true, the parameters of `NewType` will be compared in
+/// reverse order. That's useful if one of the functions is being used as a C++20
+/// synthesized operator overload with a reversed parameter order.
 bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
   const FunctionProtoType *NewType,
-  unsigned *ArgPos) {
-  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
-  N = NewType->param_type_begin(),
-  E = OldType->param_type_end();
-   O && (O != E); ++O, ++N) {
+  unsigned *A

[PATCH] D129170: [Sema] Add deprecation warnings for some compiler provided __has_* type traits

2022-07-11 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 443742.
royjacobson added a comment.

Warn on <=C++03 as well, warn on __has_trivial_destructor.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129170

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/dcl.decl/dcl.init/p5.cpp
  clang/test/CXX/drs/dr18xx.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/test/CXX/special/class.ctor/p5-0x.cpp
  clang/test/Modules/cxx-decls.cpp
  clang/test/SemaCXX/cxx0x-defaulted-functions.cpp
  clang/test/SemaCXX/cxx11-crashes.cpp
  clang/test/SemaCXX/deprecated-builtins.cpp
  clang/test/SemaCXX/sizeless-1.cpp
  clang/test/SemaCXX/trivial-constructor.cpp
  clang/test/SemaCXX/trivial-destructor.cpp
  clang/test/SemaCXX/type-traits.cpp
  clang/test/SemaObjCXX/arc-type-traits.mm
  clang/test/SemaObjCXX/objc-weak-type-traits.mm

Index: clang/test/SemaObjCXX/objc-weak-type-traits.mm
===
--- clang/test/SemaObjCXX/objc-weak-type-traits.mm
+++ clang/test/SemaObjCXX/objc-weak-type-traits.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-builtins
 // expected-no-diagnostics
 
 // Check the results of the various type-trait query functions on
Index: clang/test/SemaObjCXX/arc-type-traits.mm
===
--- clang/test/SemaObjCXX/arc-type-traits.mm
+++ clang/test/SemaObjCXX/arc-type-traits.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-builtins
 // expected-no-diagnostics
 
 // Check the results of the various type-trait query functions on
Index: clang/test/SemaCXX/type-traits.cpp
===
--- clang/test/SemaCXX/type-traits.cpp
+++ clang/test/SemaCXX/type-traits.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fms-extensions -Wno-microsoft %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fms-extensions -Wno-microsoft %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s
 
 #define T(b) (b) ? 1 : -1
 #define F(b) (b) ? -1 : 1
Index: clang/test/SemaCXX/trivial-destructor.cpp
===
--- clang/test/SemaCXX/trivial-destructor.cpp
+++ clang/test/SemaCXX/trivial-destructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-builtins
 // expected-no-diagnostics
 struct T1 {
 };
Index: clang/test/SemaCXX/trivial-constructor.cpp
===
--- clang/test/SemaCXX/trivial-constructor.cpp
+++ clang/test/SemaCXX/trivial-constructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-builtins
 // expected-no-diagnostics
 struct T1 {
 };
Index: clang/test/SemaCXX/sizeless-1.cpp
===
--- clang/test/SemaCXX/sizeless-1.cpp
+++ clang/test/SemaCXX/sizeless-1.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++98 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++11 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++17 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=gnu++17 %s
+// RUN: %clang_cc1 -fcxx

[PATCH] D129170: [Sema] Add deprecation warnings for some compiler provided __has_* type traits

2022-07-11 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaExprCXX.cpp:5400-5401
+SourceLocation KWLoc) {
+  if (!S.getLangOpts().CPlusPlus11)
+return;
+

aaron.ballman wrote:
> royjacobson wrote:
> > aaron.ballman wrote:
> > > erichkeane wrote:
> > > > royjacobson wrote:
> > > > > erichkeane wrote:
> > > > > > royjacobson wrote:
> > > > > > > aaron.ballman wrote:
> > > > > > > > I think we should always warn on these, not just in C++11.
> > > > > > > I'm not convinced we should. My reasoning is that we need a 
> > > > > > > pretty good reason to start issuing warnings for 20 years old 
> > > > > > > code. The usage of those builtins with deleted functions after 
> > > > > > > C++11 is pretty broken which is a pretty good reason, but for 
> > > > > > > earlier language versions they work 'fine' and if people want to 
> > > > > > > use C++03 I prefer leaving them at peace :)
> > > > > > > 
> > > > > > > People on C++03 are also probably using pretty old versions of 
> > > > > > > libstdc++ and/or boost type_traits, so this could have some 
> > > > > > > impact.
> > > > > > > 
> > > > > > > WDYT?
> > > > > > > 
> > > > > > warnings don't get emitted for code in header files, so at least 
> > > > > > that part isn't a concern.  
> > > > > Any header files, or just system headers?
> > > > Sorry, yes, Phab is a mess on a cell phone... in things included as 
> > > > System Headers.
> > > Agreed with Erich -- warnings in system headers (but not regular headers) 
> > > are silenced by default, you need to pass `-Wsystem-headers` to enable 
> > > them.
> > To clarify my position, I think about those builtins as an unofficial part 
> > of the C++03 standard and I think we should support them as long as we 
> > support C++03.
> > 
> > Do you think that's reasonable?
> > 
> > I agree we should update the documentation in this case.
> I still don't see the benefit of undeprecating these in C++03. The 
> replacement interfaces are available for use in C++03 mode, so there's 
> nothing that prevents a user from being pushed to use the supported 
> interfaces instead, right? To me, the older interfaces were not clean/correct 
> and the replacement interfaces are the ones that we want people to use, and 
> that's language mode agnostic.
I think they're 
1. Clean enough under C++03 semantics - without the extra complications of move 
semantics, defaulted/deleted functions etc.
2. Potentially pretty widely used in code that needs C++03, though I have no 
idea how to check that.

But you convinced me that it's probably not that of a big deal to add those 
warnings anyway, so let's add them and think about actual deprecation in a few 
years :)




Comment at: clang/lib/Sema/SemaExprCXX.cpp:5433
+// FIXME: GCC don't implement __is_trivially_destructible: Warning for this
+//   might be too noisy for now.
+// case UTT_HasTrivialDestructor:

aaron.ballman wrote:
> royjacobson wrote:
> > aaron.ballman wrote:
> > > I'd like to know how plausible that "might" is -- Clang flags it as being 
> > > deprecated, so it seems very reasonable to diagnose it as such. These 
> > > diagnostics won't be triggered from system headers by default anyway, so 
> > > I'm not certain if this will be too noisy in practice.
> > It's used in libstdc++'s type_traits and in boost's type_traits (but we 
> > will start warning on boost's type_traits anyway). So it's even if by 
> > default people are not going to see it I think it's used widely enough to 
> > be problematic and we shouldn't warn on this for now.
> > 
> > I added the libstdc++ part to the comment as well.
> My feeling is: if it's deprecated and we don't warn on it, it's not actually 
> deprecated. I'd rather see us warn uniformly on all the deprecated 
> interfaces. System headers are free to keep using these interfaces (system 
> headers are long lived), but any user code using this needs some sort of 
> notification that they're using something we don't want them to use, or we 
> will never be able to get rid of these interfaces (at which point, we should 
> undeprecate them because we need to keep them working).
Ok, added it to the warnings.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129170

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129170: [Sema] Add deprecation warnings for some compiler provided __has_* type traits

2022-07-12 Thread Roy Jacobson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0b89d1d59f82: [Sema] Add deprecation warnings for some 
compiler provided __has_* type traits (authored by royjacobson).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129170

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CXX/dcl.decl/dcl.init/p5.cpp
  clang/test/CXX/drs/dr18xx.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/test/CXX/special/class.ctor/p5-0x.cpp
  clang/test/Modules/cxx-decls.cpp
  clang/test/SemaCXX/cxx0x-defaulted-functions.cpp
  clang/test/SemaCXX/cxx11-crashes.cpp
  clang/test/SemaCXX/deprecated-builtins.cpp
  clang/test/SemaCXX/sizeless-1.cpp
  clang/test/SemaCXX/trivial-constructor.cpp
  clang/test/SemaCXX/trivial-destructor.cpp
  clang/test/SemaCXX/type-traits.cpp
  clang/test/SemaObjCXX/arc-type-traits.mm
  clang/test/SemaObjCXX/objc-weak-type-traits.mm

Index: clang/test/SemaObjCXX/objc-weak-type-traits.mm
===
--- clang/test/SemaObjCXX/objc-weak-type-traits.mm
+++ clang/test/SemaObjCXX/objc-weak-type-traits.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-builtins
 // expected-no-diagnostics
 
 // Check the results of the various type-trait query functions on
Index: clang/test/SemaObjCXX/arc-type-traits.mm
===
--- clang/test/SemaObjCXX/arc-type-traits.mm
+++ clang/test/SemaObjCXX/arc-type-traits.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify -std=c++11 %s -Wno-deprecated-builtins
 // expected-no-diagnostics
 
 // Check the results of the various type-trait query functions on
Index: clang/test/SemaCXX/type-traits.cpp
===
--- clang/test/SemaCXX/type-traits.cpp
+++ clang/test/SemaCXX/type-traits.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fms-extensions -Wno-microsoft %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fms-extensions -Wno-microsoft %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s
 
 #define T(b) (b) ? 1 : -1
 #define F(b) (b) ? -1 : 1
Index: clang/test/SemaCXX/trivial-destructor.cpp
===
--- clang/test/SemaCXX/trivial-destructor.cpp
+++ clang/test/SemaCXX/trivial-destructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-builtins
 // expected-no-diagnostics
 struct T1 {
 };
Index: clang/test/SemaCXX/trivial-constructor.cpp
===
--- clang/test/SemaCXX/trivial-constructor.cpp
+++ clang/test/SemaCXX/trivial-constructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-deprecated-builtins
 // expected-no-diagnostics
 struct T1 {
 };
Index: clang/test/SemaCXX/sizeless-1.cpp
===
--- clang/test/SemaCXX/sizeless-1.cpp
+++ clang/test/SemaCXX/sizeless-1.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++98 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++11 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++17 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall -Wno-un

[PATCH] D129583: [DOC] Add DR1734 and DR1496 Clang's cxx_dr_status as not implemented

2022-07-12 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Those two DRs about the (copy) triviality of types with deleted special member 
functions are not implemented in MSVC.
Document them as such.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129583

Files:
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.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
@@ -8790,7 +8790,7 @@
 https://wg21.link/cwg1496";>1496
 CD4
 Triviality with deleted and missing default constructors
-Unknown
+No
   
   
 https://wg21.link/cwg1497";>1497
@@ -10218,7 +10218,7 @@
 https://wg21.link/cwg1734";>1734
 CD4
 Nontrivial deleted copy functions
-Unknown
+No
   
   
 https://wg21.link/cwg1735";>1735
Index: clang/test/CXX/drs/dr17xx.cpp
===
--- clang/test/CXX/drs/dr17xx.cpp
+++ clang/test/CXX/drs/dr17xx.cpp
@@ -27,6 +27,16 @@
 #endif
 }
 
+namespace dr1734 { // dr1734: no
+#if __cplusplus >= 201103L
+struct A {
+A(const A&) = delete;
+};
+// FIXME: A should not be trivially copyable.
+static_assert(__is_trivially_copyable(A), "");
+#endif
+}
+
 namespace dr1736 { // dr1736: 3.9
 #if __cplusplus >= 201103L
 struct S {
Index: clang/test/CXX/drs/dr14xx.cpp
===
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -501,4 +501,15 @@
   template int c<0, Ts...>; // expected-error {{not more 
specialized}}
 #endif
 }
+
+namespace dr1496 { // dr1496: no
+#if __cplusplus >= 201103L
+struct A {
+A() = delete;
+};
+// FIXME: A should not be trivial.
+static_assert(__is_trivial(A), "");
+#endif
+}
+
 #endif


Index: clang/www/cxx_dr_status.html
===
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -8790,7 +8790,7 @@
 https://wg21.link/cwg1496";>1496
 CD4
 Triviality with deleted and missing default constructors
-Unknown
+No
   
   
 https://wg21.link/cwg1497";>1497
@@ -10218,7 +10218,7 @@
 https://wg21.link/cwg1734";>1734
 CD4
 Nontrivial deleted copy functions
-Unknown
+No
   
   
 https://wg21.link/cwg1735";>1735
Index: clang/test/CXX/drs/dr17xx.cpp
===
--- clang/test/CXX/drs/dr17xx.cpp
+++ clang/test/CXX/drs/dr17xx.cpp
@@ -27,6 +27,16 @@
 #endif
 }
 
+namespace dr1734 { // dr1734: no
+#if __cplusplus >= 201103L
+struct A {
+A(const A&) = delete;
+};
+// FIXME: A should not be trivially copyable.
+static_assert(__is_trivially_copyable(A), "");
+#endif
+}
+
 namespace dr1736 { // dr1736: 3.9
 #if __cplusplus >= 201103L
 struct S {
Index: clang/test/CXX/drs/dr14xx.cpp
===
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -501,4 +501,15 @@
   template int c<0, Ts...>; // expected-error {{not more specialized}}
 #endif
 }
+
+namespace dr1496 { // dr1496: no
+#if __cplusplus >= 201103L
+struct A {
+A() = delete;
+};
+// FIXME: A should not be trivial.
+static_assert(__is_trivial(A), "");
+#endif
+}
+
 #endif
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129583: [DOC] Add DR1734 and DR1496 Clang's cxx_dr_status as not implemented

2022-07-13 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 22.
royjacobson added a comment.

Update comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129583

Files:
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.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
@@ -8790,7 +8790,7 @@
 https://wg21.link/cwg1496";>1496
 CD4
 Triviality with deleted and missing default constructors
-Unknown
+No
   
   
 https://wg21.link/cwg1497";>1497
@@ -10218,7 +10218,7 @@
 https://wg21.link/cwg1734";>1734
 CD4
 Nontrivial deleted copy functions
-Unknown
+No
   
   
 https://wg21.link/cwg1735";>1735
Index: clang/test/CXX/drs/dr17xx.cpp
===
--- clang/test/CXX/drs/dr17xx.cpp
+++ clang/test/CXX/drs/dr17xx.cpp
@@ -27,6 +27,18 @@
 #endif
 }
 
+namespace dr1734 { // dr1734: no
+#if __cplusplus >= 201103L
+struct A {
+A(const A&) = delete;
+};
+// FIXME: 'A' should not be trivially copyable because the class lacks at least
+// one non-deleted copy constructor, move constructor, copy assignment
+// operator, or move assignment operator.
+static_assert(__is_trivially_copyable(A), "");
+#endif
+}
+
 namespace dr1736 { // dr1736: 3.9
 #if __cplusplus >= 201103L
 struct S {
Index: clang/test/CXX/drs/dr14xx.cpp
===
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -501,4 +501,16 @@
   template int c<0, Ts...>; // expected-error {{not more 
specialized}}
 #endif
 }
+
+namespace dr1496 { // dr1496: no
+#if __cplusplus >= 201103L
+struct A {
+A() = delete;
+};
+// FIXME: 'A' should not be trivial because the class lacks at least one
+// default constructor which is not deleted.
+static_assert(__is_trivial(A), "");
+#endif
+}
+
 #endif


Index: clang/www/cxx_dr_status.html
===
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -8790,7 +8790,7 @@
 https://wg21.link/cwg1496";>1496
 CD4
 Triviality with deleted and missing default constructors
-Unknown
+No
   
   
 https://wg21.link/cwg1497";>1497
@@ -10218,7 +10218,7 @@
 https://wg21.link/cwg1734";>1734
 CD4
 Nontrivial deleted copy functions
-Unknown
+No
   
   
 https://wg21.link/cwg1735";>1735
Index: clang/test/CXX/drs/dr17xx.cpp
===
--- clang/test/CXX/drs/dr17xx.cpp
+++ clang/test/CXX/drs/dr17xx.cpp
@@ -27,6 +27,18 @@
 #endif
 }
 
+namespace dr1734 { // dr1734: no
+#if __cplusplus >= 201103L
+struct A {
+A(const A&) = delete;
+};
+// FIXME: 'A' should not be trivially copyable because the class lacks at least
+// one non-deleted copy constructor, move constructor, copy assignment
+// operator, or move assignment operator.
+static_assert(__is_trivially_copyable(A), "");
+#endif
+}
+
 namespace dr1736 { // dr1736: 3.9
 #if __cplusplus >= 201103L
 struct S {
Index: clang/test/CXX/drs/dr14xx.cpp
===
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -501,4 +501,16 @@
   template int c<0, Ts...>; // expected-error {{not more specialized}}
 #endif
 }
+
+namespace dr1496 { // dr1496: no
+#if __cplusplus >= 201103L
+struct A {
+A() = delete;
+};
+// FIXME: 'A' should not be trivial because the class lacks at least one
+// default constructor which is not deleted.
+static_assert(__is_trivial(A), "");
+#endif
+}
+
 #endif
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129583: [DOC] Add DR1734 and DR1496 Clang's cxx_dr_status as not implemented

2022-07-13 Thread Roy Jacobson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG202b327f5d29: [DOC] Add DR1734 and DR1496 Clang's 
cxx_dr_status as not implemented (authored by royjacobson).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129583

Files:
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/CXX/drs/dr17xx.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
@@ -8790,7 +8790,7 @@
 https://wg21.link/cwg1496";>1496
 CD4
 Triviality with deleted and missing default constructors
-Unknown
+No
   
   
 https://wg21.link/cwg1497";>1497
@@ -10218,7 +10218,7 @@
 https://wg21.link/cwg1734";>1734
 CD4
 Nontrivial deleted copy functions
-Unknown
+No
   
   
 https://wg21.link/cwg1735";>1735
Index: clang/test/CXX/drs/dr17xx.cpp
===
--- clang/test/CXX/drs/dr17xx.cpp
+++ clang/test/CXX/drs/dr17xx.cpp
@@ -27,6 +27,18 @@
 #endif
 }
 
+namespace dr1734 { // dr1734: no
+#if __cplusplus >= 201103L
+struct A {
+A(const A&) = delete;
+};
+// FIXME: 'A' should not be trivially copyable because the class lacks at least
+// one non-deleted copy constructor, move constructor, copy assignment
+// operator, or move assignment operator.
+static_assert(__is_trivially_copyable(A), "");
+#endif
+}
+
 namespace dr1736 { // dr1736: 3.9
 #if __cplusplus >= 201103L
 struct S {
Index: clang/test/CXX/drs/dr14xx.cpp
===
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -501,4 +501,16 @@
   template int c<0, Ts...>; // expected-error {{not more 
specialized}}
 #endif
 }
+
+namespace dr1496 { // dr1496: no
+#if __cplusplus >= 201103L
+struct A {
+A() = delete;
+};
+// FIXME: 'A' should not be trivial because the class lacks at least one
+// default constructor which is not deleted.
+static_assert(__is_trivial(A), "");
+#endif
+}
+
 #endif


Index: clang/www/cxx_dr_status.html
===
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -8790,7 +8790,7 @@
 https://wg21.link/cwg1496";>1496
 CD4
 Triviality with deleted and missing default constructors
-Unknown
+No
   
   
 https://wg21.link/cwg1497";>1497
@@ -10218,7 +10218,7 @@
 https://wg21.link/cwg1734";>1734
 CD4
 Nontrivial deleted copy functions
-Unknown
+No
   
   
 https://wg21.link/cwg1735";>1735
Index: clang/test/CXX/drs/dr17xx.cpp
===
--- clang/test/CXX/drs/dr17xx.cpp
+++ clang/test/CXX/drs/dr17xx.cpp
@@ -27,6 +27,18 @@
 #endif
 }
 
+namespace dr1734 { // dr1734: no
+#if __cplusplus >= 201103L
+struct A {
+A(const A&) = delete;
+};
+// FIXME: 'A' should not be trivially copyable because the class lacks at least
+// one non-deleted copy constructor, move constructor, copy assignment
+// operator, or move assignment operator.
+static_assert(__is_trivially_copyable(A), "");
+#endif
+}
+
 namespace dr1736 { // dr1736: 3.9
 #if __cplusplus >= 201103L
 struct S {
Index: clang/test/CXX/drs/dr14xx.cpp
===
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -501,4 +501,16 @@
   template int c<0, Ts...>; // expected-error {{not more specialized}}
 #endif
 }
+
+namespace dr1496 { // dr1496: no
+#if __cplusplus >= 201103L
+struct A {
+A() = delete;
+};
+// FIXME: 'A' should not be trivial because the class lacks at least one
+// default constructor which is not deleted.
+static_assert(__is_trivial(A), "");
+#endif
+}
+
 #endif
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129583: [DOC] Add DR1734 and DR1496 Clang's cxx_dr_status as not implemented

2022-07-13 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

Thanks for the suggestions and for the quick review! @aaron.ballman


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129583

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D129170: [Sema] Add deprecation warnings for some compiler provided __has_* type traits

2022-07-13 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D129170#3650618 , @glandium wrote:

> From the commit message:
>
>> This patch adds deprecation warnings for the usage of those builtins, except 
>> for __has_trivial_destructor which doesn't have a GCC alternative.
>
> The exception for __has_trivial_destructor doesn't seem to be true, FWIW.

Oh, I'm really sorry for that :/ It was changed because Aaron asked me to add 
it as well, but I forgot to update the summary.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129170

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-14 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson updated this revision to Diff 444173.
royjacobson added a comment.
royjacobson updated this revision to Diff 19.
royjacobson retitled this revision from "[WIP][Clang] Implement P0848 
(Conditionally Trivial Special Member Functions)" to "[Clang] Implement P0848 
(Conditionally Trivial Special Member Functions)".
royjacobson edited the summary of this revision.
royjacobson added reviewers: clang-language-wg, erichkeane, cor3ntin, BRevzin, 
CaseyCarter, aaron.ballman.
royjacobson published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The implementation is more or less complete, but I still need to add an AST 
test for canPassInRegisters.


royjacobson added a comment.

Implementation ready for CR.




Comment at: clang/www/cxx_status.html:930
 https://wg21.link/p0848r3";>P0848R3
-No
+Clang 15
   

Should be `class="unreleased"`, I believe



Comment at: clang/www/cxx_status.html:930
 https://wg21.link/p0848r3";>P0848R3
-No
+Clang 15
   

h-vetinari wrote:
> Should be `class="unreleased"`, I believe
Thanks, nice catch!


This patch implements P0848 in Clang.

During the instantiation of a C++ class, in `Sema::ActOnFields`, we evaluate 
constraints for all the SMFs and compare the constraints to compute the 
eligibility. We defer the computation of the type's [copy-]trivial bits from 
addedMember to the eligibility computation, like we did for destructors in 
D126194 . `canPassInRegisters` is modified as 
well to better respect the ineligibility of functions.

Note: Because of the non-implementation of DR1734 and DR1496, I treat deleted 
member functions as 'eligible' for the purpose of [copy-]triviallity. This is 
unfortunate, but I couldn't think of a way to make this make sense otherwise.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128619

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/AST/DeclCXX.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/conditionally-trivial-smfs.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constrained-special-member-functions.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -927,7 +927,7 @@
   

 https://wg21.link/p0848r3";>P0848R3
-No
+Clang 15
   
   
 https://wg21.link/p1616r1";>P1616R1
Index: clang/test/SemaCXX/constrained-special-member-functions.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constrained-special-member-functions.cpp
@@ -0,0 +1,130 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s
+// expected-no-diagnostics
+
+template 
+concept C0 = (N == 0);
+template 
+concept C1 = (N == 1);
+template 
+concept C2 = (N == 2);
+
+// Checks are indexed by:
+// Definition:
+//  1. Explicitly defaulted definition
+//  2. Deleted definition
+//  3. User provided definition
+// We have a less constrained user provided method that should not disable
+// the (copyable) triviality of the type.
+
+// Note that because Clang does not implement DRs 1496 and 1734, we say some
+// classes are trivial when the SMFs are deleted.
+
+template 
+struct DefaultConstructorChecker {
+DefaultConstructorChecker() requires C0 = default;
+DefaultConstructorChecker() requires C1 = delete;
+DefaultConstructorChecker() requires C2;
+DefaultConstructorChecker();
+};
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
+static_assert(__is_trivial(DefaultConstructorChecker<0>));
+// FIXME: DR1496
+static_assert(__is_trivial(DefaultConstructorChecker<1>));
+static_assert(!__is_trivial(DefaultConstructorChecker<2>));
+static_assert(!__is_trivial(DefaultConstructorChecker<3>));
+
+template 
+struct CopyConstructorChecker {
+CopyConstructorChecker(const CopyConstructorChecker&) requires C0 = default;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C1 = delete;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C2;
+CopyConstructorChecker(const CopyConstructorChecker&);
+};
+
+static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
+static_assert(!__is_trivially_

[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 445044.
royjacobson edited the summary of this revision.
royjacobson added a comment.

Address Corentin's feedback.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/AST/DeclCXX.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/conditionally-trivial-smfs.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constrained-special-member-functions.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -927,7 +927,7 @@
   

 https://wg21.link/p0848r3";>P0848R3
-No
+Clang 15
   
   
 https://wg21.link/p1616r1";>P1616R1
Index: clang/test/SemaCXX/constrained-special-member-functions.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constrained-special-member-functions.cpp
@@ -0,0 +1,130 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s
+// expected-no-diagnostics
+
+template 
+concept C0 = (N == 0);
+template 
+concept C1 = (N == 1);
+template 
+concept C2 = (N == 2);
+
+// Checks are indexed by:
+// Definition:
+//  1. Explicitly defaulted definition
+//  2. Deleted definition
+//  3. User provided definition
+// We have a less constrained user provided method that should not disable
+// the (copyable) triviality of the type.
+
+// Note that because Clang does not implement DRs 1496 and 1734, we say some
+// classes are trivial when the SMFs are deleted.
+
+template 
+struct DefaultConstructorChecker {
+DefaultConstructorChecker() requires C0 = default;
+DefaultConstructorChecker() requires C1 = delete;
+DefaultConstructorChecker() requires C2;
+DefaultConstructorChecker();
+};
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
+static_assert(__is_trivial(DefaultConstructorChecker<0>));
+// FIXME: DR1496
+static_assert(__is_trivial(DefaultConstructorChecker<1>));
+static_assert(!__is_trivial(DefaultConstructorChecker<2>));
+static_assert(!__is_trivial(DefaultConstructorChecker<3>));
+
+template 
+struct CopyConstructorChecker {
+CopyConstructorChecker(const CopyConstructorChecker&) requires C0 = default;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C1 = delete;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C2;
+CopyConstructorChecker(const CopyConstructorChecker&);
+};
+
+static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));
+static_assert(!__is_trivial(CopyConstructorChecker<0>));
+static_assert(!__is_trivial(CopyConstructorChecker<1>));
+static_assert(!__is_trivial(CopyConstructorChecker<2>));
+static_assert(!__is_trivial(CopyConstructorChecker<3>));
+
+template 
+struct MoveConstructorChecker {
+MoveConstructorChecker(MoveConstructorChecker&&) requires C0 = default;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C1 = delete;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C2;
+MoveConstructorChecker(MoveConstructorChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));
+static_assert(!__is_trivial(MoveConstructorChecker<0>));
+static_assert(!__is_trivial(MoveConstructorChecker<1>));
+static_assert(!__is_trivial(MoveConstructorChecker<2>));
+static_assert(!__is_trivial(MoveConstructorChecker<3>));
+
+template 
+struct MoveAssignmentChecker {
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0 = default;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1 = delete;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));
+// FIXME: DR1734.
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>));
+static

[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson marked 4 inline comments as done and an inline comment as not done.
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:17960-17961
+}
+if (AnotherMethodIsMoreConstrained)
+  break;
+  }

cor3ntin wrote:
> Is that codepath ever taken?
> I wonder if there is a way to do that that is not n^2. Maybe not.
It's not, I didn't mean to leave it there. Thanks for the catch :)


Generally finding a maximal set in a partial ordering is O(n^2) in the worst 
case which is when no two objects are comparable.

We could optimize this a bit for some cases: We can group the functions by 
their kind, and we can skip comparing functions if we already know that they 
are not maximal. But since the number of SMFs expected in a class is very (1-3) 
small, I didn't think those possible improvements are worth the extra 
complexity.

Another possible optimization is we could short-circuit this evaluation if we 
know that a type is not trivially [copyable], since that's the only outcome we 
really care about, but then the AST is left in a very awkward state.




Comment at: clang/test/AST/conditionally-trivial-smfs.cpp:39
+
+template struct DefaultConstructorCheck<2>;
+// CHECK: "kind": "ClassTemplateSpecializationDecl",

BRevzin wrote:
> It's possible that I just don't understand what these tests actually mean 
> but... where is the test for `DefaultConstructorCheck<2>` having a deleted 
> default constructor, or `DefaultConstructorCheck<3>` having a non-defaulted 
> one?
> 
> It'd also be worthwhile to have at least one test with constaints that 
> subsume each other instead of being mutually exclusive. 
Should I check this? Except destructors, the other SMFs are found during 
overload resolution using the usual lookup that already takes into account 
delete/default/constraints etc.

This patch is about making sure that we set the triviality attributes correctly 
according to the eligible functions, so this is what I added tests for.

Most of this testing is done in the sema test, but I need this AST test as well 
to make sure we get the `canPassInRegisters` attribute correctly - we're doing 
some custom processing over the functions without the usual type attributes 
because there are some weird compatibility edge cases.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson marked an inline comment as done.
royjacobson added inline comments.



Comment at: clang/test/AST/conditionally-trivial-smfs.cpp:39
+
+template struct DefaultConstructorCheck<2>;
+// CHECK: "kind": "ClassTemplateSpecializationDecl",

BRevzin wrote:
> royjacobson wrote:
> > BRevzin wrote:
> > > It's possible that I just don't understand what these tests actually mean 
> > > but... where is the test for `DefaultConstructorCheck<2>` having a 
> > > deleted default constructor, or `DefaultConstructorCheck<3>` having a 
> > > non-defaulted one?
> > > 
> > > It'd also be worthwhile to have at least one test with constaints that 
> > > subsume each other instead of being mutually exclusive. 
> > Should I check this? Except destructors, the other SMFs are found during 
> > overload resolution using the usual lookup that already takes into account 
> > delete/default/constraints etc.
> > 
> > This patch is about making sure that we set the triviality attributes 
> > correctly according to the eligible functions, so this is what I added 
> > tests for.
> > 
> > Most of this testing is done in the sema test, but I need this AST test as 
> > well to make sure we get the `canPassInRegisters` attribute correctly - 
> > we're doing some custom processing over the functions without the usual 
> > type attributes because there are some weird compatibility edge cases.
> > 
> One of the motivations for the paper is to ensure that like given:
> 
> ```
> template 
> struct optional {
> optional(optional const&) requires copyable && trivially_copyableT> = 
> default;
> optional(optional const&) requires copyable;
> };
> ```
> 
> `optional` is copyable (but not trivially copyable), `optional` 
> is trivially copyable, and `optional>` isn't copyable. I'm 
> not sure what in here checks if that works. 
That's more-or-less the check in `constrained-special-member-functions.cpp:50`, 
I think.

Didn't acknowledge it in my first response - but yeah, I need some more 
complicated subsumption test cases



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-17 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 445350.
royjacobson marked an inline comment as not done.
royjacobson added a comment.

Add a test case with more subsumption


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/AST/DeclCXX.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/conditionally-trivial-smfs.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constrained-special-member-functions.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -927,7 +927,7 @@
   

 https://wg21.link/p0848r3";>P0848R3
-No
+Clang 15
   
   
 https://wg21.link/p1616r1";>P1616R1
Index: clang/test/SemaCXX/constrained-special-member-functions.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constrained-special-member-functions.cpp
@@ -0,0 +1,186 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s
+// expected-no-diagnostics
+
+template 
+concept C0 = (N == 0);
+template 
+concept C1 = (N == 1);
+template 
+concept C2 = (N == 2);
+
+// Checks are indexed by:
+// Definition:
+//  1. Explicitly defaulted definition
+//  2. Deleted definition
+//  3. User provided definition
+// We have a less constrained user provided method that should not disable
+// the (copyable) triviality of the type.
+
+// Note that because Clang does not implement DRs 1496 and 1734, we say some
+// classes are trivial when the SMFs are deleted.
+
+template 
+struct DefaultConstructorChecker {
+DefaultConstructorChecker() requires C0 = default;
+DefaultConstructorChecker() requires C1 = delete;
+DefaultConstructorChecker() requires C2;
+DefaultConstructorChecker();
+};
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
+static_assert(__is_trivial(DefaultConstructorChecker<0>));
+// FIXME: DR1496
+static_assert(__is_trivial(DefaultConstructorChecker<1>));
+static_assert(!__is_trivial(DefaultConstructorChecker<2>));
+static_assert(!__is_trivial(DefaultConstructorChecker<3>));
+
+template 
+struct CopyConstructorChecker {
+CopyConstructorChecker(const CopyConstructorChecker&) requires C0 = default;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C1 = delete;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C2;
+CopyConstructorChecker(const CopyConstructorChecker&);
+};
+
+static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));
+static_assert(!__is_trivial(CopyConstructorChecker<0>));
+static_assert(!__is_trivial(CopyConstructorChecker<1>));
+static_assert(!__is_trivial(CopyConstructorChecker<2>));
+static_assert(!__is_trivial(CopyConstructorChecker<3>));
+
+template 
+struct MoveConstructorChecker {
+MoveConstructorChecker(MoveConstructorChecker&&) requires C0 = default;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C1 = delete;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C2;
+MoveConstructorChecker(MoveConstructorChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));
+static_assert(!__is_trivial(MoveConstructorChecker<0>));
+static_assert(!__is_trivial(MoveConstructorChecker<1>));
+static_assert(!__is_trivial(MoveConstructorChecker<2>));
+static_assert(!__is_trivial(MoveConstructorChecker<3>));
+
+template 
+struct MoveAssignmentChecker {
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0 = default;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1 = delete;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));
+// FIXME: DR1734.
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>)

[PATCH] D128750: [c++20] Implement P2113R0: Changes to the Partial Ordering of Constrained Functions

2022-07-19 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D128750#3661576 , @ychen wrote:

> ...
> There is *no* way to reorder the template parameters list again (to get two 
> or more reordering) and the resulted template still works, because of the 
> *positionally correspond* requirement. If this reasoning is sound, I think 
> the current approach of deducing order to compare constraints for rewritten 
> candidates is correct. I wouldn't say I'm 100% confident. But it still makes 
> sense to me at this moment.

I'm not sure I follow your reasoning here. I agree we can't reorder the 
function parameters, but in your example with T/U/V we have 3 template 
parameters that we could reorder in 6 different ways. According to how I read 
6.2.1.2 we'd need to check there's only one way to order them equivalently, 
which (I think) reduces to every template parameter appears only once.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128750

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-20 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:17870
+///   parameter type and the same cv-qualifiers and ref-qualifier, if any.
+bool AreSpecialMemberFunctionsSameKind(CXXMethodDecl *M1, CXXMethodDecl *M2,
+ Sema::CXXSpecialMember CSM) {

cor3ntin wrote:
> 
It's in an anonymous namespace. Is it a Clang convention to use static 
functions instead? I saw both used in Sema, I think



Comment at: clang/lib/Sema/SemaDecl.cpp:17874
+  return true;
+if (M1->getParamDecl(0)->getType() != M2->getParamDecl(0)->getType())
+  return false;

erichkeane wrote:
> I don't think you'd want to compare with equality here, it ends up not 
> desugaring/etc.  I believe `ASTContext::HasSameType` should be what you want. 
>  
Good catch! added a test for this.



Comment at: clang/lib/Sema/SemaDecl.cpp:17899
+  ConstraintSatisfaction Satisfaction;
+  if (S.CheckFunctionConstraints(Method, Satisfaction))
+SatisfactionStatus.push_back(false);

erichkeane wrote:
> This seems problematic, doesn't it?  Checking this constraint will (once I 
> figure out how to get deferred instantiation to work) cause instantiation, 
> which can cause issues with incomplete types/CRTP/etc.
> 
> I think the result is that we cannot 'calculate' this until it is queried, 
> else we will cause incorrect errors.
Making this queried on demand is a relatively big change to how we handle type 
triviality, so I want to be sure we actually need to do this to be conformant.

When I started working on this I checked what GCC does and it instantiates 
those constraints during class completion as well. For example this CRTP case: 
https://godbolt.org/z/EdoYf96zq. MSVC seem to do it as well.

So maybe it's OK to check the constraints of SMFs specifically?




Comment at: clang/lib/Sema/SemaDecl.cpp:17960-17961
+}
+if (AnotherMethodIsMoreConstrained)
+  break;
+  }

cor3ntin wrote:
> royjacobson wrote:
> > cor3ntin wrote:
> > > Is that codepath ever taken?
> > > I wonder if there is a way to do that that is not n^2. Maybe not.
> > It's not, I didn't mean to leave it there. Thanks for the catch :)
> > 
> > 
> > Generally finding a maximal set in a partial ordering is O(n^2) in the 
> > worst case which is when no two objects are comparable.
> > 
> > We could optimize this a bit for some cases: We can group the functions by 
> > their kind, and we can skip comparing functions if we already know that 
> > they are not maximal. But since the number of SMFs expected in a class is 
> > very (1-3) small, I didn't think those possible improvements are worth the 
> > extra complexity.
> > 
> > Another possible optimization is we could short-circuit this evaluation if 
> > we know that a type is not trivially [copyable], since that's the only 
> > outcome we really care about, but then the AST is left in a very awkward 
> > state.
> > 
> Thanks, I guess this is fine, I cannot really think of a better way either
Ok, did another look on this and it's because `AnotherMethodIsMoreConstrained` 
is the output of `IsAtLeastAsConstrained`, so that's why the extra check. Added 
it back :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-20 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 446172.
royjacobson added a comment.

Fixed the tests, fixed the type comparison checks.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/AST/DeclCXX.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/conditionally-trivial-smfs.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constrained-special-member-functions.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -927,7 +927,7 @@
   

 https://wg21.link/p0848r3";>P0848R3
-No
+Clang 15
   
   
 https://wg21.link/p1616r1";>P1616R1
Index: clang/test/SemaCXX/constrained-special-member-functions.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constrained-special-member-functions.cpp
@@ -0,0 +1,195 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s
+// expected-no-diagnostics
+
+template 
+concept C0 = (N == 0);
+template 
+concept C1 = (N == 1);
+template 
+concept C2 = (N == 2);
+
+// Checks are indexed by:
+// Definition:
+//  1. Explicitly defaulted definition
+//  2. Deleted definition
+//  3. User provided definition
+// We have a less constrained user provided method that should not disable
+// the (copyable) triviality of the type.
+
+// Note that because Clang does not implement DRs 1496 and 1734, we say some
+// classes are trivial when the SMFs are deleted.
+
+template 
+struct DefaultConstructorChecker {
+DefaultConstructorChecker() requires C0 = default;
+DefaultConstructorChecker() requires C1 = delete;
+DefaultConstructorChecker() requires C2;
+DefaultConstructorChecker();
+};
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
+static_assert(__is_trivial(DefaultConstructorChecker<0>));
+// FIXME: DR1496
+static_assert(__is_trivial(DefaultConstructorChecker<1>));
+static_assert(!__is_trivial(DefaultConstructorChecker<2>));
+static_assert(!__is_trivial(DefaultConstructorChecker<3>));
+
+template 
+struct CopyConstructorChecker {
+CopyConstructorChecker(const CopyConstructorChecker&) requires C0 = default;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C1 = delete;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C2;
+CopyConstructorChecker(const CopyConstructorChecker&);
+};
+
+static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));
+static_assert(!__is_trivial(CopyConstructorChecker<0>));
+static_assert(!__is_trivial(CopyConstructorChecker<1>));
+static_assert(!__is_trivial(CopyConstructorChecker<2>));
+static_assert(!__is_trivial(CopyConstructorChecker<3>));
+
+template 
+struct MoveConstructorChecker {
+MoveConstructorChecker(MoveConstructorChecker&&) requires C0 = default;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C1 = delete;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C2;
+MoveConstructorChecker(MoveConstructorChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));
+static_assert(!__is_trivial(MoveConstructorChecker<0>));
+static_assert(!__is_trivial(MoveConstructorChecker<1>));
+static_assert(!__is_trivial(MoveConstructorChecker<2>));
+static_assert(!__is_trivial(MoveConstructorChecker<3>));
+
+template 
+struct MoveAssignmentChecker {
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0 = default;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1 = delete;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));
+// FIXME: DR1734.
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>));
+static_assert(__is_trivial(MoveAs

[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-20 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:17899
+  ConstraintSatisfaction Satisfaction;
+  if (S.CheckFunctionConstraints(Method, Satisfaction))
+SatisfactionStatus.push_back(false);

erichkeane wrote:
> cor3ntin wrote:
> > erichkeane wrote:
> > > cor3ntin wrote:
> > > > royjacobson wrote:
> > > > > erichkeane wrote:
> > > > > > This seems problematic, doesn't it?  Checking this constraint will 
> > > > > > (once I figure out how to get deferred instantiation to work) cause 
> > > > > > instantiation, which can cause issues with incomplete 
> > > > > > types/CRTP/etc.
> > > > > > 
> > > > > > I think the result is that we cannot 'calculate' this until it is 
> > > > > > queried, else we will cause incorrect errors.
> > > > > Making this queried on demand is a relatively big change to how we 
> > > > > handle type triviality, so I want to be sure we actually need to do 
> > > > > this to be conformant.
> > > > > 
> > > > > When I started working on this I checked what GCC does and it 
> > > > > instantiates those constraints during class completion as well. For 
> > > > > example this CRTP case: https://godbolt.org/z/EdoYf96zq. MSVC seem to 
> > > > > do it as well.
> > > > > 
> > > > > So maybe it's OK to check the constraints of SMFs specifically?
> > > > > 
> > > > I think this is done on completeness already in this patch, unless i 
> > > > misunderstood the code.
> > > > I don't think doing it on demand is a great direction, as this does not 
> > > > only affect type traits but also code gen, etc. It would create 
> > > > instanciations in unexpected places. wouldn't it.
> > > > Does the standard has wording suggesting it should be done later than 
> > > > on type completeness?
> > > The problem, at least for the deferred concepts, is that it breaks in the 
> > > CRTP as required to implement ranges.  So something like this: 
> > > https://godbolt.org/z/hPqrcqhx5 breaks.
> > > 
> > > I'm currently working to 'fix' that, so if this patch causes us to 
> > > 'check' constraints early, it'll go back to breaking that example.  The 
> > > example that Roy showed seems to show that it is actually checking 
> > > 'delayed' right now (that is, on demand) in GCC/MSVC.  I don't know of 
> > > the consequence/standardeeze that causes that though.
> > Thanks, 
> > Follow up stupid question then, do we care about the triviality of 
> > dependant types?
> > I think doing the check on complete non-dependant types might be a better 
> > solution than trying to do it lazily on triviality checks?
> I would think it would be not a problem on non-dependent types.  BUT concepts 
> are only allowed on templated functions (note not only on 
> function-templates!) anyway, so I don't think this would be a problem?  
Erich, I'm a bit confused by your response. I think my example demonstrates 
that for default constructors (and other SMFs) GCC and MSVC instantiate the 
constraints on class completion and **not** on demand. This is what I would 
like to do as well, if we don't have a good reason not to. (For destructors, 
performing the checks is even explicit in the standard.)

Not doing this can introduce some REALLY bad edge cases. What does this do if 
we defer the triviality computation?

```c++

template 
struct Base {
  Base() = default;
  Base() requires (!std::is_trivial_v);
};

struct Child : Base { };
```
We defer the computation of the constraints on `Base`, and complete `Child` 
somehow, but if `Child` is complete then `std::is_trivial_v` should be 
well-formed, right? But we get a logical contradiction instead.




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-20 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:17899
+  ConstraintSatisfaction Satisfaction;
+  if (S.CheckFunctionConstraints(Method, Satisfaction))
+SatisfactionStatus.push_back(false);

erichkeane wrote:
> royjacobson wrote:
> > erichkeane wrote:
> > > cor3ntin wrote:
> > > > erichkeane wrote:
> > > > > cor3ntin wrote:
> > > > > > royjacobson wrote:
> > > > > > > erichkeane wrote:
> > > > > > > > This seems problematic, doesn't it?  Checking this constraint 
> > > > > > > > will (once I figure out how to get deferred instantiation to 
> > > > > > > > work) cause instantiation, which can cause issues with 
> > > > > > > > incomplete types/CRTP/etc.
> > > > > > > > 
> > > > > > > > I think the result is that we cannot 'calculate' this until it 
> > > > > > > > is queried, else we will cause incorrect errors.
> > > > > > > Making this queried on demand is a relatively big change to how 
> > > > > > > we handle type triviality, so I want to be sure we actually need 
> > > > > > > to do this to be conformant.
> > > > > > > 
> > > > > > > When I started working on this I checked what GCC does and it 
> > > > > > > instantiates those constraints during class completion as well. 
> > > > > > > For example this CRTP case: https://godbolt.org/z/EdoYf96zq. MSVC 
> > > > > > > seem to do it as well.
> > > > > > > 
> > > > > > > So maybe it's OK to check the constraints of SMFs specifically?
> > > > > > > 
> > > > > > I think this is done on completeness already in this patch, unless 
> > > > > > i misunderstood the code.
> > > > > > I don't think doing it on demand is a great direction, as this does 
> > > > > > not only affect type traits but also code gen, etc. It would create 
> > > > > > instanciations in unexpected places. wouldn't it.
> > > > > > Does the standard has wording suggesting it should be done later 
> > > > > > than on type completeness?
> > > > > The problem, at least for the deferred concepts, is that it breaks in 
> > > > > the CRTP as required to implement ranges.  So something like this: 
> > > > > https://godbolt.org/z/hPqrcqhx5 breaks.
> > > > > 
> > > > > I'm currently working to 'fix' that, so if this patch causes us to 
> > > > > 'check' constraints early, it'll go back to breaking that example.  
> > > > > The example that Roy showed seems to show that it is actually 
> > > > > checking 'delayed' right now (that is, on demand) in GCC/MSVC.  I 
> > > > > don't know of the consequence/standardeeze that causes that though.
> > > > Thanks, 
> > > > Follow up stupid question then, do we care about the triviality of 
> > > > dependant types?
> > > > I think doing the check on complete non-dependant types might be a 
> > > > better solution than trying to do it lazily on triviality checks?
> > > I would think it would be not a problem on non-dependent types.  BUT 
> > > concepts are only allowed on templated functions (note not only on 
> > > function-templates!) anyway, so I don't think this would be a problem?  
> > Erich, I'm a bit confused by your response. I think my example demonstrates 
> > that for default constructors (and other SMFs) GCC and MSVC instantiate the 
> > constraints on class completion and **not** on demand. This is what I would 
> > like to do as well, if we don't have a good reason not to. (For 
> > destructors, performing the checks is even explicit in the standard.)
> > 
> > Not doing this can introduce some REALLY bad edge cases. What does this do 
> > if we defer the triviality computation?
> > 
> > ```c++
> > 
> > template 
> > struct Base {
> >   Base() = default;
> >   Base() requires (!std::is_trivial_v);
> > };
> > 
> > struct Child : Base { };
> > ```
> > We defer the computation of the constraints on `Base`, and complete `Child` 
> > somehow, but if `Child` is complete then `std::is_trivial_v` should 
> > be well-formed, right? But we get a logical contradiction instead.
> > 
> > 
> >Erich, I'm a bit confused by your response
> It is entirely possible we're talking past eachother, or misunderstanding 
> eachothers examples.  I'm totally open to that being part of this issue.
> 
> In that example, if we calculate the triviality at '`Base` Class completion', 
> `Child` is not yet complete, right?  So the is_trivial_v would be UB.  If you 
> instead require `sizeof(T)`, we typically give a diagnostic.
> 
> In this case, you'd at MINIMUM have to wait to calculate the requires-clause 
> until after `Child` is complete.  And it isn't clear to me that we're 
> delaying it until then.
> 
> That is what I intend to show with: https://godbolt.org/z/1YjsdY73P
> 
> As far as doing it 'on demand', I definitely see your circular argument here, 
> but I think the is_trivial_v test is UB if we calculate it at `Base' 
> completion.
I'm arguing for checking the constraints at the completion of `Base`, and for 
making `is_trivial_v/sizeof` ill formed in this context.

Your GCC example is a bit misle

[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-20 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 446264.
royjacobson added a comment.

Add a test for the CRTP constraints timings


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/AST/DeclCXX.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/conditionally-trivial-smfs.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constrained-special-member-functions.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -927,7 +927,7 @@
   

 https://wg21.link/p0848r3";>P0848R3
-No
+Clang 15
   
   
 https://wg21.link/p1616r1";>P1616R1
Index: clang/test/SemaCXX/constrained-special-member-functions.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constrained-special-member-functions.cpp
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s
+
+template 
+concept C0 = (N == 0);
+template 
+concept C1 = (N == 1);
+template 
+concept C2 = (N == 2);
+
+// Checks are indexed by:
+// Definition:
+//  1. Explicitly defaulted definition
+//  2. Deleted definition
+//  3. User provided definition
+// We have a less constrained user provided method that should not disable
+// the (copyable) triviality of the type.
+
+// Note that because Clang does not implement DRs 1496 and 1734, we say some
+// classes are trivial when the SMFs are deleted.
+
+template 
+struct DefaultConstructorChecker {
+DefaultConstructorChecker() requires C0 = default;
+DefaultConstructorChecker() requires C1 = delete;
+DefaultConstructorChecker() requires C2;
+DefaultConstructorChecker();
+};
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
+static_assert(__is_trivial(DefaultConstructorChecker<0>));
+// FIXME: DR1496
+static_assert(__is_trivial(DefaultConstructorChecker<1>));
+static_assert(!__is_trivial(DefaultConstructorChecker<2>));
+static_assert(!__is_trivial(DefaultConstructorChecker<3>));
+
+template 
+struct CopyConstructorChecker {
+CopyConstructorChecker(const CopyConstructorChecker&) requires C0 = default;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C1 = delete;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C2;
+CopyConstructorChecker(const CopyConstructorChecker&);
+};
+
+static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));
+static_assert(!__is_trivial(CopyConstructorChecker<0>));
+static_assert(!__is_trivial(CopyConstructorChecker<1>));
+static_assert(!__is_trivial(CopyConstructorChecker<2>));
+static_assert(!__is_trivial(CopyConstructorChecker<3>));
+
+template 
+struct MoveConstructorChecker {
+MoveConstructorChecker(MoveConstructorChecker&&) requires C0 = default;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C1 = delete;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C2;
+MoveConstructorChecker(MoveConstructorChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));
+static_assert(!__is_trivial(MoveConstructorChecker<0>));
+static_assert(!__is_trivial(MoveConstructorChecker<1>));
+static_assert(!__is_trivial(MoveConstructorChecker<2>));
+static_assert(!__is_trivial(MoveConstructorChecker<3>));
+
+template 
+struct MoveAssignmentChecker {
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0 = default;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1 = delete;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));
+// FIXME: DR1734.
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>));
+static_assert(__is_trivial(MoveAssignmentChecker<0>));
+// FIXME: DR

[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-20 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:17899
+  ConstraintSatisfaction Satisfaction;
+  if (S.CheckFunctionConstraints(Method, Satisfaction))
+SatisfactionStatus.push_back(false);

cor3ntin wrote:
> erichkeane wrote:
> > royjacobson wrote:
> > > erichkeane wrote:
> > > > royjacobson wrote:
> > > > > erichkeane wrote:
> > > > > > cor3ntin wrote:
> > > > > > > erichkeane wrote:
> > > > > > > > cor3ntin wrote:
> > > > > > > > > royjacobson wrote:
> > > > > > > > > > erichkeane wrote:
> > > > > > > > > > > This seems problematic, doesn't it?  Checking this 
> > > > > > > > > > > constraint will (once I figure out how to get deferred 
> > > > > > > > > > > instantiation to work) cause instantiation, which can 
> > > > > > > > > > > cause issues with incomplete types/CRTP/etc.
> > > > > > > > > > > 
> > > > > > > > > > > I think the result is that we cannot 'calculate' this 
> > > > > > > > > > > until it is queried, else we will cause incorrect errors.
> > > > > > > > > > Making this queried on demand is a relatively big change to 
> > > > > > > > > > how we handle type triviality, so I want to be sure we 
> > > > > > > > > > actually need to do this to be conformant.
> > > > > > > > > > 
> > > > > > > > > > When I started working on this I checked what GCC does and 
> > > > > > > > > > it instantiates those constraints during class completion 
> > > > > > > > > > as well. For example this CRTP case: 
> > > > > > > > > > https://godbolt.org/z/EdoYf96zq. MSVC seem to do it as well.
> > > > > > > > > > 
> > > > > > > > > > So maybe it's OK to check the constraints of SMFs 
> > > > > > > > > > specifically?
> > > > > > > > > > 
> > > > > > > > > I think this is done on completeness already in this patch, 
> > > > > > > > > unless i misunderstood the code.
> > > > > > > > > I don't think doing it on demand is a great direction, as 
> > > > > > > > > this does not only affect type traits but also code gen, etc. 
> > > > > > > > > It would create instanciations in unexpected places. wouldn't 
> > > > > > > > > it.
> > > > > > > > > Does the standard has wording suggesting it should be done 
> > > > > > > > > later than on type completeness?
> > > > > > > > The problem, at least for the deferred concepts, is that it 
> > > > > > > > breaks in the CRTP as required to implement ranges.  So 
> > > > > > > > something like this: https://godbolt.org/z/hPqrcqhx5 breaks.
> > > > > > > > 
> > > > > > > > I'm currently working to 'fix' that, so if this patch causes us 
> > > > > > > > to 'check' constraints early, it'll go back to breaking that 
> > > > > > > > example.  The example that Roy showed seems to show that it is 
> > > > > > > > actually checking 'delayed' right now (that is, on demand) in 
> > > > > > > > GCC/MSVC.  I don't know of the consequence/standardeeze that 
> > > > > > > > causes that though.
> > > > > > > Thanks, 
> > > > > > > Follow up stupid question then, do we care about the triviality 
> > > > > > > of dependant types?
> > > > > > > I think doing the check on complete non-dependant types might be 
> > > > > > > a better solution than trying to do it lazily on triviality 
> > > > > > > checks?
> > > > > > I would think it would be not a problem on non-dependent types.  
> > > > > > BUT concepts are only allowed on templated functions (note not only 
> > > > > > on function-templates!) anyway, so I don't think this would be a 
> > > > > > problem?  
> > > > > Erich, I'm a bit confused by your response. I think my example 
> > > > > demonstrates that for default constructors (and other SMFs) GCC and 
> > > > > MSVC instantiate the constraints on class completion and **not** on 
> > > > > demand. This is what I would like to do as well, if we don't have a 
> > > > > good reason not to. (For destructors, performing the checks is even 
> > > > > explicit in the standard.)
> > > > > 
> > > > > Not doing this can introduce some REALLY bad edge cases. What does 
> > > > > this do if we defer the triviality computation?
> > > > > 
> > > > > ```c++
> > > > > 
> > > > > template 
> > > > > struct Base {
> > > > >   Base() = default;
> > > > >   Base() requires (!std::is_trivial_v);
> > > > > };
> > > > > 
> > > > > struct Child : Base { };
> > > > > ```
> > > > > We defer the computation of the constraints on `Base`, and complete 
> > > > > `Child` somehow, but if `Child` is complete then 
> > > > > `std::is_trivial_v` should be well-formed, right? But we get a 
> > > > > logical contradiction instead.
> > > > > 
> > > > > 
> > > > >Erich, I'm a bit confused by your response
> > > > It is entirely possible we're talking past eachother, or 
> > > > misunderstanding eachothers examples.  I'm totally open to that being 
> > > > part of this issue.
> > > > 
> > > > In that example, if we calculate the triviality at '`Base` Class 
> > > > completion', `Child` is not yet complete, right?  So the is_trivial_v 
> > > > would be UB.  

[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-22 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/test/SemaCXX/constrained-special-member-functions.cpp:103
+// FIXME: DR1734.
+static_assert(__is_trivially_copyable(CopyAssignmentChecker<1>));
+static_assert(!__is_trivially_copyable(CopyAssignmentChecker<2>));

cor3ntin wrote:
> Have you rebased since D127593 landed?
Yes. It's related but it's different DRs. And unfortunately they seem much more 
ABI breaking to fix - GCC don't implement them, for example


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:17875
+return true;
+  if (!Context.hasSameType(M1->getParamDecl(0)->getType(),
+   M2->getParamDecl(0)->getType()))

shafik wrote:
> What happens if we have further parameters with default arguments? Unless I 
> am missing something they are still special member functions but the proposal 
> does not seem to cover them.
That's an excellent question.

I'm not sure what to do about default arguments. In a context where the 
additional parameters matter, you're not using them as constructors anymore, 
right? So why would this affect the type traits?
On the one hand [over.match.best] is against this idea of comparing constraints 
when the parameters differ. So also every context where this actually matters 
the overload resolution would probably be ambiguous anyway?

@BRevzin, what do you think? Is the wording intentional to include copy/move 
constructors with default arguments as well?

I checked with GCC and they seem to handle default arguments separately: 
https://godbolt.org/z/1ch3M7MjP



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-25 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 447425.
royjacobson marked an inline comment as done.
royjacobson added a comment.

Rebase on main and slightly update docs.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/AST/DeclCXX.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/conditionally-trivial-smfs.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constrained-special-member-functions.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -927,7 +927,7 @@
   

 https://wg21.link/p0848r3";>P0848R3
-No
+Clang 15
   
   
 https://wg21.link/p1616r1";>P1616R1
Index: clang/test/SemaCXX/constrained-special-member-functions.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constrained-special-member-functions.cpp
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 -verify -std=c++20 %s
+
+template 
+concept C0 = (N == 0);
+template 
+concept C1 = (N == 1);
+template 
+concept C2 = (N == 2);
+
+// Checks are indexed by:
+// Definition:
+//  1. Explicitly defaulted definition
+//  2. Deleted definition
+//  3. User provided definition
+// We have a less constrained user provided method that should not disable
+// the (copyable) triviality of the type.
+
+// Note that because Clang does not implement DRs 1496 and 1734, we say some
+// classes are trivial when the SMFs are deleted.
+
+template 
+struct DefaultConstructorChecker {
+DefaultConstructorChecker() requires C0 = default;
+DefaultConstructorChecker() requires C1 = delete;
+DefaultConstructorChecker() requires C2;
+DefaultConstructorChecker();
+};
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
+static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
+static_assert(__is_trivial(DefaultConstructorChecker<0>));
+// FIXME: DR1496
+static_assert(__is_trivial(DefaultConstructorChecker<1>));
+static_assert(!__is_trivial(DefaultConstructorChecker<2>));
+static_assert(!__is_trivial(DefaultConstructorChecker<3>));
+
+template 
+struct CopyConstructorChecker {
+CopyConstructorChecker(const CopyConstructorChecker&) requires C0 = default;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C1 = delete;
+CopyConstructorChecker(const CopyConstructorChecker&) requires C2;
+CopyConstructorChecker(const CopyConstructorChecker&);
+};
+
+static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));
+static_assert(!__is_trivial(CopyConstructorChecker<0>));
+static_assert(!__is_trivial(CopyConstructorChecker<1>));
+static_assert(!__is_trivial(CopyConstructorChecker<2>));
+static_assert(!__is_trivial(CopyConstructorChecker<3>));
+
+template 
+struct MoveConstructorChecker {
+MoveConstructorChecker(MoveConstructorChecker&&) requires C0 = default;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C1 = delete;
+MoveConstructorChecker(MoveConstructorChecker&&) requires C2;
+MoveConstructorChecker(MoveConstructorChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));
+// FIXME: DR1734
+static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));
+static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));
+static_assert(!__is_trivial(MoveConstructorChecker<0>));
+static_assert(!__is_trivial(MoveConstructorChecker<1>));
+static_assert(!__is_trivial(MoveConstructorChecker<2>));
+static_assert(!__is_trivial(MoveConstructorChecker<3>));
+
+template 
+struct MoveAssignmentChecker {
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0 = default;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1 = delete;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2;
+MoveAssignmentChecker& operator=(MoveAssignmentChecker&&);
+};
+
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));
+// FIXME: DR1734.
+static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));
+static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>));
+static_assert(__is_trivia

[PATCH] D128619: [Clang] Implement P0848 (Conditionally Trivial Special Member Functions)

2022-07-25 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

@erichkeane @cor3ntin

If you have time for review right now, I think it's reasonably ready and I 
would still like to merge it this week so it can land in Clang15.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128619

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D125711: [concepts] Implement dcl.decl.general p4: No constraints on non-template funcs

2022-05-16 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson accepted this revision.
royjacobson added a comment.
This revision is now accepted and ready to land.

Code and added/modified tests LGTM!

Do you think we should add a release note, given that it could break existing 
code? Its seems a bit unlikely, but the amount of broken tests have made me a 
bit worried.
Also, maybe mention the github issue 
(https://github.com/llvm/llvm-project/issues/51173) in the commit message.




Comment at: clang/test/Parser/cxx-concepts-requires-clause.cpp:145
 
+  template
 struct B {




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

https://reviews.llvm.org/D125711

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D126160: [Concepts] Add an error for unsupported P0848 (destructor overloading) code

2022-05-22 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

We have received numeroud bug reports over P0848 not being implemented for 
destructors. We currently allow multiple destructor declarations but we will 
always select the first one, which might unintendedly compile with the wrong 
destructor. This patch adds a diagnostic for classes that try to overload 
destructors with constraints so users won't be confused when their (legal) code 
doesn't work.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D126160

Files:
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/lib/AST/DeclCXX.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp


Index: clang/test/CXX/over/over.match/over.match.viable/p3.cpp
===
--- clang/test/CXX/over/over.match/over.match.viable/p3.cpp
+++ clang/test/CXX/over/over.match/over.match.viable/p3.cpp
@@ -48,21 +48,20 @@
   void foo(A) requires true;
   S(A) requires false;
   S(double) requires true;
+  // expected-note@-1 7{{destructor declared here}}
   ~S() requires false;
-  // expected-note@-1 2{{because 'false' evaluated to false}}
+  // expected-note@-1 7{{destructor declared here}}
   ~S() requires true;
   operator int() requires true;
   operator int() requires false;
 };
 
 void bar() {
+  // Note - we have a hard error in this case until P0848 is implemented.
+  // expected-error@ 7{{overloading destructors is not supported yet}}
   WrapsStatics::foo(A{});
   S{1.}.foo(A{});
-  // expected-error@-1{{invalid reference to function '~S': constraints not 
satisfied}}
-  // Note - this behavior w.r.t. constrained dtors is a consequence of current
-  // wording, which does not invoke overload resolution when a dtor is called.
-  // P0848 is set to address this issue.
+
   S s = 1;
-  // expected-error@-1{{invalid reference to function '~S': constraints not 
satisfied}}
   int a = s;
 }
Index: clang/lib/AST/DeclCXX.cpp
===
--- clang/lib/AST/DeclCXX.cpp
+++ clang/lib/AST/DeclCXX.cpp
@@ -29,6 +29,7 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/UnresolvedSet.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticAST.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
@@ -1895,6 +1896,32 @@
 
   DeclContext::lookup_result R = lookup(Name);
 
+  // We don't support C++20 constrained destructors yet, and we are unlikely to
+  // do so in the near future. Until we do, we check here for multiple
+  // declarations and report an error. We have to handle correctly the case of
+  // merged declarations in modules and the case of invalid templated
+  // destructors so this is a bit involved.
+  if (!(R.empty() || R.isSingleResult())) {
+bool hasNonTrivialOverloads = false;
+auto firstDecl = R.front();
+for (const auto &decl : R) {
+  if (decl->getFunctionType() && firstDecl->getFunctionType() &&
+  !Context.hasSameType(decl->getFunctionType(),
+   firstDecl->getFunctionType())) {
+hasNonTrivialOverloads = true;
+  }
+}
+if (hasNonTrivialOverloads) {
+  Context.getDiagnostics().Report(
+  diag::err_unsupported_destructor_overloading);
+  for (const auto &decl : R) {
+Context.getDiagnostics().Report(
+decl->getLocation(),
+diag::note_unsupported_destructor_overloading_declaration);
+  }
+}
+  }
+
   return R.empty() ? nullptr : dyn_cast(R.front());
 }
 
Index: clang/include/clang/Basic/DiagnosticASTKinds.td
===
--- clang/include/clang/Basic/DiagnosticASTKinds.td
+++ clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -597,4 +597,11 @@
 def warn_unaligned_access : Warning<
   "field %1 within %0 is less aligned than %2 and is usually due to %0 being "
   "packed, which can lead to unaligned accesses">, InGroup, 
DefaultIgnore;
+
+def err_unsupported_destructor_overloading : Error<
+  "overloading destructors is not supported yet in this version. Consult "
+  "'https://github.com/llvm/llvm-project/issues/45614' for updates">;
+def note_unsupported_destructor_overloading_declaration : Note<
+  "destructor declared here.">;
+
 }


Index: clang/test/CXX/over/over.match/over.match.viable/p3.cpp
===
--- clang/test/CXX/over/over.match/over.match.viable/p3.cpp
+++ clang/test/CXX/over/over.match/over.match.viable/p3.cpp
@@ -48,21 +48,20 @@
   void foo(A) requires true;
   S(A) requires false;
   S(double) requires true;
+  // expected-note@-1 7{{destructor declared here}}
   ~S() requires false;
-  // expected-note@-1 2{{because 'false' evaluated to false}}
+  // expected-note@-1 7{{d

[PATCH] D126160: [Concepts] Add an error for unsupported P0848 (destructor overloading) code

2022-05-22 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 431229.
royjacobson added a comment.

A working version.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126160

Files:
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/lib/AST/DeclCXX.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp


Index: clang/test/CXX/over/over.match/over.match.viable/p3.cpp
===
--- clang/test/CXX/over/over.match/over.match.viable/p3.cpp
+++ clang/test/CXX/over/over.match/over.match.viable/p3.cpp
@@ -44,24 +44,26 @@
 
 template
 struct S {
+  // expected-error@-1 7{{overloading destructors is not supported}}
   void foo(int) requires false;
   void foo(A) requires true;
   S(A) requires false;
   S(double) requires true;
   ~S() requires false;
   // expected-note@-1 2{{because 'false' evaluated to false}}
+  // expected-note@-2 7{{destructor declared here}}
   ~S() requires true;
+  // expected-note@-1 7{{destructor declared here}}
   operator int() requires true;
   operator int() requires false;
 };
 
 void bar() {
+  // Note - we have a hard error in this case until P0848 is implemented.
   WrapsStatics::foo(A{});
   S{1.}.foo(A{});
   // expected-error@-1{{invalid reference to function '~S': constraints not 
satisfied}}
-  // Note - this behavior w.r.t. constrained dtors is a consequence of current
-  // wording, which does not invoke overload resolution when a dtor is called.
-  // P0848 is set to address this issue.
+
   S s = 1;
   // expected-error@-1{{invalid reference to function '~S': constraints not 
satisfied}}
   int a = s;
Index: clang/lib/AST/DeclCXX.cpp
===
--- clang/lib/AST/DeclCXX.cpp
+++ clang/lib/AST/DeclCXX.cpp
@@ -29,6 +29,7 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/UnresolvedSet.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticAST.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
@@ -1895,6 +1896,33 @@
 
   DeclContext::lookup_result R = lookup(Name);
 
+  // We don't support C++20 constrained destructors yet, and we are unlikely to
+  // do so in the near future. Until we do, we check here for multiple
+  // declarations and report an error. We have to handle correctly the case of
+  // merged declarations in modules and the case of invalid templated
+  // destructors so this is a bit involved.
+  // We also don't emit errors on OpenCL code because OpenCL desturctors can
+  // overload on address space (https://reviews.llvm.org/D64569).
+  if (!(R.empty() || R.isSingleResult()) && !Context.getLangOpts().OpenCL) {
+bool hasNonTrivialOverloads = false;
+auto firstDecl = R.front();
+for (const auto &decl : R) {
+  if (!decl->isTemplateDecl() && !firstDecl->isTemplateDecl() &&
+  !Context.isSameEntity(decl, firstDecl)) {
+hasNonTrivialOverloads = true;
+  }
+}
+if (hasNonTrivialOverloads) {
+  Context.getDiagnostics().Report(
+  getLocation(), diag::err_unsupported_destructor_overloading);
+  for (const auto &decl : R) {
+Context.getDiagnostics().Report(
+decl->getLocation(),
+diag::note_unsupported_destructor_overloading_declaration);
+  }
+}
+  }
+
   return R.empty() ? nullptr : dyn_cast(R.front());
 }
 
Index: clang/include/clang/Basic/DiagnosticASTKinds.td
===
--- clang/include/clang/Basic/DiagnosticASTKinds.td
+++ clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -597,4 +597,11 @@
 def warn_unaligned_access : Warning<
   "field %1 within %0 is less aligned than %2 and is usually due to %0 being "
   "packed, which can lead to unaligned accesses">, InGroup, 
DefaultIgnore;
+
+def err_unsupported_destructor_overloading : Error<
+  "overloading destructors is not supported yet in this version. Consult "
+  "'https://github.com/llvm/llvm-project/issues/45614' for updates">;
+def note_unsupported_destructor_overloading_declaration : Note<
+  "destructor declared here.">;
+
 }


Index: clang/test/CXX/over/over.match/over.match.viable/p3.cpp
===
--- clang/test/CXX/over/over.match/over.match.viable/p3.cpp
+++ clang/test/CXX/over/over.match/over.match.viable/p3.cpp
@@ -44,24 +44,26 @@
 
 template
 struct S {
+  // expected-error@-1 7{{overloading destructors is not supported}}
   void foo(int) requires false;
   void foo(A) requires true;
   S(A) requires false;
   S(double) requires true;
   ~S() requires false;
   // expected-note@-1 2{{because 'false' evaluated to false}}
+  // expected-note@-2 7{{destructor declared here}}
   ~S() requires true;
+  // expected-note@-1 7{{destructor declared here}}
   operator int() requires true;
   operator int() requires false;

[PATCH] D126160: [Concepts] Add an error for unsupported P0848 (destructor overloading) code

2022-05-22 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson planned changes to this revision.
royjacobson added a comment.

I've thought about this a bit more and I want to move the diagnostic into 
SemaTemplateInstantiateDecl or somewhere close. It makes more sense because 
it's closer to where P0848 needs to be implemented and it will spam less errors.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126160

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D126160: [Concepts] Add an error for unsupported P0848 (destructor overloading) code

2022-05-22 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 431251.
royjacobson added a comment.

Move diagnostic into Sema, make it fire once for every class template 
definitions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126160

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp

Index: clang/test/CXX/over/over.match/over.match.viable/p3.cpp
===
--- clang/test/CXX/over/over.match/over.match.viable/p3.cpp
+++ clang/test/CXX/over/over.match/over.match.viable/p3.cpp
@@ -44,24 +44,26 @@
 
 template
 struct S {
+  // expected-error@-1  {{overloading destructors is not supported}}
   void foo(int) requires false;
   void foo(A) requires true;
   S(A) requires false;
   S(double) requires true;
   ~S() requires false;
   // expected-note@-1 2{{because 'false' evaluated to false}}
+  // expected-note@-2 {{destructor declared here}}
   ~S() requires true;
+  // expected-note@-1 {{destructor declared here}}
   operator int() requires true;
   operator int() requires false;
 };
 
 void bar() {
+  // Note - we have a hard error in this case until P0848 is implemented.
   WrapsStatics::foo(A{});
   S{1.}.foo(A{});
   // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
-  // Note - this behavior w.r.t. constrained dtors is a consequence of current
-  // wording, which does not invoke overload resolution when a dtor is called.
-  // P0848 is set to address this issue.
+
   S s = 1;
   // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
   int a = s;
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -6731,6 +6731,45 @@
   return IssuedDiagnostic;
 }
 
+namespace {
+
+/// We don't support C++20 constrained destructors yet, and we are unlikely to
+/// do so in the near future. Until we do, we check here for multiple
+/// declarations and report an error. We have to handle correctly the case of
+/// merged declarations in modules and the case of invalid templated
+/// destructors so this is a bit involved.
+/// We also don't emit errors on OpenCL code because OpenCL destructors can
+/// overload on address space (https://reviews.llvm.org/D64569).
+void DiagnoseUnsupportedDestructorOverloading(Sema& S, const CXXRecordDecl* Record) {
+  ASTContext &Context = Record->getASTContext();
+  QualType ClassType = Context.getTypeDeclType(Record);
+
+  DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
+  Context.getCanonicalType(ClassType));
+
+  DeclContext::lookup_result R = Record->lookup(Name);
+
+  if (!(R.empty() || R.isSingleResult()) && !Context.getLangOpts().OpenCL) {
+bool hasNonTrivialOverloads = false;
+auto firstDecl = R.front();
+for (const auto &decl : R) {
+  if (!decl->isTemplateDecl() && !firstDecl->isTemplateDecl() &&
+  !Context.isSameEntity(decl, firstDecl)) {
+hasNonTrivialOverloads = true;
+  }
+}
+if (hasNonTrivialOverloads) {
+  S.Diag(Record->getLocation(),
+ diag::err_unsupported_destructor_overloading);
+  for (const auto &decl : R) {
+S.Diag(decl->getLocation(),
+   diag::note_unsupported_destructor_overloading_declaration);
+  }
+}
+  }
+}
+} // namespace
+
 /// Perform semantic checks on a class definition that has been
 /// completing, introducing implicitly-declared members, checking for
 /// abstract types, etc.
@@ -6955,6 +6994,9 @@
   CheckCompletedMemberFunction(M);
   };
 
+  if (!inTemplateInstantiation())
+DiagnoseUnsupportedDestructorOverloading(*this, Record);
+
   // Check the destructor before any other member function. We need to
   // determine whether it's trivial in order to determine whether the claas
   // type is a literal type, which is a prerequisite for determining whether
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2892,6 +2892,11 @@
 def err_unsupported_placeholder_constraint : Error<
   "constrained placeholder types other than simple 'auto' on non-type template "
   "parameters not supported yet">;
+def err_unsupported_destructor_overloading : Error<
+  "overloading destructors is not supported yet in this version. Consult "
+  "'https://github.com/llvm/llvm-project/issues/45614' for updates">;
+def note_unsupported_destructor_overloading_declaration : Note<
+  "destructor declared here.">;
 
 def err_template_different_requires_clause : Error<
   "requires clause differs in template redeclaration">;
___

[PATCH] D126160: [Concepts] Add an error for unsupported P0848 (destructor overloading) code

2022-05-22 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 431263.
royjacobson added a comment.

Fix conventions


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126160

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp

Index: clang/test/CXX/over/over.match/over.match.viable/p3.cpp
===
--- clang/test/CXX/over/over.match/over.match.viable/p3.cpp
+++ clang/test/CXX/over/over.match/over.match.viable/p3.cpp
@@ -44,24 +44,26 @@
 
 template
 struct S {
+  // expected-error@-1  {{overloading destructors is not supported}}
   void foo(int) requires false;
   void foo(A) requires true;
   S(A) requires false;
   S(double) requires true;
   ~S() requires false;
   // expected-note@-1 2{{because 'false' evaluated to false}}
+  // expected-note@-2 {{destructor declared here}}
   ~S() requires true;
+  // expected-note@-1 {{destructor declared here}}
   operator int() requires true;
   operator int() requires false;
 };
 
 void bar() {
+  // Note - we have a hard error in this case until P0848 is implemented.
   WrapsStatics::foo(A{});
   S{1.}.foo(A{});
   // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
-  // Note - this behavior w.r.t. constrained dtors is a consequence of current
-  // wording, which does not invoke overload resolution when a dtor is called.
-  // P0848 is set to address this issue.
+
   S s = 1;
   // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
   int a = s;
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -6731,6 +6731,45 @@
   return IssuedDiagnostic;
 }
 
+namespace {
+
+/// We don't support C++20 constrained destructors yet, and we are unlikely to
+/// do so in the near future. Until we do, we check here for multiple
+/// declarations and report an error. We have to handle correctly the case of
+/// merged declarations in modules and the case of invalid templated
+/// destructors so this is a bit involved.
+/// We also don't emit errors on OpenCL code because OpenCL destructors can
+/// overload on address space (https://reviews.llvm.org/D64569).
+void DiagnoseUnsupportedDestructorOverloading(Sema& S, const CXXRecordDecl* Record) {
+  ASTContext &Context = Record->getASTContext();
+  QualType ClassType = Context.getTypeDeclType(Record);
+
+  DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
+  Context.getCanonicalType(ClassType));
+
+  DeclContext::lookup_result R = Record->lookup(Name);
+
+  if (!(R.empty() || R.isSingleResult()) && !Context.getLangOpts().OpenCL) {
+bool HasNonTrivialOverloads = false;
+auto FirstDecl = R.front();
+for (const auto &Decl : R) {
+  if (!Decl->isTemplateDecl() && !FirstDecl->isTemplateDecl() &&
+  !Context.isSameEntity(Decl, FirstDecl)) {
+HasNonTrivialOverloads = true;
+  }
+}
+if (HasNonTrivialOverloads) {
+  S.Diag(Record->getLocation(),
+ diag::err_unsupported_destructor_overloading);
+  for (const auto &Decl : R) {
+S.Diag(Decl->getLocation(),
+   diag::note_unsupported_destructor_overloading_declaration);
+  }
+}
+  }
+}
+} // namespace
+
 /// Perform semantic checks on a class definition that has been
 /// completing, introducing implicitly-declared members, checking for
 /// abstract types, etc.
@@ -6955,6 +6994,9 @@
   CheckCompletedMemberFunction(M);
   };
 
+  if (!inTemplateInstantiation())
+DiagnoseUnsupportedDestructorOverloading(*this, Record);
+
   // Check the destructor before any other member function. We need to
   // determine whether it's trivial in order to determine whether the claas
   // type is a literal type, which is a prerequisite for determining whether
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2892,6 +2892,11 @@
 def err_unsupported_placeholder_constraint : Error<
   "constrained placeholder types other than simple 'auto' on non-type template "
   "parameters not supported yet">;
+def err_unsupported_destructor_overloading : Error<
+  "overloading destructors is not supported yet in this version. Consult "
+  "'https://github.com/llvm/llvm-project/issues/45614' for updates">;
+def note_unsupported_destructor_overloading_declaration : Note<
+  "destructor declared here.">;
 
 def err_template_different_requires_clause : Error<
   "requires clause differs in template redeclaration">;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lis

[PATCH] D126160: [Concepts] Add an error for unsupported P0848 (destructor overloading) code

2022-05-22 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson abandoned this revision.
royjacobson added a comment.

I continued hacking a bit at this and I think I got a working approach to 
implementing P0848 (down to 6 failing tests, will probably post at least a 
draft tomorrow). So I'll close for now. Maybe it's still useful for backporting 
if someone wants to. Sorry for all the mail spam from today...


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126160

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D126194: [Concepts] Implement overload resolution for destructors (P0848)

2022-05-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson created this revision.
Herald added a project: All.
royjacobson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch implements a necessary part of P0848, the overload resolution for 
destructors.
It is now possible to overload destructors based on constraints, and the 
eligible destructor
will be selected at the end of the class.

The approach this patch takes is to perform the overload resolution after 
instantiating the members
in Sema::InstantiateClass, and to remove from the CXXRecordDecl all 
declarations of non-selected
destructors.

This is the approach that I found that can satisfy the following requirements:

1. The overload resolution and constraint checking is performed after the other 
members are defined but before the type is complete. This is important because 
constraints can check other members of the class, but the result of the 
overload resolution can change the type traits (triviallity etc.) of the class.
2. The order of (visible) functions in the AST is kept. This is important 
because it affects ABI through the order of functions in the vtable.

Note: this is only enabled for CPP20 - I tested it without the CPP20 
restriction and
all the tests passed, so I can remove the restriction. I slightly prefer to 
remove it because
it will be easier to get coverage for this and it seems safer.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D126194

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/CXX/class/class.dtor/p4.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp

Index: clang/test/CXX/over/over.match/over.match.viable/p3.cpp
===
--- clang/test/CXX/over/over.match/over.match.viable/p3.cpp
+++ clang/test/CXX/over/over.match/over.match.viable/p3.cpp
@@ -49,7 +49,6 @@
   S(A) requires false;
   S(double) requires true;
   ~S() requires false;
-  // expected-note@-1 2{{because 'false' evaluated to false}}
   ~S() requires true;
   operator int() requires true;
   operator int() requires false;
@@ -58,11 +57,7 @@
 void bar() {
   WrapsStatics::foo(A{});
   S{1.}.foo(A{});
-  // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
-  // Note - this behavior w.r.t. constrained dtors is a consequence of current
-  // wording, which does not invoke overload resolution when a dtor is called.
-  // P0848 is set to address this issue.
+
   S s = 1;
-  // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
   int a = s;
 }
Index: clang/test/CXX/class/class.dtor/p4.cpp
===
--- /dev/null
+++ clang/test/CXX/class/class.dtor/p4.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+
+template 
+struct A {
+  ~A() = delete; // expected-note {{explicitly marked deleted}}
+  ~A() requires(N == 1) = delete; // expected-note {{explicitly marked deleted}}
+};
+
+template 
+struct B {
+  ~B() requires(N == 1) = delete; // expected-note {{explicitly marked deleted}}
+  virtual ~B() = delete; // expected-note {{explicitly marked deleted}}
+};
+
+template
+concept CO1 = N == 1;
+
+template
+concept CO2 = N > 0;
+
+template 
+struct C {
+  ~C() = delete; // expected-note {{explicitly marked deleted}}
+  ~C() requires(CO1) = delete;
+  ~C() requires(CO1 && CO2) = delete; // expected-note {{explicitly marked deleted}}
+};
+
+template 
+struct D {
+  ~D() requires(N != 0) = delete; // expected-note {{explicitly marked deleted}}
+  // expected-note@-1 {{candidate function has been explicitly deleted}}
+  // expected-note@-2 {{candidate function not viable: constraints not satisfied}}
+  // expected-note@-3 {{evaluated to false}}
+  ~D() requires(N == 1) = delete;
+  // expected-note@-1 {{candidate function has been explicitly deleted}}
+  // expected-note@-2 {{candidate function not viable: constraints not satisfied}}
+  // expected-note@-3 {{evaluated to false}}
+};
+
+template 
+concept Foo = requires (T t) {
+  { t.foo() };
+};
+
+template
+struct E {
+  void foo();
+  ~E();
+  ~E() requires Foo = delete;  // expected-note {{explicitly marked deleted}}
+};
+
+template struct A<1>;
+template struct A<2>;
+template struct B<1>;
+template struct B<2>;
+template struct C<1>;
+template struct C<2>;
+template struct D<0>;  // expected-error {{no viable destructor found for class 'D<0>'}} expected-note {{in instantiation of template}}
+template struct D<1>;  // expected-error {{destructor of class 'D<1>' is ambiguous}} expected-note {{in instantiation of template}}
+template struct D<2>;
+template struct E<1>;
+
+int main() {
+  A<1> a1; // expected-error {{attempt to use a deleted function}}
+  A<2> a2; // expected-error {{attempt to use a deleted function}}
+  B<1> b1; // expected-error {{attempt to use a deleted function}}

[PATCH] D126194: [Concepts] Implement overload resolution for destructors (P0848)

2022-05-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 431333.
royjacobson added a comment.

Fix typo


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126194

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/CXX/class/class.dtor/p4.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp

Index: clang/test/CXX/over/over.match/over.match.viable/p3.cpp
===
--- clang/test/CXX/over/over.match/over.match.viable/p3.cpp
+++ clang/test/CXX/over/over.match/over.match.viable/p3.cpp
@@ -49,7 +49,6 @@
   S(A) requires false;
   S(double) requires true;
   ~S() requires false;
-  // expected-note@-1 2{{because 'false' evaluated to false}}
   ~S() requires true;
   operator int() requires true;
   operator int() requires false;
@@ -58,11 +57,7 @@
 void bar() {
   WrapsStatics::foo(A{});
   S{1.}.foo(A{});
-  // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
-  // Note - this behavior w.r.t. constrained dtors is a consequence of current
-  // wording, which does not invoke overload resolution when a dtor is called.
-  // P0848 is set to address this issue.
+
   S s = 1;
-  // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
   int a = s;
 }
Index: clang/test/CXX/class/class.dtor/p4.cpp
===
--- /dev/null
+++ clang/test/CXX/class/class.dtor/p4.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+
+template 
+struct A {
+  ~A() = delete; // expected-note {{explicitly marked deleted}}
+  ~A() requires(N == 1) = delete; // expected-note {{explicitly marked deleted}}
+};
+
+template 
+struct B {
+  ~B() requires(N == 1) = delete; // expected-note {{explicitly marked deleted}}
+  virtual ~B() = delete; // expected-note {{explicitly marked deleted}}
+};
+
+template
+concept CO1 = N == 1;
+
+template
+concept CO2 = N > 0;
+
+template 
+struct C {
+  ~C() = delete; // expected-note {{explicitly marked deleted}}
+  ~C() requires(CO1) = delete;
+  ~C() requires(CO1 && CO2) = delete; // expected-note {{explicitly marked deleted}}
+};
+
+template 
+struct D {
+  ~D() requires(N != 0) = delete; // expected-note {{explicitly marked deleted}}
+  // expected-note@-1 {{candidate function has been explicitly deleted}}
+  // expected-note@-2 {{candidate function not viable: constraints not satisfied}}
+  // expected-note@-3 {{evaluated to false}}
+  ~D() requires(N == 1) = delete;
+  // expected-note@-1 {{candidate function has been explicitly deleted}}
+  // expected-note@-2 {{candidate function not viable: constraints not satisfied}}
+  // expected-note@-3 {{evaluated to false}}
+};
+
+template 
+concept Foo = requires (T t) {
+  { t.foo() };
+};
+
+template
+struct E {
+  void foo();
+  ~E();
+  ~E() requires Foo = delete;  // expected-note {{explicitly marked deleted}}
+};
+
+template struct A<1>;
+template struct A<2>;
+template struct B<1>;
+template struct B<2>;
+template struct C<1>;
+template struct C<2>;
+template struct D<0>;  // expected-error {{no viable destructor found for class 'D<0>'}} expected-note {{in instantiation of template}}
+template struct D<1>;  // expected-error {{destructor of class 'D<1>' is ambiguous}} expected-note {{in instantiation of template}}
+template struct D<2>;
+template struct E<1>;
+
+int main() {
+  A<1> a1; // expected-error {{attempt to use a deleted function}}
+  A<2> a2; // expected-error {{attempt to use a deleted function}}
+  B<1> b1; // expected-error {{attempt to use a deleted function}}
+  B<2> b2; // expected-error {{attempt to use a deleted function}}
+  C<1> c1; // expected-error {{attempt to use a deleted function}}
+  C<2> c2; // expected-error {{attempt to use a deleted function}}
+  D<0> d0;
+  D<1> d1;
+  D<2> d2; // expected-error {{attempt to use a deleted function}}
+  E<1> e1; // expected-error {{attempt to use a deleted function}}
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2320,6 +2320,81 @@
 }
   };
 
+  /// [class.dtor]p4:
+  ///   At the end of the definition of a class, overload resolution is
+  ///   performed among the prospective destructors declared in that class with
+  ///   an empty argument list to select the destructor for the class, also
+  ///   known as the selected destructor.
+  ///
+  /// To achieve that, we remove all non-selected destructors from the AST,
+  /// which is a bit unusual. We can't let those declarations be in AST and rely
+  /// on LookupSpecialMember to return the correct declaration because a lot of
+  /// code relies on CXXRecordDecl::getDestructor() which assumes there can only
+  /// 

[PATCH] D126194: [Concepts] Implement overload resolution for destructors (P0848)

2022-05-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D126194#3531280 , @cor3ntin wrote:

> In D126194#3531267 , @erichkeane 
> wrote:
>
>> How much of P0848 is missing after this?  If nothing/not much, should we 
>> update cxx_status.html as well?
>
> P0848 applies to all special member function. At best we could mark it 
> partial but most of the work still need to be done.
> I gave a shot to P0848 a few months ago, but my assesment is that clang might 
> have to significantly refactor of special member functions to do that cleanly

Corentin, are there other places like getDestructor where we need the 
constraints Sema information in the AST? I hoped the other special member 
functions go through LookupSpecialMember which does the needed overload 
resolution.

So as far as I understand the code base, the P0848 part that remains is 
computing the SMFs that are 'eligible' and update the type traits 
(trivial/trivially copyable) accordingly. Currently we mark those inside 
CXXRecordDecl::addedMember, so we'll probably have to override them. I also 
don't understand how exactly the eligibility checks interact with the deferred 
concept checking.

BTW, this also interacts funnily with other type traits. For example, this is 
apparently legal

  #include 
  template
  struct A {
A& operator=(A&&) requires true;
virtual A& operator=(A&&);
  };
  static_assert(!std::is_aggregate_v>);

So ineligible SMFs are ineligible only for the purpose of [copy]triviality, and 
can still have other visible effects!

About the status page - we're going to break ABI when we implement the type 
traits change so I don't think we should update it yet.




Comment at: clang/lib/Sema/SemaTemplateInstantiate.cpp:2330
+  /// To achieve that, we remove all non-selected destructors from the AST,
+  /// which is a bit unusual. We can't let those declarations be in AST and 
rely
+  /// on LookupSpecialMember to return the correct declaration because a lot of

cor3ntin wrote:
> erichkeane wrote:
> > I don't think this ends up being acceptable (removing them from the AST).  
> > Instead, we should probably mark them as "invalid" and update getDestructor 
> > to only return the 'only' destructor, or the first not-invalid one.
> I'd rather we stay consistent with the wording, keep track of a selected 
> destructor which would be returned by `getDestructor`. it's more surgery but 
> it's a lot cleaner imo
Corentin, do you suggest doing this in CXXRecordDecl explicitly?

Erich - I agree, this seems like a better solution, although this is a bit of 
abuse to 'invalid' in the case of less-constrained candidates. Ideally we might 
want another AST property of 'eligible' and keep track of things there, but I 
don't really know the AST code well enough to do it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126194

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D126194: [Concepts] Implement overload resolution for destructors (P0848)

2022-05-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaTemplateInstantiate.cpp:2330
+  /// To achieve that, we remove all non-selected destructors from the AST,
+  /// which is a bit unusual. We can't let those declarations be in AST and 
rely
+  /// on LookupSpecialMember to return the correct declaration because a lot of

erichkeane wrote:
> royjacobson wrote:
> > cor3ntin wrote:
> > > erichkeane wrote:
> > > > I don't think this ends up being acceptable (removing them from the 
> > > > AST).  Instead, we should probably mark them as "invalid" and update 
> > > > getDestructor to only return the 'only' destructor, or the first 
> > > > not-invalid one.
> > > I'd rather we stay consistent with the wording, keep track of a selected 
> > > destructor which would be returned by `getDestructor`. it's more surgery 
> > > but it's a lot cleaner imo
> > Corentin, do you suggest doing this in CXXRecordDecl explicitly?
> > 
> > Erich - I agree, this seems like a better solution, although this is a bit 
> > of abuse to 'invalid' in the case of less-constrained candidates. Ideally 
> > we might want another AST property of 'eligible' and keep track of things 
> > there, but I don't really know the AST code well enough to do it.
> I like the idea of marking them eligible that way.  If this JUST has to do 
> with Destructors for now, adding a bit to `CXXDestructorDecl` is a pretty 
> trivial thing to do.  I'm pretty sure it is defined in `DeclCXX.h`. At that 
> point, we just need to make sure it is checked during 'getDestructor' (or at 
> least, around any calls to that).
I think we'll need it soon for the other SMF as well. (Or maybe even for all 
member functions if CWG2421 is ever resolved). 

So maybe I should just take some time to look at `FunctionDeclBitfields` and 
see if I can update it. (I hope updating the ast printers isn't too hard)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126194

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D126194: [Concepts] Implement overload resolution for destructors (P0848)

2022-05-23 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 431589.
royjacobson added a comment.

Update the approach to use an AST property, and enable this for all language 
variants (not just CPP20).

There's still one test failing because OpenCL have got their own destructor 
thing going, I'll try to
see what I can do about it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126194

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/class/class.dtor/p4.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp

Index: clang/test/CXX/over/over.match/over.match.viable/p3.cpp
===
--- clang/test/CXX/over/over.match/over.match.viable/p3.cpp
+++ clang/test/CXX/over/over.match/over.match.viable/p3.cpp
@@ -49,7 +49,6 @@
   S(A) requires false;
   S(double) requires true;
   ~S() requires false;
-  // expected-note@-1 2{{because 'false' evaluated to false}}
   ~S() requires true;
   operator int() requires true;
   operator int() requires false;
@@ -58,11 +57,7 @@
 void bar() {
   WrapsStatics::foo(A{});
   S{1.}.foo(A{});
-  // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
-  // Note - this behavior w.r.t. constrained dtors is a consequence of current
-  // wording, which does not invoke overload resolution when a dtor is called.
-  // P0848 is set to address this issue.
+
   S s = 1;
-  // expected-error@-1{{invalid reference to function '~S': constraints not satisfied}}
   int a = s;
 }
Index: clang/test/CXX/class/class.dtor/p4.cpp
===
--- /dev/null
+++ clang/test/CXX/class/class.dtor/p4.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+
+template 
+struct A {
+  ~A() = delete; // expected-note {{explicitly marked deleted}}
+  ~A() requires(N == 1) = delete; // expected-note {{explicitly marked deleted}}
+};
+
+template 
+struct B {
+  ~B() requires(N == 1) = delete; // expected-note {{explicitly marked deleted}}
+  virtual ~B() = delete; // expected-note {{explicitly marked deleted}}
+};
+
+template
+concept CO1 = N == 1;
+
+template
+concept CO2 = N > 0;
+
+template 
+struct C {
+  ~C() = delete; // expected-note {{explicitly marked deleted}}
+  ~C() requires(CO1) = delete;
+  ~C() requires(CO1 && CO2) = delete; // expected-note {{explicitly marked deleted}}
+};
+
+template 
+struct D {
+  ~D() requires(N != 0) = delete; // expected-note {{explicitly marked deleted}}
+  // expected-note@-1 {{candidate function has been explicitly deleted}}
+  // expected-note@-2 {{candidate function not viable: constraints not satisfied}}
+  // expected-note@-3 {{evaluated to false}}
+  ~D() requires(N == 1) = delete;
+  // expected-note@-1 {{candidate function has been explicitly deleted}}
+  // expected-note@-2 {{candidate function not viable: constraints not satisfied}}
+  // expected-note@-3 {{evaluated to false}}
+};
+
+template 
+concept Foo = requires (T t) {
+  { t.foo() };
+};
+
+template
+struct E {
+  void foo();
+  ~E();
+  ~E() requires Foo = delete;  // expected-note {{explicitly marked deleted}}
+};
+
+template struct A<1>;
+template struct A<2>;
+template struct B<1>;
+template struct B<2>;
+template struct C<1>;
+template struct C<2>;
+template struct D<0>;  // expected-error {{no viable destructor found for class 'D<0>'}} expected-note {{in instantiation of template}}
+template struct D<1>;  // expected-error {{destructor of class 'D<1>' is ambiguous}} expected-note {{in instantiation of template}}
+template struct D<2>;
+template struct E<1>;
+
+int main() {
+  A<1> a1; // expected-error {{attempt to use a deleted function}}
+  A<2> a2; // expected-error {{attempt to use a deleted function}}
+  B<1> b1; // expected-error {{attempt to use a deleted function}}
+  B<2> b2; // expected-error {{attempt to use a deleted function}}
+  C<1> c1; // expected-error {{attempt to use a deleted function}}
+  C<2> c2; // expected-error {{attempt to use a deleted function}}
+  D<0> d0;
+  D<1> d1;
+  D<2> d2; // expected-error {{attempt to use a deleted function}}
+  E<1> e1; // expected-error {{attempt to use a deleted function}}
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -17755,6 +17755,62 @@
   AllIvarDecls.push_back(Ivar);
 }
 
+namespace {
+/// [class.dtor]p4:
+///   At the end of the definition of a class, overload resolution is
+///   performed among the prospective destructors declared in that class with
+///   an empty argument list to select the destructor for the class, also
+///   known as the selected destructor.
+///
+/// We do th

  1   2   3   4   >