[PATCH] D140828: [C++] Implement "Deducing this" (P0847R7)
Corentin Jabot via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 27 14:05:53 PDT 2023
cor3ntin added inline comments.
================
Comment at: clang/include/clang/AST/ASTLambda.h:45
+ return isLambdaCallOperator(DC) &&
+ !cast<CXXMethodDecl>(DC)->getType().isNull() &&
+ !cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction();
----------------
aaron.ballman wrote:
> cor3ntin wrote:
> > erichkeane wrote:
> > > Under what cases does this end up being null? It seems like this condition shouldn't be necessary, and it doesn't seem like we should have a case where we create a method/function without a type set?
> > If you have invalid captures for example, you can end up with no type. (but we do need to create a method because you need to have a context to which attach the captures to)
> This does feel rather unclean, though it may be fine for now. Instead of a null type, I would expect the declaration to be marked as invalid (and perhaps for callers to avoid calling `isLambdaCallWithImplicitObjectParameter()` on an invalid declaration so that we can turn the predicate into an assertion).
>
> Let's add a FIXME for now?
I added a fixme.
I spent some time thinking about alternatives but i can't think of something obvious at the moment.
Making a lambda being parsed invalid does not seem ideal either
================
Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:9378-9381
+ "an explicitly-defaulted %sub{select_special_member_kind}0 cannot "
"have default arguments">;
def err_defaulted_special_member_variadic : Error<
+ "an explicitly-defaulted %sub{select_special_member_kind}0 cannot "
----------------
aaron.ballman wrote:
> aaron.ballman wrote:
> > These changes seem like they're orthogonal to the patch. Should we split them off into their own NFC commit so we can get them out of here?
> These changes can still be split off into their own NFC commit.
Discussed offline, we can keep those
================
Comment at: clang/include/clang/Sema/Sema.h:3775
bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs = true,
- bool ConsiderRequiresClauses = true);
+ bool UseOverrideRules = false);
----------------
aaron.ballman wrote:
> cor3ntin wrote:
> > aaron.ballman wrote:
> > > I think we should add some comments here explaining what `UseOverrideRules` means. The old parameter was kind of mysterious as well, but this one feels even more mysterious to me.
> > Maybe we should document the whole function, but for that I'd need to better understand `UseMemberUsingDeclRules`
> >
> > The other solution might be to have an `IsOverride` function such that both `IsOverride` and `IsOverload` function would dispatch to the same internal function.
> >
> > The other solution might be to have an IsOverride function such that both IsOverride and IsOverload function would dispatch to the same internal function.
>
> I think that's a clean solution.
I added `IsOverride`
================
Comment at: clang/lib/Parse/ParseDecl.cpp:5756
const ParsedTemplateInfo *TemplateInfo) {
- TentativeParsingAction TPA(*this);
-
+ RevertingTentativeParsingAction TPA(*this);
// Parse the C++ scope specifier.
----------------
aaron.ballman wrote:
> aaron.ballman wrote:
> > This is a good NFC cleanup; feel free to land this change separately if you'd like to get it out of this review.
> This can still be split off to make the review shorter for folks.
Discussed offline, we can keep these here
================
Comment at: clang/lib/Sema/SemaOverload.cpp:911-915
if (X->getNumParams() != Y->getNumParams())
return false;
for (unsigned I = 0; I < X->getNumParams(); ++I)
if (!Ctx.hasSameUnqualifiedType(X->getParamDecl(I)->getType(),
Y->getParamDecl(I)->getType()))
----------------
cor3ntin wrote:
> cor3ntin wrote:
> > aaron.ballman wrote:
> > > Do we need changes here?
> > Yes, although I need to figure out a test
> We need changes.
> Which changes is not obvious to me. https://lists.isocpp.org/core/2023/08/14711.php
Added link to https://cplusplus.github.io/CWG/issues/2797.html
================
Comment at: clang/lib/Sema/SemaOverload.cpp:6254-6258
+ if (Obj->Classify(S.getASTContext()).isPRValue()) {
+ Obj = S.CreateMaterializeTemporaryExpr(
+ ObjType, Obj,
+ !Fun->getParamDecl(0)->getType()->isRValueReferenceType());
+ }
----------------
aaron.ballman wrote:
> aaron.ballman wrote:
> > Do we have test coverage for this situation?
> Still wondering about test coverage for this bit.
What specific test would you like to see?
================
Comment at: clang/lib/Sema/SemaOverload.cpp:1299-1300
+
+ // We do not allow overloading based off of '__restrict'.
+ Q.removeRestrict();
+
----------------
aaron.ballman wrote:
> cor3ntin wrote:
> > aaron.ballman wrote:
> > > Just restrict? So `_Nonnull` is fine?
> > Good question. This was pre-existing code though. I'll think about it more
> Any new thoughts on this?
Nope, I will add a fixme
================
Comment at: clang/test/CXX/drs/dr25xx.cpp:104-106
+struct D : B {
+ void f(this D&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
+};
----------------
cor3ntin wrote:
> aaron.ballman wrote:
> > I'd like to see two other tests:
> > ```
> > struct D2 : B {
> > void f(this B&); // expected-error {{an explicit object parameter cannot appear in a virtual function}}
> > };
> > ```
> > to demonstrate we also catch it when naming the base class instead of the derived class. And:
> > ```
> > struct T {};
> > struct D3 : B {
> > void f(this T&); // Okay, not an override
> > };
> >
> > void func() {
> > T t;
> > t.f(); // Verify this calls D3::f() and not B::f(), probably as a codegen test
> > }
> > ```
> I might need help with the codegen test setup, it's sill my nemesis. Or we can put it somewhere else
Added the first test. the second test is still an override. I guess i can still add it but it is IF
================
Comment at: clang/test/SemaCXX/cxx2b-deducing-this.cpp:192
+ f(); // expected-error{{call to non-static member function without an object argument}}
+ f(Over_Call_Func_Example{}); // expected-error{{call to non-static member function without an object argument}}
+ Over_Call_Func_Example{}.f(); // ok
----------------
aaron.ballman wrote:
> cor3ntin wrote:
> > aaron.ballman wrote:
> > > Errr, this diagnostic seems likely to be hard for users to act on: this non-static member function has an object argument! And it's even the right type!
> > >
> > > If the model for the feature is "these are just static functions with funky lookup rules", I kind of wonder if this should be accepted instead of rejected. But if it needs to be rejected, I think we should have a better diagnostic, perhaps along the lines of "a call to an explicit object member function cannot specify the explicit object argument" with a fix-it to remove that argument. WDYT?
> > UGH, phab is confused, I'm no longer sure which diag you are concerned about...
> ```
> static void h() {
> f(); // expected-error{{call to non-static member function without an object argument}}
> f(Over_Call_Func_Example{}); // expected-error{{call to non-static member function without an object argument}}
> Over_Call_Func_Example{}.f(); // ok
> }
> ```
> from around line 214 in the latest patch; the second error seems hard to understand because there is an object argument being passed, it's just not the form allowed.
You have a rewording suggestion?
================
Comment at: clang/test/SemaCXX/cxx2b-deducing-this.cpp:29-30
+ S(this auto); // expected-error {{an explicit object parameter cannot appear in a constructor}}
+ ~S(this S) {} // expected-error {{an explicit object parameter cannot appear in a destructor}} \
+ // expected-error {{destructor cannot have any parameters}}
+};
----------------
aaron.ballman wrote:
> cor3ntin wrote:
> > aaron.ballman wrote:
> > > If possible, it would be nicer if we only issued one warning as the root cause is the same for both diagnostics.
> > Should we simply remove the newly added diagnostic then?
> I think the new diagnostic is helpful; I'm more wondering if we can emit just the new diagnostic and skip `destructor cannot have any parameters` if we already said it can't have an explicit object parameter?
FYI i remember looking at that and i think it was non trivial, I'd rather punt it
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D140828/new/
https://reviews.llvm.org/D140828
More information about the llvm-commits
mailing list