[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, 

[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-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-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] D120255: [Concepts] Check constraints for explicit template instantiations

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

In D120255#3352755 , @erichkeane 
wrote:

> Hmm... doing FileCheck in a Sema test is highly irregular.  I would expect us 
> to be able to test this in the type system in some way.  Something like 
> `A<3>::f()` is invalid (see -verify).
>
> Also, please add all the context (as requested above!) with the -U stuff.

I couldn't think of a way to "internally" know whether some function got 
instantiated. I also saw some other instantiation tests do it this way 
(SemaTemplate/instantiate-friend-function.cpp, 
SemaTemplate/inject-templated-friend.cpp). But I'm really not familiar enough 
with the code structure to have an opinion about this..

Also, as I wrote in the description - function explicit instantiation doesn't 
check constraints either but it's a different code path, so, `A<3>::f()` 
currently fails for the wrong reason. It will just try to instantiate the first 
function it finds and then fail the static assert and not the constraint.
(Or worse, fail the internal assert in `SemaTemplate.cpp:10161` if clang was 
built with assertions).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120255

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


[PATCH] D120255: [Concepts] Check constraints for explicit template instantiations

2022-03-01 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 412229.
royjacobson edited the summary of this revision.
royjacobson set the repository for this revision to rG LLVM Github Monorepo.
royjacobson added a comment.
Herald added projects: clang, All.

Updated test so it checks actual instantiation and update the description.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120255

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/SemaTemplate/constraints-instantiation.cpp


Index: clang/test/SemaTemplate/constraints-instantiation.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/constraints-instantiation.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -S -std=c++20 -emit-llvm %s -o - | FileCheck %s
+
+// void PR46029::A<1>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi1EE1fEv
+// void PR46029::A<2>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi2EE1fEv
+// void PR46029::A<3>::f()
+// CHECK-NOT: define {{.*}} @_ZN7PR460291AILi3EE1fEv
+
+namespace PR46029 {
+template 
+struct A {
+  void f() requires(N == 1) {
+static_assert(N == 1);
+  }
+  void f() requires(N == 2) {
+static_assert(N == 2);
+  }
+};
+
+template struct A<1>;
+template struct A<2>;
+template struct A<3>;
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3230,6 +3230,14 @@
   if (FunctionDecl *Pattern =
   Function->getInstantiatedFromMemberFunction()) {

+if (Function->getTrailingRequiresClause()) {
+  ConstraintSatisfaction Satisfaction;
+  if (CheckFunctionConstraints(Function, Satisfaction) ||
+  !Satisfaction.IsSatisfied) {
+continue;
+  }
+}
+
 if (Function->hasAttr())
   continue;



Index: clang/test/SemaTemplate/constraints-instantiation.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/constraints-instantiation.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -S -std=c++20 -emit-llvm %s -o - | FileCheck %s
+
+// void PR46029::A<1>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi1EE1fEv
+// void PR46029::A<2>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi2EE1fEv
+// void PR46029::A<3>::f()
+// CHECK-NOT: define {{.*}} @_ZN7PR460291AILi3EE1fEv
+
+namespace PR46029 {
+template 
+struct A {
+  void f() requires(N == 1) {
+static_assert(N == 1);
+  }
+  void f() requires(N == 2) {
+static_assert(N == 2);
+  }
+};
+
+template struct A<1>;
+template struct A<2>;
+template struct A<3>;
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3230,6 +3230,14 @@
   if (FunctionDecl *Pattern =
   Function->getInstantiatedFromMemberFunction()) {

+if (Function->getTrailingRequiresClause()) {
+  ConstraintSatisfaction Satisfaction;
+  if (CheckFunctionConstraints(Function, Satisfaction) ||
+  !Satisfaction.IsSatisfied) {
+continue;
+  }
+}
+
 if (Function->hasAttr())
   continue;

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


[PATCH] D120255: [Concepts] Check constraints for explicit template instantiations

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

Adding context.
(Sorry - didn't realize you were speaking about the diff itself, thought you 
meant adding general context to the PR message...)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120255

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/SemaTemplate/constraints-instantiation.cpp


Index: clang/test/SemaTemplate/constraints-instantiation.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/constraints-instantiation.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -S -std=c++20 -emit-llvm %s -o - | FileCheck %s
+
+// void PR46029::A<1>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi1EE1fEv
+// void PR46029::A<2>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi2EE1fEv
+// void PR46029::A<3>::f()
+// CHECK-NOT: define {{.*}} @_ZN7PR460291AILi3EE1fEv
+
+namespace PR46029 {
+template 
+struct A {
+  void f() requires(N == 1) {
+static_assert(N == 1);
+  }
+  void f() requires(N == 2) {
+static_assert(N == 2);
+  }
+};
+
+template struct A<1>;
+template struct A<2>;
+template struct A<3>;
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3230,6 +3230,14 @@
   if (FunctionDecl *Pattern =
   Function->getInstantiatedFromMemberFunction()) {
 
+if (Function->getTrailingRequiresClause()) {
+  ConstraintSatisfaction Satisfaction;
+  if (CheckFunctionConstraints(Function, Satisfaction) ||
+  !Satisfaction.IsSatisfied) {
+continue;
+  }
+}
+
 if (Function->hasAttr())
   continue;
 


Index: clang/test/SemaTemplate/constraints-instantiation.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/constraints-instantiation.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -S -std=c++20 -emit-llvm %s -o - | FileCheck %s
+
+// void PR46029::A<1>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi1EE1fEv
+// void PR46029::A<2>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi2EE1fEv
+// void PR46029::A<3>::f()
+// CHECK-NOT: define {{.*}} @_ZN7PR460291AILi3EE1fEv
+
+namespace PR46029 {
+template 
+struct A {
+  void f() requires(N == 1) {
+static_assert(N == 1);
+  }
+  void f() requires(N == 2) {
+static_assert(N == 2);
+  }
+};
+
+template struct A<1>;
+template struct A<2>;
+template struct A<3>;
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3230,6 +3230,14 @@
   if (FunctionDecl *Pattern =
   Function->getInstantiatedFromMemberFunction()) {
 
+if (Function->getTrailingRequiresClause()) {
+  ConstraintSatisfaction Satisfaction;
+  if (CheckFunctionConstraints(Function, Satisfaction) ||
+  !Satisfaction.IsSatisfied) {
+continue;
+  }
+}
+
 if (Function->hasAttr())
   continue;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D120255: [Concepts] Check constraints for explicit template instantiations

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

Slightly update the test command line (add -triple %itanium_abi_triple like in 
other similar tests).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120255

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/SemaTemplate/constraints-instantiation.cpp


Index: clang/test/SemaTemplate/constraints-instantiation.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/constraints-instantiation.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -S -triple %itanium_abi_triple -std=c++20 -emit-llvm %s -o 
- | FileCheck %s
+
+// void PR46029::A<1>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi1EE1fEv
+// void PR46029::A<2>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi2EE1fEv
+// void PR46029::A<3>::f()
+// CHECK-NOT: define {{.*}} @_ZN7PR460291AILi3EE1fEv
+
+namespace PR46029 {
+template 
+struct A {
+  void f() requires(N == 1) {
+static_assert(N == 1);
+  }
+  void f() requires(N == 2) {
+static_assert(N == 2);
+  }
+};
+
+template struct A<1>;
+template struct A<2>;
+template struct A<3>;
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3230,6 +3230,14 @@
   if (FunctionDecl *Pattern =
   Function->getInstantiatedFromMemberFunction()) {
 
+if (Function->getTrailingRequiresClause()) {
+  ConstraintSatisfaction Satisfaction;
+  if (CheckFunctionConstraints(Function, Satisfaction) ||
+  !Satisfaction.IsSatisfied) {
+continue;
+  }
+}
+
 if (Function->hasAttr())
   continue;
 


Index: clang/test/SemaTemplate/constraints-instantiation.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/constraints-instantiation.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -S -triple %itanium_abi_triple -std=c++20 -emit-llvm %s -o - | FileCheck %s
+
+// void PR46029::A<1>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi1EE1fEv
+// void PR46029::A<2>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi2EE1fEv
+// void PR46029::A<3>::f()
+// CHECK-NOT: define {{.*}} @_ZN7PR460291AILi3EE1fEv
+
+namespace PR46029 {
+template 
+struct A {
+  void f() requires(N == 1) {
+static_assert(N == 1);
+  }
+  void f() requires(N == 2) {
+static_assert(N == 2);
+  }
+};
+
+template struct A<1>;
+template struct A<2>;
+template struct A<3>;
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3230,6 +3230,14 @@
   if (FunctionDecl *Pattern =
   Function->getInstantiatedFromMemberFunction()) {
 
+if (Function->getTrailingRequiresClause()) {
+  ConstraintSatisfaction Satisfaction;
+  if (CheckFunctionConstraints(Function, Satisfaction) ||
+  !Satisfaction.IsSatisfied) {
+continue;
+  }
+}
+
 if (Function->hasAttr())
   continue;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D120255: [Concepts] Check constraints for explicit template instantiations

2022-03-02 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/test/SemaTemplate/constraints-instantiation.cpp:3-8
+// void PR46029::A<1>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi1EE1fEv
+// void PR46029::A<2>::f()
+// CHECK: define {{.*}} @_ZN7PR460291AILi2EE1fEv
+// void PR46029::A<3>::f()
+// CHECK-NOT: define {{.*}} @_ZN7PR460291AILi3EE1fEv

aaron.ballman wrote:
> I think it might be better to test this via an `-ast-dump` test (which lives 
> in the `AST` test directory) rather than emitting LLVM IR to determine 
> whether something was instantiated or not.
> 
> Btw, when you convert the test to use `-ast-dump`, be sure to make use of 
> regexes for things like line, column numbers, pointer values, etc so that the 
> test is easier to edit without breaking.
I tried to look now into doing it in the ast-dump. It seems that we create a 
new `ClassTemplateSpecializationDecl` in SemaTemplate:9663 
(`ActOnExplicitInstantiation`) that is copied from the parent 
`ClassTemplateDecl` along with all its members and `CXXMethodDecl`s. That means 
that the member functions with the unsatisfied constraints still appear in the 
AST.

Do you think I should add the constraints checks into the creation of 
`ClassTemplateSpecializationDecl` instead, so we don't create unnecessary 
`CXXMethodDecl`?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120255

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


[PATCH] D120255: [Concepts] Check constraints for explicit template instantiations

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

Thanks for the quick feedback :)

I looked again at the AST and found out that there is a difference between 
instantiated and non-instantiated functions I missed - the instantiated 
functions have actual code AST.
I had some trouble matching the actual generated AST, so I ended up testing 
that indirectly - I call a second 'canary' template function and validate that 
it was instantiated with the correct arguments. Couldn't think of something 
simpler unfortunately :/


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120255

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/AST/constraints-explicit-instantiation.cpp


Index: clang/test/AST/constraints-explicit-instantiation.cpp
===
--- /dev/null
+++ clang/test/AST/constraints-explicit-instantiation.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++20 -ast-dump %s | FileCheck %s
+
+namespace PR46029 {
+
+template 
+void canary1();
+template 
+void canary2();
+
+template 
+struct A {
+  void f() requires(N == 1) {
+static_assert(N == 1);
+canary1();
+  }
+  void f() requires(N == 2) {
+static_assert(N == 2);
+canary2();
+  }
+};
+
+// This checks that `canary1<1>` and `canaray2<2>` are instantiated, thus
+// indirectly validating that the correct candidates of `A::f` were really
+// instantiated each time. 
+// The `static_assert`s validate we don't instantiate wrong candidates.
+
+// CHECK:{{.*}}FunctionTemplateDecl {{.*}} canary1
+// CHECK:  {{.*}}TemplateArgument integral
+// CHECK-SAME: {{1$}}
+template struct A<1>;
+
+// CHECK:  {{.*}}FunctionTemplateDecl {{.*}} canary2
+// CHECK:  {{.*}}TemplateArgument integral
+// CHECK-SAME: {{2$}}
+template struct A<2>;
+
+template struct A<3>;
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3230,6 +3230,14 @@
   if (FunctionDecl *Pattern =
   Function->getInstantiatedFromMemberFunction()) {
 
+if (Function->getTrailingRequiresClause()) {
+  ConstraintSatisfaction Satisfaction;
+  if (CheckFunctionConstraints(Function, Satisfaction) ||
+  !Satisfaction.IsSatisfied) {
+continue;
+  }
+}
+
 if (Function->hasAttr())
   continue;
 


Index: clang/test/AST/constraints-explicit-instantiation.cpp
===
--- /dev/null
+++ clang/test/AST/constraints-explicit-instantiation.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++20 -ast-dump %s | FileCheck %s
+
+namespace PR46029 {
+
+template 
+void canary1();
+template 
+void canary2();
+
+template 
+struct A {
+  void f() requires(N == 1) {
+static_assert(N == 1);
+canary1();
+  }
+  void f() requires(N == 2) {
+static_assert(N == 2);
+canary2();
+  }
+};
+
+// This checks that `canary1<1>` and `canaray2<2>` are instantiated, thus
+// indirectly validating that the correct candidates of `A::f` were really
+// instantiated each time. 
+// The `static_assert`s validate we don't instantiate wrong candidates.
+
+// CHECK:{{.*}}FunctionTemplateDecl {{.*}} canary1
+// CHECK:  {{.*}}TemplateArgument integral
+// CHECK-SAME: {{1$}}
+template struct A<1>;
+
+// CHECK:  {{.*}}FunctionTemplateDecl {{.*}} canary2
+// CHECK:  {{.*}}TemplateArgument integral
+// CHECK-SAME: {{2$}}
+template struct A<2>;
+
+template struct A<3>;
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3230,6 +3230,14 @@
   if (FunctionDecl *Pattern =
   Function->getInstantiatedFromMemberFunction()) {
 
+if (Function->getTrailingRequiresClause()) {
+  ConstraintSatisfaction Satisfaction;
+  if (CheckFunctionConstraints(Function, Satisfaction) ||
+  !Satisfaction.IsSatisfied) {
+continue;
+  }
+}
+
 if (Function->hasAttr())
   continue;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D120255: [Concepts] Check constraints for explicit template instantiations

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

In D120255#3357007 , @erichkeane 
wrote:

> Do you have push rights, or do you need someone to push for you?  If you need 
> someone to push for you, please post the name and email address you'd like 
> the commit under.

Thanks a lot! I don't have push rights, so please push this with Roy Jacobson 

(not a typo, the email has different spelling)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120255

___
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 ();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does 
not satisfy 'same_as'}}
+same_as auto  = f();
+same_as auto & = 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  = f(); // expected-error {{deduced type 'const 
int' does not satisfy 'same_as'}}
+same_as auto & = 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 ();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto  = f();
+same_as auto & = 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  = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto & = 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,

[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 ();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto  = f();
+same_as auto & = 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  = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto & = f();
+
+template 
+concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
+
+int **const ();
+
+C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto ** = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **& = 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] 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 ();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto  = f();
+same_as auto & = 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  = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto & = f();
+
+template 
+concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
+
+int **const ();
+
+C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto ** = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **& = 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 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 ();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto  = f();
+same_as auto & = 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  = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto & = f();
+
+template 
+concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
+
+int **const ();
+
+C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto ** = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **& = 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 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 ();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does 
not satisfy 'same_as'}}
+same_as auto  = f();
+same_as auto & = 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  = f(); // expected-error {{deduced type 'const 
int' does not satisfy 'same_as'}}
+same_as auto & = 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() {
-return 

[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 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 ();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does not satisfy 'same_as'}}
+same_as auto  = f();
+same_as auto & = 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  = f(); // expected-error {{deduced type 'const int' does not satisfy 'same_as'}}
+same_as auto & = f();
+
+template 
+concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
+
+int **const ();
+
+C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto ** = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
+C auto **& = 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
 ^^^
___
cfe-commits 

[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 ();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does 
not satisfy 'same_as'}}
+same_as auto  = f();
+same_as auto & = 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  = f(); // expected-error {{deduced type 'const 
int' does not satisfy 'same_as'}}
+same_as auto & = 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 'void' does 

[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 ) {} // 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 

[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 ) {} // 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 = 

[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 ) {} // 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 

[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 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 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 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 ) {} // 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) {
+  

[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 ) {} // 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 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 ) {} // 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 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-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 ) {} // 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 

[PATCH] D150075: Fix PR#62594 : static lambda call operator is not convertible to function pointer on win32

2023-09-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

@shafik @aaron.ballman does any of you want to commandeer this diff? seems 
simple enough of a change


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D150075

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


[PATCH] D154893: [Clang] Fix some triviality computations

2023-09-15 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D154893#4646405 , @cor3ntin wrote:

> @royjacobson ^

I did not have a lot of time for Clang the last few months unfortunately. I 
might take a look at this again next month when I'll have a bit more time.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154893

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


[PATCH] D154893: [Clang] Fix some triviality computations

2023-10-08 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

I, uh, got preoccupied by some recent events. Don't think I'll have the time 
for this unfortunately.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154893

___
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
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-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 ) {} // 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 

[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 ) {} // 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 

[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 ) {} // 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] D126194: [Concepts] Implement overload resolution for destructors (P0848)

2022-05-30 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson planned changes to this revision.
royjacobson added inline comments.



Comment at: clang/lib/AST/DeclCXX.cpp:1901
+  for (auto* Decl : R) {
+auto* DD = dyn_cast(Decl);
+if (DD && DD->isEligibleOrSelected())

erichkeane wrote:
> What cases happen when the lookup for a destructor name ends up not being a 
> destructor on a RecordDecl type?  I guess I could see this happening with a 
> pseudo-destructor, but that isn't a class type.
> 
> 
It's a bit silly, but it's because we can have template destructors that we 
added to the AST even though they're invalid (it ends up as a 
FunctionTemplateDecl).

I noticed it because of SemaTemplate/destructor-template.cpp



Comment at: clang/lib/Sema/SemaDecl.cpp:17841
+  if (CXXRecord && !CXXRecord->isDependentType())
+ComputeSelectedDestructor(*this, CXXRecord);
+

erichkeane wrote:
> How does all of this play with the 'defaulted destructor is constexpr' stuff? 
>  We end up storing facts like that, destructor 
> triviality/irrelevance/defaulted-and-constexpr/deleted/etc as a bit in the 
> Decl, rather than calculating it.  Can this feature (Allowing overloading) 
> cause those to be inaccurate?
> 
> That is, could we do something like use a requires clause to select between a 
> trivial, irrelevant, and constexpr destructor? Do we need to make sure we 
> update those too?  I would expect that the destructor here would need to 
> store its OWN trivaility/relevance/constexpr/etc here, so we can then update 
> those flags on the type once it is selected.
> 
You're right, I also found `canPassInRegisters` that will need to be adjusted a 
bit so it seems I need to write some codegen tests to make sure this gets the 
ABI correctly.

I won't have much time in the coming month, I hope to get to it by the start of 
July (but if someone wants to pick this up in the meantime feel free to do so).


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 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] 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  = 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  : 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  : 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 

[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  = 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  : 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  : 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

[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 

[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 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 

[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

2022-06-21 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added subscribers: thakis, rsmith.
royjacobson added a comment.

In D127593#3598234 , @sberg wrote:

> In general, there's still a handful of `__has_trivial_*` calls across 
> Abseil's recent master branch `absl/meta/type_traits.h`.

Breaking abseil seems pretty bad indeed :/ @rsmith do you think we should 
revert this?
Pinging @thakis as well for chrome.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

___
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] 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-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 

[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 

[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 

[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-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: 

[PATCH] D127487: [Sema] Fix assertion failure when instantiating requires expression

2022-06-10 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/lib/Sema/SemaConcept.cpp:352
+  [this](const Expr *AtomicExpr) -> ExprResult {
+// We only do this to immitate lvalue-to-rvalue conversion.
+return PerformContextuallyConvertToBool(const_cast(AtomicExpr));

erichkeane wrote:
> ilya-biryukov wrote:
> > erichkeane wrote:
> > > Can you explain this more?  How does this work, and why don't we do that 
> > > directly instead?
> > That's entangled with `calculateConstraintSatisfaction`. I actually tried 
> > to do it directly, but before passing expressions to this function 
> > `calculateConstraintSatisfaction` calls `IgnoreParenImpCasts()`, which 
> > strips away the lvalue-to-rvalue conversion.
> > And we need this conversion so that the evaluation that runs after this 
> > callback returns actually produces an r-value.
> > 
> > Note that the other call to `calculateConstraintSatisfaction` also calls 
> > `PerformContextuallyConvertToBool` after doing template substitution into 
> > the constraint expression.
> > 
> > I don't have full context on why it's the way it is, maybe there is a more 
> > fundamental change that helps with both cases.
> Hmm... my understanding is we DO need these to be a boolean expression 
> eventually, since we have to test them as a bool, so that is why the other 
> attempts the converesion.  If you think of any generalizations of this, it 
> would be appreciated, I'll think it through as well.
Note we already have a related bug about this 
https://github.com/llvm/llvm-project/issues/54524


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127487

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


[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

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

I don't think the OpenMP tests are failing because of this PR, they are a bit 
flaky sometimes.

@erichkeane - Since we haven't branched clang15 yet, I think it's Ok not to add 
the Ver15 value to the ABI options?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

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


[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

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

This is great, thanks for the changes! I added two follow-up inline comments.

Another two other small details: Please add documentation about this to 
LangOptions.h (We try to document there the changes for each ABI version), and 
please add a release note about this change (in clang/docs/ReleaseNotes.rst). 
The "ABI Changes in Clang" section seems appropriate.

Do you have LLVM commit access? If not, I can commit it for you - let me know 
the name+email you want the commit to be under in that case.




Comment at: clang/lib/Sema/SemaDeclCXX.cpp:9778
+
+const bool ClangABICompat14 = Context.getLangOpts().getClangABICompat() <=
+  LangOptions::ClangABI::Ver14;

Please add a comment here about the defect report and what the ClangABICompat14 
is about.



Comment at: clang/test/CXX/special/class.copy/p12-0x.cpp:31
 };
-using _ = not_trivially_copyable;
 

Could you add a test that we use the previous behavior (for this and for 
trivially assignable) when clang-abi-compat=14 is set? Either a new test 
specifically for this behavior, or you can use the `CLANG_ABI_COMPAT` macro and 
run the same test with the flag.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

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


[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

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

In D127593#3585073 , @erichkeane 
wrote:

> The OMP failures are still there though, which is a touch concerning.

Yeah, I rerun the CI and it still fails. I couldn't reproduce the failures 
locally, though, and the CI logs don't seem to contain any actual problem. I'm 
not sure what to do from here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

___
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-06-18 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 rG21eb1af469c3: [Concepts] Implement overload resolution for 
destructors (P0848) (authored by royjacobson).

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/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-decl.cpp
  clang/test/AST/overloaded-destructors.cpp
  clang/test/CXX/class/class.dtor/p4.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp
  clang/test/SemaTemplate/destructor-template.cpp

Index: clang/test/SemaTemplate/destructor-template.cpp
===
--- clang/test/SemaTemplate/destructor-template.cpp
+++ clang/test/SemaTemplate/destructor-template.cpp
@@ -98,7 +98,7 @@
   template 
   ~S(); // expected-error{{destructor cannot be declared as a template}}
 };
-struct T : S {// expected-note{{destructor of 'T' is implicitly deleted because base class 'PR38671::S' has no destructor}}
-  ~T() = default; // expected-warning{{explicitly defaulted destructor is implicitly deleted}}
+struct T : S {
+  ~T() = default;
 };
 } // namespace PR38671
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,77 @@
+// 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}}
+};
+
+// FIXME: We should probably make it illegal to mix virtual and non-virtual methods
+// this way. See CWG2488 and some discussion in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105699.
+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 &) = 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; // 

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

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

Update the PR to now handle triviality, which turned out to require a different 
approach.
On the bright side it is now easier to see how to implemenet the rest of P0848.

Added an AST dump test that checks the bitfields of structs and some derived 
traits.

Also fixed the OpenCL test error - their destructor model is quite incompatible 
with clang
and already broken in some ways, so I tried my best to continue the current 
behaviour.


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/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-decl.cpp
  clang/test/AST/overloaded-destructors.cpp
  clang/test/CXX/class/class.dtor/p4.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp
  clang/test/SemaTemplate/destructor-template.cpp

Index: clang/test/SemaTemplate/destructor-template.cpp
===
--- clang/test/SemaTemplate/destructor-template.cpp
+++ clang/test/SemaTemplate/destructor-template.cpp
@@ -98,7 +98,7 @@
   template 
   ~S(); // expected-error{{destructor cannot be declared as a template}}
 };
-struct T : S {// expected-note{{destructor of 'T' is implicitly deleted because base class 'PR38671::S' has no destructor}}
-  ~T() = default; // expected-warning{{explicitly defaulted destructor is implicitly deleted}}
+struct T : S {
+  ~T() = default;
 };
 } // namespace PR38671
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,77 @@
+// 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}}
+};
+
+// FIXME: We should probably make it illegal to mix virtual and non-virtual methods
+// this way. See CWG2488 and some discussion in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105699.
+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 &) = 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>'}} 

[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

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

I started to get those errors on D126194  as 
well, definitely annoying.

They both do spooky things with type triviality so maybe this is somehow 
related? I'm not sure.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

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


[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

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

The OpenMP tests passed on D127998  (I think 
just randomly?). I'm going to commit this tomorrow morning so I can revert if 
needed.

Javier, thanks again for the patch and for the patience!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

___
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-06-17 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added inline comments.



Comment at: clang/docs/ReleaseNotes.rst:434
 
+- As per "Conditionally Trivial Special Member Functions" (P0848), it is
+  now possible to overload destructors using concepts. Note that the rest

erichkeane wrote:
> Do we have enough to update cxx_status.html?
I think it's still partial enough that I don't want to communicate 'maybe it 
will work'.
I plan to finish the rest in time for Clang 15 so I prefer to just update it 
then :) But I don't feel very strongly about it either way.




Comment at: clang/include/clang/AST/DeclCXX.h:1430
+  /// out of which one will be selected at the end.
+  /// This is called separately from addedMember because it has to be deferred
+  /// to the completion of the class.

erichkeane wrote:
> @aaron.ballman  is messing around with addedMember recently... I wonder if 
> there are OTHER decisions that need to be updated/moved here?
Do you know what papers/DRs he's working on? It seemed like most constexpr 
stuff is done per-function and not per-class.

I don't think there's something else that needs to change but it's definitely 
possible I missed something.. I went through addedMember and tried to remove 
everything destructor related basically.




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] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

2022-06-17 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 rG5ea341d7c4f9: [clang] Fix trivially copyable for copy 
constructor and copy assignment operator (authored by Javier-varez, committed 
by royjacobson).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

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

Index: clang/www/cxx_dr_status.html
===
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -12840,7 +12840,7 @@
 https://wg21.link/cwg2171;>2171
 CD4
 Triviality of copy constructor with less-qualified parameter
-Unknown
+Clang 15
   
   
 https://wg21.link/cwg2172;>2172
Index: clang/test/CXX/special/class.copy/p25-0x.cpp
===
--- clang/test/CXX/special/class.copy/p25-0x.cpp
+++ clang/test/CXX/special/class.copy/p25-0x.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++11 -verify %s -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14
 
 // expected-no-diagnostics
 
@@ -31,7 +32,30 @@
 struct NonConstCopy {
   NonConstCopy =(NonConstCopy &) = default;
 };
+#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 14
+// Up until (and including) Clang 14, non-const copy assignment operators were not trivial because
+// of dr2171
 using _ = not_trivially_assignable;
+#else
+// In the latest Clang version, all defaulted assignment operators are trivial, even if non-const,
+// because dr2171 is fixed
+static_assert(__has_trivial_assign(NonConstCopy), "");
+static_assert(__is_trivially_assignable(NonConstCopy &, NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, const NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy &&), "");
+static_assert(__is_trivially_assignable(NonConstCopy &&, NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, const NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy &&), "");
+
+struct DefaultedSpecialMembers {
+  DefaultedSpecialMembers =(const DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers =(DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers =(DefaultedSpecialMembers &&) = default;
+};
+using _ = trivially_assignable;
+#endif
 
 // class X has no virtual functions
 struct VFn {
Index: clang/test/CXX/special/class.copy/p12-0x.cpp
===
--- clang/test/CXX/special/class.copy/p12-0x.cpp
+++ clang/test/CXX/special/class.copy/p12-0x.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s -Wno-defaulted-function-deleted
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-defaulted-function-deleted -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14
 
 // expected-no-diagnostics
 
@@ -28,7 +29,25 @@
 struct NonConstCopy {
   NonConstCopy(NonConstCopy &) = default;
 };
+#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 14
+// Up until (and including) Clang 14, non-const copy constructors were not trivial because of dr2171
 using _ = not_trivially_copyable;
+#else
+// In the latest Clang version, all defaulted constructors are trivial, even if non-const, because
+// dr2171 is fixed.
+static_assert(__has_trivial_copy(NonConstCopy), "");
+static_assert(__is_trivially_constructible(NonConstCopy, NonConstCopy &), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, const NonConstCopy &), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy &&), "");
+
+struct DefaultedSpecialMembers {
+  DefaultedSpecialMembers(const DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers(DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers(DefaultedSpecialMembers &&) = default;
+};
+using _ = trivially_copyable;
+#endif
 
 // class X has no virtual functions
 struct VFn {
Index: clang/test/CXX/drs/dr21xx.cpp
===
--- clang/test/CXX/drs/dr21xx.cpp
+++ clang/test/CXX/drs/dr21xx.cpp
@@ -140,6 +140,33 @@
 #endif
 }
 
+namespace dr2171 { // dr2171: 15
+#if __cplusplus >= 201103L
+
+struct NonConstCopy {
+  NonConstCopy(NonConstCopy &) = default;
+  NonConstCopy =(NonConstCopy 

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

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

Fix the AST test on windows and rebase on HEAD.


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/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-decl.cpp
  clang/test/AST/overloaded-destructors.cpp
  clang/test/CXX/class/class.dtor/p4.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp
  clang/test/SemaTemplate/destructor-template.cpp

Index: clang/test/SemaTemplate/destructor-template.cpp
===
--- clang/test/SemaTemplate/destructor-template.cpp
+++ clang/test/SemaTemplate/destructor-template.cpp
@@ -98,7 +98,7 @@
   template 
   ~S(); // expected-error{{destructor cannot be declared as a template}}
 };
-struct T : S {// expected-note{{destructor of 'T' is implicitly deleted because base class 'PR38671::S' has no destructor}}
-  ~T() = default; // expected-warning{{explicitly defaulted destructor is implicitly deleted}}
+struct T : S {
+  ~T() = default;
 };
 } // namespace PR38671
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,77 @@
+// 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}}
+};
+
+// FIXME: We should probably make it illegal to mix virtual and non-virtual methods
+// this way. See CWG2488 and some discussion in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105699.
+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 &) = 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; 

[PATCH] D127998: [CI test] D127593

2022-06-16 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 projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.

Testing D127593  by Javier varez to see if 
the CI failures are random or not


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D127998

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

Index: clang/www/cxx_dr_status.html
===
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -12840,7 +12840,7 @@
 https://wg21.link/cwg2171;>2171
 CD4
 Triviality of copy constructor with less-qualified parameter
-Unknown
+Clang 15
   
   
 https://wg21.link/cwg2172;>2172
Index: clang/test/CXX/special/class.copy/p25-0x.cpp
===
--- clang/test/CXX/special/class.copy/p25-0x.cpp
+++ clang/test/CXX/special/class.copy/p25-0x.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++11 -verify %s -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14
 
 // expected-no-diagnostics
 
@@ -31,7 +32,30 @@
 struct NonConstCopy {
   NonConstCopy =(NonConstCopy &) = default;
 };
+#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 14
+// Up until (and including) Clang 14, non-const copy assignment operators were not trivial because
+// of dr2171
 using _ = not_trivially_assignable;
+#else
+// In the latest Clang version, all defaulted assignment operators are trivial, even if non-const,
+// because dr2171 is fixed
+static_assert(__has_trivial_assign(NonConstCopy), "");
+static_assert(__is_trivially_assignable(NonConstCopy &, NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, const NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy &&), "");
+static_assert(__is_trivially_assignable(NonConstCopy &&, NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, const NonConstCopy &), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy), "");
+static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy &&), "");
+
+struct DefaultedSpecialMembers {
+  DefaultedSpecialMembers =(const DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers =(DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers =(DefaultedSpecialMembers &&) = default;
+};
+using _ = trivially_assignable;
+#endif
 
 // class X has no virtual functions
 struct VFn {
Index: clang/test/CXX/special/class.copy/p12-0x.cpp
===
--- clang/test/CXX/special/class.copy/p12-0x.cpp
+++ clang/test/CXX/special/class.copy/p12-0x.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s -Wno-defaulted-function-deleted
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-defaulted-function-deleted -fclang-abi-compat=14 -DCLANG_ABI_COMPAT=14
 
 // expected-no-diagnostics
 
@@ -28,7 +29,25 @@
 struct NonConstCopy {
   NonConstCopy(NonConstCopy &) = default;
 };
+#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 14
+// Up until (and including) Clang 14, non-const copy constructors were not trivial because of dr2171
 using _ = not_trivially_copyable;
+#else
+// In the latest Clang version, all defaulted constructors are trivial, even if non-const, because
+// dr2171 is fixed.
+static_assert(__has_trivial_copy(NonConstCopy), "");
+static_assert(__is_trivially_constructible(NonConstCopy, NonConstCopy &), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, const NonConstCopy &), "");
+static_assert(!__is_trivially_constructible(NonConstCopy, NonConstCopy &&), "");
+
+struct DefaultedSpecialMembers {
+  DefaultedSpecialMembers(const DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers(DefaultedSpecialMembers &) = default;
+  DefaultedSpecialMembers(DefaultedSpecialMembers &&) = default;
+};
+using _ = trivially_copyable;
+#endif
 
 // class X has no virtual functions
 struct VFn {
Index: clang/test/CXX/drs/dr21xx.cpp
===
--- clang/test/CXX/drs/dr21xx.cpp
+++ clang/test/CXX/drs/dr21xx.cpp
@@ -140,6 +140,33 @@
 #endif
 }
 
+namespace dr2171 { // dr2171: 15
+#if __cplusplus >= 201103L
+
+struct NonConstCopy {
+  NonConstCopy(NonConstCopy &) = default;
+  NonConstCopy =(NonConstCopy &) = default;
+};
+

[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

2022-06-12 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson requested changes to this revision.
royjacobson added a reviewer: clang-language-wg.
royjacobson added a comment.
This revision now requires changes to proceed.

Hi Javier, thank you for submitting this patch!

As far as I could tell, this patch implements the CWG2171 defect report from 
2016: https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2171. That 
means that you'll have to add a test inside clang/test/CXX/drs/dr21xx.cpp to 
make sure it shows on the DRs status page.

This change is also a large ABI break, which means it has to be considered 
carefully. I think the best approach here would be to revert to the previous 
behavior when the -fclang-abi-compat flag is used for clang <= 14, but I'm not 
sure about this. I would like the approval of someone with more ABI experience 
here.

The code itself and the tests look good! If you'll need help with the changes I 
mentioned please let me know.




Comment at: clang/lib/Sema/SemaDeclCXX.cpp:9786-9789
+if (RT && ((RT->getPointeeType().getCVRQualifiers() & Qualifiers::Const) ==
+   Qualifiers::Const)) {
+  ConstArg = true;
+}

I think this should work instead? No need to check for RT since we already 
returned if !RT.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

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


[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

2022-06-14 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.

Thank you! LGTM. I see the CI still has those OpenMP failures - could you try 
to rebase on main to get it green?

@erichkeane is this good to go? Should I ping some ABI people about this?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

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


[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

2022-06-20 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D127593#3596601 , @sberg wrote:

> Is it intended that a deleted copy assignment op as in `struct S { void 
> operator =(S &) = delete; };` (though, somewhat oddly, not in `struct S { 
> void operator =(S) = delete; };`) is now marked as trivial?
>
> I think that's the root cause why a build of PDFium with clang-cl against the 
> MSVC standard library started to fail for me now, effectively complaining 
> that `__is_trivially_assignable(std::pair &, std::pair 
> const &)` is false (as expected) while 
> `__has_trivial_assign(std::pair)` is (unexpectedly) true.

I don't see it on godbolt trunk: https://godbolt.org/z/KPfxWqnhd.
Did you mean other traits maybe?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

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


[PATCH] D127593: [clang] Fix trivially copyable for copy constructor and copy assignment operator

2022-06-21 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson added a comment.

In D127593#3597374 , @sberg wrote:

> You'd only see it when compiling with Clang against MSVC's ``, where 
> `std::pair` has a deleted copy assignment op (something I approximated with 
> the `struct S` above).  https://godbolt.org/z/bbEqvosvP shows how the 
> behavior changed in Clang trunk. (Interestingly, the behavior is different 
> between MSVC and GCC, and Clang now changed from matching the MSVC behavior 
> to matching the GCC one.)

I've done some more lookup, and I believe the current behavior is correct.
The reasoning is that the behavior in regards to deleted functions in 
`__has_trivial_assign` is pretty old and is documented here: 
https://github.com/llvm/llvm-project/issues/33063. As Richard writes there (and 
as documented in 
https://clang.llvm.org/docs/LanguageExtensions.html#type-trait-primitives) 
those type traits are deprecated exactly because they exhibit this weird 
behavior.

Is it possible to check how often PDFium uses `__has_trivial_assign`? Depending 
on how large this breakage is we might need to revert and proceed more 
carefully..


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127593

___
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 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 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  : 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  : 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 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  : 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  : 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{{destructor 

[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] 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>));

[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 

[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-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: 

[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] 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>));

[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>));

[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 Clangs 
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] 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] 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] 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] 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-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>));

[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-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>));

[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


  1   2   3   4   >