[clang] [Clang] Don't add top-level const qualifiers to captured function types (PR #118050)

2024-12-03 Thread via cfe-commits

https://github.com/cor3ntin approved this pull request.


https://github.com/llvm/llvm-project/pull/118050
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Don't add top-level const qualifiers to captured function types (PR #118050)

2024-12-03 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/118050

>From 92b8a28eb7664b3cac6a8039834b099b010af3ed Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Fri, 29 Nov 2024 13:19:30 +0800
Subject: [PATCH 1/2] [Clang] Don't add top-level const qualifiers to captured
 function types

---
 clang/docs/ReleaseNotes.rst|  1 +
 clang/lib/Sema/SemaExpr.cpp| 11 +--
 .../test/SemaCXX/lambda-capture-type-deduction.cpp | 14 ++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8bd06fadfdc984..553856f3060bc1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -712,6 +712,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)
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 6c7472ce92703b..04b713a91dedfa 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18479,7 +18479,10 @@ 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++ [dcl.fct]p7:
+//   [When] adding cv-qualifications on top of the function type [...] the
+//   cv-qualifiers are ignored.
+if (Cap.isCopyCapture() && !DeclRefType->isFunctionType() &&
 !(isa(CSI) &&
   !cast(CSI)->lambdaCaptureShouldBeConst()) &&
 !(isa(CSI) &&
@@ -18789,7 +18792,11 @@ 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++ [dcl.fct]p7:
+//   [When] adding cv-qualifications on top of the function type [...] the
+//   cv-qualifiers are ignored.
+if (Const && !CaptureType->isReferenceType() &&
+!DeclRefType->isFunctionType())
   DeclRefType.addConst();
   }
 
diff --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp 
b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
index a86f3018989927..ba7ab34f943be1 100644
--- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -319,3 +319,17 @@ constexpr void foo() {
 }
 
 } // namespace GH47400
+
+namespace GH84961 {
+
+template  void g(const T &t) {}
+
+template  void f(const T &t) {
+  [t] { g(t); }();
+}
+
+void h() {
+  f(h);
+}
+
+} // namespace GH84961

>From 1ce64b5c1339a1ee22cf6df47a3ba3cb1ebf4bfb Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Wed, 4 Dec 2024 13:30:16 +0800
Subject: [PATCH 2/2] Refer to [expr.prim.lambda]p10

---
 clang/lib/Sema/SemaExpr.cpp | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 04b713a91dedfa..47612ef2effb95 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18479,9 +18479,10 @@ 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);
-// C++ [dcl.fct]p7:
-//   [When] adding cv-qualifications on top of the function type [...] the
-//   cv-qualifiers are ignored.
+// 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(CSI) &&
   !cast(CSI)->lambdaCaptureShouldBeConst()) &&
@@ -18792,9 +18793,10 @@ static bool captureInLambda(LambdaScopeInfo *LSI, 
ValueDecl *Var,
 //   parameter-declaration-clause is not followed by mutable.
 DeclRefType = CaptureType.getNonReferenceType();
 bool Const = LSI->lambdaCaptureShouldBeConst();
-// C++ [dcl.fct]p7:
-//   [When] adding cv-qualifications on top of the function type [...] the
-//   cv-qualifiers are ignored.
+// C++ [expr.prim.lambda]p10:
+//   The type of such a data member is [...]

[clang] [Clang] Don't add top-level const qualifiers to captured function types (PR #118050)

2024-12-03 Thread Younan Zhang via cfe-commits


@@ -18789,7 +18792,11 @@ 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++ [dcl.fct]p7:
+//   [When] adding cv-qualifications on top of the function type [...] the
+//   cv-qualifiers are ignored.

zyn0217 wrote:

Thanks, and sorry for missing this review

https://github.com/llvm/llvm-project/pull/118050
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Don't add top-level const qualifiers to captured function types (PR #118050)

2024-12-02 Thread via cfe-commits


@@ -18789,7 +18792,11 @@ 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++ [dcl.fct]p7:
+//   [When] adding cv-qualifications on top of the function type [...] the
+//   cv-qualifiers are ignored.

cor3ntin wrote:

I think the more relevant wording is 
https://eel.is/c++draft/expr.prim.lambda#capture-10.sentence-4


https://github.com/llvm/llvm-project/pull/118050
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Don't add top-level const qualifiers to captured function types (PR #118050)

2024-11-28 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)


Changes

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


---
Full diff: https://github.com/llvm/llvm-project/pull/118050.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+9-2) 
- (modified) clang/test/SemaCXX/lambda-capture-type-deduction.cpp (+14) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8bd06fadfdc984..553856f3060bc1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -712,6 +712,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)
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 6c7472ce92703b..04b713a91dedfa 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18479,7 +18479,10 @@ 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++ [dcl.fct]p7:
+//   [When] adding cv-qualifications on top of the function type [...] the
+//   cv-qualifiers are ignored.
+if (Cap.isCopyCapture() && !DeclRefType->isFunctionType() &&
 !(isa(CSI) &&
   !cast(CSI)->lambdaCaptureShouldBeConst()) &&
 !(isa(CSI) &&
@@ -18789,7 +18792,11 @@ 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++ [dcl.fct]p7:
+//   [When] adding cv-qualifications on top of the function type [...] the
+//   cv-qualifiers are ignored.
+if (Const && !CaptureType->isReferenceType() &&
+!DeclRefType->isFunctionType())
   DeclRefType.addConst();
   }
 
diff --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp 
b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
index a86f3018989927..ba7ab34f943be1 100644
--- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -319,3 +319,17 @@ constexpr void foo() {
 }
 
 } // namespace GH47400
+
+namespace GH84961 {
+
+template  void g(const T &t) {}
+
+template  void f(const T &t) {
+  [t] { g(t); }();
+}
+
+void h() {
+  f(h);
+}
+
+} // namespace GH84961

``




https://github.com/llvm/llvm-project/pull/118050
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Don't add top-level const qualifiers to captured function types (PR #118050)

2024-11-28 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 ready_for_review 
https://github.com/llvm/llvm-project/pull/118050
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Don't add top-level const qualifiers to captured function types (PR #118050)

2024-11-28 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 created 
https://github.com/llvm/llvm-project/pull/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


>From 92b8a28eb7664b3cac6a8039834b099b010af3ed Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Fri, 29 Nov 2024 13:19:30 +0800
Subject: [PATCH] [Clang] Don't add top-level const qualifiers to captured
 function types

---
 clang/docs/ReleaseNotes.rst|  1 +
 clang/lib/Sema/SemaExpr.cpp| 11 +--
 .../test/SemaCXX/lambda-capture-type-deduction.cpp | 14 ++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8bd06fadfdc984..553856f3060bc1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -712,6 +712,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)
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 6c7472ce92703b..04b713a91dedfa 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18479,7 +18479,10 @@ 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++ [dcl.fct]p7:
+//   [When] adding cv-qualifications on top of the function type [...] the
+//   cv-qualifiers are ignored.
+if (Cap.isCopyCapture() && !DeclRefType->isFunctionType() &&
 !(isa(CSI) &&
   !cast(CSI)->lambdaCaptureShouldBeConst()) &&
 !(isa(CSI) &&
@@ -18789,7 +18792,11 @@ 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++ [dcl.fct]p7:
+//   [When] adding cv-qualifications on top of the function type [...] the
+//   cv-qualifiers are ignored.
+if (Const && !CaptureType->isReferenceType() &&
+!DeclRefType->isFunctionType())
   DeclRefType.addConst();
   }
 
diff --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp 
b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
index a86f3018989927..ba7ab34f943be1 100644
--- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -319,3 +319,17 @@ constexpr void foo() {
 }
 
 } // namespace GH47400
+
+namespace GH84961 {
+
+template  void g(const T &t) {}
+
+template  void f(const T &t) {
+  [t] { g(t); }();
+}
+
+void h() {
+  f(h);
+}
+
+} // namespace GH84961

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