mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 08:16:47 +00:00
[Clang] Don't add top-level const qualifiers to captured function types (#118050)
This aligns with the logic in `TreeTransform::RebuildQualifiedType()` where we refrain from adding const qualifiers to function types. Previously, we seemed to overlook this edge case when copy-capturing a variable that is of function type within a const-qualified lambda. This issue also reveals other related problems as in incorrect type printout and a suspicious implementation in DeduceTemplateArguments. I decide to leave them in follow-up work. Fixes #84961
This commit is contained in:
parent
94d6b1cce5
commit
154c7c0bf2
@ -761,6 +761,7 @@ Bug Fixes to C++ Support
|
||||
- Name independent data members were not correctly initialized from default member initializers. (#GH114069)
|
||||
- Fixed expression transformation for ``[[assume(...)]]``, allowing using pack indexing expressions within the
|
||||
assumption if they also occur inside of a dependent lambda. (#GH114787)
|
||||
- Lambdas now capture function types without considering top-level const qualifiers. (#GH84961)
|
||||
- Clang now uses valid deduced type locations when diagnosing functions with trailing return type
|
||||
missing placeholder return type. (#GH78694)
|
||||
- Fixed a bug where bounds of partially expanded pack indexing expressions were checked too early. (#GH116105)
|
||||
|
@ -18431,7 +18431,11 @@ static bool isVariableAlreadyCapturedInScopeInfo(CapturingScopeInfo *CSI,
|
||||
// are mutable in the sense that user can change their value - they are
|
||||
// private instances of the captured declarations.
|
||||
const Capture &Cap = CSI->getCapture(Var);
|
||||
if (Cap.isCopyCapture() &&
|
||||
// C++ [expr.prim.lambda]p10:
|
||||
// The type of such a data member is [...] an lvalue reference to the
|
||||
// referenced function type if the entity is a reference to a function.
|
||||
// [...]
|
||||
if (Cap.isCopyCapture() && !DeclRefType->isFunctionType() &&
|
||||
!(isa<LambdaScopeInfo>(CSI) &&
|
||||
!cast<LambdaScopeInfo>(CSI)->lambdaCaptureShouldBeConst()) &&
|
||||
!(isa<CapturedRegionScopeInfo>(CSI) &&
|
||||
@ -18741,7 +18745,12 @@ static bool captureInLambda(LambdaScopeInfo *LSI, ValueDecl *Var,
|
||||
// parameter-declaration-clause is not followed by mutable.
|
||||
DeclRefType = CaptureType.getNonReferenceType();
|
||||
bool Const = LSI->lambdaCaptureShouldBeConst();
|
||||
if (Const && !CaptureType->isReferenceType())
|
||||
// C++ [expr.prim.lambda]p10:
|
||||
// The type of such a data member is [...] an lvalue reference to the
|
||||
// referenced function type if the entity is a reference to a function.
|
||||
// [...]
|
||||
if (Const && !CaptureType->isReferenceType() &&
|
||||
!DeclRefType->isFunctionType())
|
||||
DeclRefType.addConst();
|
||||
}
|
||||
|
||||
|
@ -335,3 +335,17 @@ constexpr void foo() {
|
||||
}
|
||||
|
||||
} // namespace GH47400
|
||||
|
||||
namespace GH84961 {
|
||||
|
||||
template <typename T> void g(const T &t) {}
|
||||
|
||||
template <typename T> void f(const T &t) {
|
||||
[t] { g(t); }();
|
||||
}
|
||||
|
||||
void h() {
|
||||
f(h);
|
||||
}
|
||||
|
||||
} // namespace GH84961
|
||||
|
Loading…
x
Reference in New Issue
Block a user