[clang] [Clang] [CodeGen] Perform derived-to-base conversion on explicit object parameter in lambda (PR #89828)
John McCall via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 23 19:41:44 PDT 2024
================
@@ -4684,6 +4684,29 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field,
else
LambdaLV = MakeAddrLValue(AddrOfExplicitObject,
D->getType().getNonReferenceType());
+
+ // Make sure we have an lvalue to the lambda itself and not a derived class.
+ auto *ThisTy = D->getType().getNonReferenceType()->getAsCXXRecordDecl();
+ auto *LambdaTy = cast<CXXRecordDecl>(Field->getParent());
+ if (ThisTy != LambdaTy) {
+ CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
+ /*DetectVirtual=*/false);
+
+ [[maybe_unused]] bool Derived = ThisTy->isDerivedFrom(LambdaTy, Paths);
+ assert(Derived && "Type not derived from lambda type?");
----------------
rjmccall wrote:
We can manually resolve between the `operator()`s at the call site with a qualified member name, and the `operator()` should still get called with the original `Overloaded` without any hint about which subobject it was called on.
We could also have `Overloaded` just pick one of its bases to `using` the `operator()` from, but then I suppose someone might argue that the operator ought to pick up on that to decide the base path. (That would be absurd, IMO.)
Example of the first: https://godbolt.org/z/rqvKGfevY
I think you need to open a DR with the committee. It just needs to be ill-formed for a lambda call operator with an explicit `this` parameter to be instantiated such that the `this` parameter has a type with multiple base subobjects of the lambda type. I can't imagine any other resolution short of something absurd like adding an implicit offset parameter, which would then be breaking in other ways.
Please go ahead and diagnose that condition in Sema.
https://github.com/llvm/llvm-project/pull/89828
More information about the cfe-commits
mailing list