Re: r291905 - [Sema] Add warning for unused lambda captures
On Wed, Feb 15, 2017 at 7:42 PM, Richard Smith via cfe-commitswrote: > https://bugs.llvm.org/show_bug.cgi?id=31977 makes the good point that this > is warning on a certain idiomatic use of capture-by-value to extend the > lifetime of an RAII object; consider: > > shared_ptr p = /*...*/; > int *q = >n; > return [=, p] { return *q++; } > > Here, we'll warn that the capture of p is unused, but it's not -- the "use" > is to hold a reference to keep the Foo object alive. > > I'd suggest suppressing the warning for a by-copy capture of a variable with > a non-trivial destructor (this mirrors what we do for -Wunused-variable). Thank you for the compelling example -- I agree, that's a good solution to the issue. ~Aaron > > On 13 January 2017 at 07:01, Malcolm Parsons via cfe-commits > wrote: >> >> Author: malcolm.parsons >> Date: Fri Jan 13 09:01:06 2017 >> New Revision: 291905 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=291905=rev >> Log: >> [Sema] Add warning for unused lambda captures >> >> Summary: >> Warn when a lambda explicitly captures something that is not used in its >> body. >> >> The warning is part of -Wunused and can be enabled with >> -Wunused-lambda-capture. >> >> Reviewers: rsmith, arphaman, jbcoe, aaron.ballman >> >> Subscribers: Quuxplusone, arphaman, cfe-commits >> >> Differential Revision: https://reviews.llvm.org/D28467 >> >> Added: >> cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp >> Modified: >> cfe/trunk/include/clang/Basic/DiagnosticGroups.td >> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> cfe/trunk/include/clang/Sema/ScopeInfo.h >> cfe/trunk/include/clang/Sema/Sema.h >> cfe/trunk/lib/Sema/SemaExpr.cpp >> cfe/trunk/lib/Sema/SemaExprCXX.cpp >> cfe/trunk/lib/Sema/SemaLambda.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp >> cfe/trunk/test/SemaCXX/uninitialized.cpp >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=291905=291904=291905=diff >> >> == >> --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jan 13 09:01:06 >> 2017 >> @@ -480,6 +480,7 @@ def UnusedFunction : DiagGroup<"unused-f >> def UnusedMemberFunction : DiagGroup<"unused-member-function", >> [UnneededMemberFunction]>; >> def UnusedLabel : DiagGroup<"unused-label">; >> +def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">; >> def UnusedParameter : DiagGroup<"unused-parameter">; >> def UnusedResult : DiagGroup<"unused-result">; >> def PotentiallyEvaluatedExpression : >> DiagGroup<"potentially-evaluated-expression">; >> @@ -617,8 +618,9 @@ def Unused : DiagGroup<"unused", >> [UnusedArgument, UnusedFunction, UnusedLabel, >> // UnusedParameter, (matches GCC's behavior) >> // UnusedMemberFunction, (clean-up llvm before >> enabling) >> -UnusedPrivateField, UnusedLocalTypedef, >> -UnusedValue, UnusedVariable, >> UnusedPropertyIvar]>, >> +UnusedPrivateField, UnusedLambdaCapture, >> +UnusedLocalTypedef, UnusedValue, UnusedVariable, >> +UnusedPropertyIvar]>, >> DiagCategory<"Unused Entity Issue">; >> >> // Format settings. >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=291905=291904=291905=diff >> >> == >> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 13 >> 09:01:06 2017 >> @@ -316,6 +316,9 @@ def warn_unneeded_member_function : Warn >>InGroup, DefaultIgnore; >> def warn_unused_private_field: Warning<"private field %0 is not used">, >>InGroup, DefaultIgnore; >> +def warn_unused_lambda_capture: Warning<"lambda capture %0 is not " >> + "%select{used|required to be captured for use in an unevaluated >> context}1">, >> + InGroup, DefaultIgnore; >> >> def warn_parameter_size: Warning< >>"%0 is a large (%1 bytes) pass-by-value argument; " >> >> Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h >> URL: >>
Re: r291905 - [Sema] Add warning for unused lambda captures
https://bugs.llvm.org/show_bug.cgi?id=31977 makes the good point that this is warning on a certain idiomatic use of capture-by-value to extend the lifetime of an RAII object; consider: shared_ptr p = /*...*/; int *q = >n; return [=, p] { return *q++; } Here, we'll warn that the capture of p is unused, but it's not -- the "use" is to hold a reference to keep the Foo object alive. I'd suggest suppressing the warning for a by-copy capture of a variable with a non-trivial destructor (this mirrors what we do for -Wunused-variable). On 13 January 2017 at 07:01, Malcolm Parsons via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: malcolm.parsons > Date: Fri Jan 13 09:01:06 2017 > New Revision: 291905 > > URL: http://llvm.org/viewvc/llvm-project?rev=291905=rev > Log: > [Sema] Add warning for unused lambda captures > > Summary: > Warn when a lambda explicitly captures something that is not used in its > body. > > The warning is part of -Wunused and can be enabled with > -Wunused-lambda-capture. > > Reviewers: rsmith, arphaman, jbcoe, aaron.ballman > > Subscribers: Quuxplusone, arphaman, cfe-commits > > Differential Revision: https://reviews.llvm.org/D28467 > > Added: > cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp > Modified: > cfe/trunk/include/clang/Basic/DiagnosticGroups.td > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/include/clang/Sema/ScopeInfo.h > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/Sema/SemaExpr.cpp > cfe/trunk/lib/Sema/SemaExprCXX.cpp > cfe/trunk/lib/Sema/SemaLambda.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp > cfe/trunk/test/SemaCXX/uninitialized.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Basic/DiagnosticGroups.td?rev=291905=291904=291905=diff > > == > --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jan 13 09:01:06 > 2017 > @@ -480,6 +480,7 @@ def UnusedFunction : DiagGroup<"unused-f > def UnusedMemberFunction : DiagGroup<"unused-member-function", > [UnneededMemberFunction]>; > def UnusedLabel : DiagGroup<"unused-label">; > +def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">; > def UnusedParameter : DiagGroup<"unused-parameter">; > def UnusedResult : DiagGroup<"unused-result">; > def PotentiallyEvaluatedExpression : DiagGroup<"potentially- > evaluated-expression">; > @@ -617,8 +618,9 @@ def Unused : DiagGroup<"unused", > [UnusedArgument, UnusedFunction, UnusedLabel, > // UnusedParameter, (matches GCC's behavior) > // UnusedMemberFunction, (clean-up llvm before > enabling) > -UnusedPrivateField, UnusedLocalTypedef, > -UnusedValue, UnusedVariable, UnusedPropertyIvar]>, > +UnusedPrivateField, UnusedLambdaCapture, > +UnusedLocalTypedef, UnusedValue, UnusedVariable, > +UnusedPropertyIvar]>, > DiagCategory<"Unused Entity Issue">; > > // Format settings. > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/ > DiagnosticSemaKinds.td?rev=291905=291904=291905=diff > > == > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 13 > 09:01:06 2017 > @@ -316,6 +316,9 @@ def warn_unneeded_member_function : Warn >InGroup, DefaultIgnore; > def warn_unused_private_field: Warning<"private field %0 is not used">, >InGroup, DefaultIgnore; > +def warn_unused_lambda_capture: Warning<"lambda capture %0 is not " > + "%select{used|required to be captured for use in an unevaluated > context}1">, > + InGroup, DefaultIgnore; > > def warn_parameter_size: Warning< >"%0 is a large (%1 bytes) pass-by-value argument; " > > Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Sema/ScopeInfo.h?rev=291905=291904=291905=diff > > == > --- cfe/trunk/include/clang/Sema/ScopeInfo.h (original) > +++ cfe/trunk/include/clang/Sema/ScopeInfo.h Fri Jan 13 09:01:06 2017 > @@ -452,6 +452,14 @@ public: > /// non-static data member that would hold the capture.
Re: r291905 - [Sema] Add warning for unused lambda captures
On Mon, Jan 23, 2017 at 5:55 PM, Nico Weberwrote: > On Mon, Jan 23, 2017 at 5:29 PM, Aaron Ballman > wrote: >> >> On Mon, Jan 23, 2017 at 5:00 PM, Nico Weber via cfe-commits >> wrote: >> > On Sun, Jan 22, 2017 at 6:17 AM, Malcolm Parsons >> > >> > wrote: >> >> >> >> On 20 January 2017 at 21:32, Nico Weber wrote: >> >> > This warns about code like >> >> > >> >> > constexpr int foo = 4; >> >> > []() { use(foo); } >> >> > >> >> > That's correct, but removing then makes MSVC complain about this >> >> > code >> >> > like "error C3493: 'foo' cannot be implicitly captured because no >> >> > default >> >> > capture mode has been specified". A workaround is to make foo static >> >> > const >> >> > instead of constexpr. >> >> > >> >> > This seems like an MSVC bug, but it's still a bit annoying that clang >> >> > now >> >> > suggests doing things that won't build in other compilers. Any ideas >> >> > what to >> >> > do about this? >> >> >> >> Should Clang care about the behaviour of other compilers that don't >> >> follow the standard? >> > >> > >> > clang should be a compiler that people like to use. Multi-platform >> > development isn't super uncommon, so trying to give a good experience in >> > that case seems like a good thing to me -- and we've tried to do that in >> > the >> > past pretty hard. It's possible that "do nothing" is the right thing, >> > but >> > "well that other compiler is buggy" seems like a somewhat oversimplified >> > reply. >> >> We generally don't try to be bug-for-bug compatible with other >> compilers unless the bug is sufficiently important (like it is relied >> upon in system headers, for instance). In this case, I think the bug >> in MSVC is annoying, but not the end of the world because it's trivial >> to workaround in a compiler-agnostic way > > > It's easy, but you need to know about it. Say you're working on some project > that uses clang on macOS, gcc on Linux, MSVC on Windows, and you're > developing on Linux. You write some patch, and things work fine on your > machine. You submit your thing, it gets reverted because it triggers this > new warning on mac. Hey, fair enough, looks like a good warning, so you > remove the thing from the capture list and reland. Now you get reverted > _again_ because MSVC does need that thing that clang just told you to > revert. After three such interactions you'll be pretty unhappy, I gather :-) I don't disagree that you'd be unhappy in that circumstance. >> >> Cast foo to void inside the lambda. >> > >> > >> > That's equivalent to disabling the clang warning in those cases (which >> > would >> > be a shame, since the warning is super useful, and it doesn't introduce >> > problems in most cases -- only with local constexprs). Maybe the warning >> > could be split in two, so that it can be toggled separately for >> > constexpr? >> >> While functional, that seems like a lot of work for this case. > > > It's like 4 lines, no? Yes, but no. It's 4 lines that introduce a compiler flag that we have to support forever, even if Microsoft eventually fixes their bug (making the purpose to the compiler flag entirely moot), which is what my concern boils down to. If this was a common problem, then I would think the flag (or some other, heavier fix) might actually be worth having to keep around forever. Since it doesn't really seem to be a common issue, I'm not keen on adding a user-facing compiler flag because of the maintenance burden. ~Aaron > As I said, I'm not sure it's worth it either. As-is, I think larger cross > platform teams must enable this warning for the reason mentioned above. > Requiring this is a bit of a shame since I think it's a great warning, so I > was hoping we could come up with a way so we could use the warning as well. > >> >> However, the downside to the cast to void is that when MSVC does fix >> the bug, the diagnostic remains silenced in the user's source base. >> >> > >> >> >> >> Only capture foo when building with MSVC. >> >> >> >> Stop building with MSVC. >> > >> > >> > This reply like this make me believe you think it was silly to even >> > report >> > this problem. I don't think it's silly, and there's ample precedent in >> > clang >> > to make it work well in the actual world instead of in a world we wished >> > we >> > lived in. >> >> Definitely not silly to report the problem, but at the same time, that >> precedent is usually reserved for things that affect a significant >> portion of users when the issue boils down to a compiler bug in >> another compiler. How common of a problem is this use case? Does it >> crop up in important header files? > > > It's not super common. Ivan, I think you ran into this twice in all of > Chromium? > >> >> >> ~Aaron >> >> > >> >> >> >> Complain to Microsoft. >> > >> > >> > Already done. The reality is that their shipping compiler produces this >> >
Re: r291905 - [Sema] Add warning for unused lambda captures
On Mon, Jan 23, 2017 at 5:29 PM, Aaron Ballmanwrote: > On Mon, Jan 23, 2017 at 5:00 PM, Nico Weber via cfe-commits > wrote: > > On Sun, Jan 22, 2017 at 6:17 AM, Malcolm Parsons < > malcolm.pars...@gmail.com> > > wrote: > >> > >> On 20 January 2017 at 21:32, Nico Weber wrote: > >> > This warns about code like > >> > > >> > constexpr int foo = 4; > >> > []() { use(foo); } > >> > > >> > That's correct, but removing then makes MSVC complain about this > >> > code > >> > like "error C3493: 'foo' cannot be implicitly captured because no > >> > default > >> > capture mode has been specified". A workaround is to make foo static > >> > const > >> > instead of constexpr. > >> > > >> > This seems like an MSVC bug, but it's still a bit annoying that clang > >> > now > >> > suggests doing things that won't build in other compilers. Any ideas > >> > what to > >> > do about this? > >> > >> Should Clang care about the behaviour of other compilers that don't > >> follow the standard? > > > > > > clang should be a compiler that people like to use. Multi-platform > > development isn't super uncommon, so trying to give a good experience in > > that case seems like a good thing to me -- and we've tried to do that in > the > > past pretty hard. It's possible that "do nothing" is the right thing, but > > "well that other compiler is buggy" seems like a somewhat oversimplified > > reply. > > We generally don't try to be bug-for-bug compatible with other > compilers unless the bug is sufficiently important (like it is relied > upon in system headers, for instance). In this case, I think the bug > in MSVC is annoying, but not the end of the world because it's trivial > to workaround in a compiler-agnostic way It's easy, but you need to know about it. Say you're working on some project that uses clang on macOS, gcc on Linux, MSVC on Windows, and you're developing on Linux. You write some patch, and things work fine on your machine. You submit your thing, it gets reverted because it triggers this new warning on mac. Hey, fair enough, looks like a good warning, so you remove the thing from the capture list and reland. Now you get reverted _again_ because MSVC does need that thing that clang just told you to revert. After three such interactions you'll be pretty unhappy, I gather :-) > without disabling the > diagnostic everywhere in Clang. You can leave the capture in place to > appease MSVC and cast the use to void to appease Clang, if you so > desire. Not an awesome solution, but my intuition is that this is an > uncommon situation in the first place. > > > > >> > >> You could: > >> Disable the warning on the command line. > >> Disable the warning with a pragma. > > > > > > It's an error, not a warning. > > I took the original statement to mean "for a Clang build", not "for an > MSVC build". > Ah, that makes more sense. > > > > >> > >> Cast foo to void inside the lambda. > > > > > > That's equivalent to disabling the clang warning in those cases (which > would > > be a shame, since the warning is super useful, and it doesn't introduce > > problems in most cases -- only with local constexprs). Maybe the warning > > could be split in two, so that it can be toggled separately for > constexpr? > > While functional, that seems like a lot of work for this case. > It's like 4 lines, no? As I said, I'm not sure it's worth it either. As-is, I think larger cross platform teams must enable this warning for the reason mentioned above. Requiring this is a bit of a shame since I think it's a great warning, so I was hoping we could come up with a way so we could use the warning as well. > However, the downside to the cast to void is that when MSVC does fix > the bug, the diagnostic remains silenced in the user's source base. > > > > >> > >> Only capture foo when building with MSVC. > >> > >> Stop building with MSVC. > > > > > > This reply like this make me believe you think it was silly to even > report > > this problem. I don't think it's silly, and there's ample precedent in > clang > > to make it work well in the actual world instead of in a world we wished > we > > lived in. > > Definitely not silly to report the problem, but at the same time, that > precedent is usually reserved for things that affect a significant > portion of users when the issue boils down to a compiler bug in > another compiler. How common of a problem is this use case? Does it > crop up in important header files? > It's not super common. Ivan, I think you ran into this twice in all of Chromium? > > ~Aaron > > > > >> > >> Complain to Microsoft. > > > > > > Already done. The reality is that their shipping compiler produces this > > diagnostic, and the current 2017 build does too. > > > > ___ > > cfe-commits mailing list > > cfe-commits@lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > > >
Re: r291905 - [Sema] Add warning for unused lambda captures
On Mon, Jan 23, 2017 at 5:00 PM, Nico Weber via cfe-commitswrote: > On Sun, Jan 22, 2017 at 6:17 AM, Malcolm Parsons > wrote: >> >> On 20 January 2017 at 21:32, Nico Weber wrote: >> > This warns about code like >> > >> > constexpr int foo = 4; >> > []() { use(foo); } >> > >> > That's correct, but removing then makes MSVC complain about this >> > code >> > like "error C3493: 'foo' cannot be implicitly captured because no >> > default >> > capture mode has been specified". A workaround is to make foo static >> > const >> > instead of constexpr. >> > >> > This seems like an MSVC bug, but it's still a bit annoying that clang >> > now >> > suggests doing things that won't build in other compilers. Any ideas >> > what to >> > do about this? >> >> Should Clang care about the behaviour of other compilers that don't >> follow the standard? > > > clang should be a compiler that people like to use. Multi-platform > development isn't super uncommon, so trying to give a good experience in > that case seems like a good thing to me -- and we've tried to do that in the > past pretty hard. It's possible that "do nothing" is the right thing, but > "well that other compiler is buggy" seems like a somewhat oversimplified > reply. We generally don't try to be bug-for-bug compatible with other compilers unless the bug is sufficiently important (like it is relied upon in system headers, for instance). In this case, I think the bug in MSVC is annoying, but not the end of the world because it's trivial to workaround in a compiler-agnostic way without disabling the diagnostic everywhere in Clang. You can leave the capture in place to appease MSVC and cast the use to void to appease Clang, if you so desire. Not an awesome solution, but my intuition is that this is an uncommon situation in the first place. > >> >> You could: >> Disable the warning on the command line. >> Disable the warning with a pragma. > > > It's an error, not a warning. I took the original statement to mean "for a Clang build", not "for an MSVC build". > >> >> Cast foo to void inside the lambda. > > > That's equivalent to disabling the clang warning in those cases (which would > be a shame, since the warning is super useful, and it doesn't introduce > problems in most cases -- only with local constexprs). Maybe the warning > could be split in two, so that it can be toggled separately for constexpr? While functional, that seems like a lot of work for this case. However, the downside to the cast to void is that when MSVC does fix the bug, the diagnostic remains silenced in the user's source base. > >> >> Only capture foo when building with MSVC. >> >> Stop building with MSVC. > > > This reply like this make me believe you think it was silly to even report > this problem. I don't think it's silly, and there's ample precedent in clang > to make it work well in the actual world instead of in a world we wished we > lived in. Definitely not silly to report the problem, but at the same time, that precedent is usually reserved for things that affect a significant portion of users when the issue boils down to a compiler bug in another compiler. How common of a problem is this use case? Does it crop up in important header files? ~Aaron > >> >> Complain to Microsoft. > > > Already done. The reality is that their shipping compiler produces this > diagnostic, and the current 2017 build does too. > > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r291905 - [Sema] Add warning for unused lambda captures
On Sun, Jan 22, 2017 at 6:17 AM, Malcolm Parsonswrote: > On 20 January 2017 at 21:32, Nico Weber wrote: > > This warns about code like > > > > constexpr int foo = 4; > > []() { use(foo); } > > > > That's correct, but removing then makes MSVC complain about this > code > > like "error C3493: 'foo' cannot be implicitly captured because no default > > capture mode has been specified". A workaround is to make foo static > const > > instead of constexpr. > > > > This seems like an MSVC bug, but it's still a bit annoying that clang now > > suggests doing things that won't build in other compilers. Any ideas > what to > > do about this? > > Should Clang care about the behaviour of other compilers that don't > follow the standard? > clang should be a compiler that people like to use. Multi-platform development isn't super uncommon, so trying to give a good experience in that case seems like a good thing to me -- and we've tried to do that in the past pretty hard. It's possible that "do nothing" is the right thing, but "well that other compiler is buggy" seems like a somewhat oversimplified reply. > You could: > Disable the warning on the command line. > Disable the warning with a pragma. > It's an error, not a warning. > Cast foo to void inside the lambda. > That's equivalent to disabling the clang warning in those cases (which would be a shame, since the warning is super useful, and it doesn't introduce problems in most cases -- only with local constexprs). Maybe the warning could be split in two, so that it can be toggled separately for constexpr? > Only capture foo when building with MSVC. Stop building with MSVC. > This reply like this make me believe you think it was silly to even report this problem. I don't think it's silly, and there's ample precedent in clang to make it work well in the actual world instead of in a world we wished we lived in. > Complain to Microsoft. > Already done. The reality is that their shipping compiler produces this diagnostic, and the current 2017 build does too. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r291905 - [Sema] Add warning for unused lambda captures
On 20 January 2017 at 21:32, Nico Weberwrote: > This warns about code like > > constexpr int foo = 4; > []() { use(foo); } > > That's correct, but removing then makes MSVC complain about this code > like "error C3493: 'foo' cannot be implicitly captured because no default > capture mode has been specified". A workaround is to make foo static const > instead of constexpr. > > This seems like an MSVC bug, but it's still a bit annoying that clang now > suggests doing things that won't build in other compilers. Any ideas what to > do about this? Should Clang care about the behaviour of other compilers that don't follow the standard? You could: Disable the warning on the command line. Disable the warning with a pragma. Cast foo to void inside the lambda. Only capture foo when building with MSVC. Stop building with MSVC. Complain to Microsoft. -- Malcolm Parsons ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r291905 - [Sema] Add warning for unused lambda captures
This warns about code like constexpr int foo = 4; []() { use(foo); } That's correct, but removing then makes MSVC complain about this code like "error C3493: 'foo' cannot be implicitly captured because no default capture mode has been specified". A workaround is to make foo static const instead of constexpr. This seems like an MSVC bug, but it's still a bit annoying that clang now suggests doing things that won't build in other compilers. Any ideas what to do about this? On Fri, Jan 13, 2017 at 10:01 AM, Malcolm Parsons via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: malcolm.parsons > Date: Fri Jan 13 09:01:06 2017 > New Revision: 291905 > > URL: http://llvm.org/viewvc/llvm-project?rev=291905=rev > Log: > [Sema] Add warning for unused lambda captures > > Summary: > Warn when a lambda explicitly captures something that is not used in its > body. > > The warning is part of -Wunused and can be enabled with > -Wunused-lambda-capture. > > Reviewers: rsmith, arphaman, jbcoe, aaron.ballman > > Subscribers: Quuxplusone, arphaman, cfe-commits > > Differential Revision: https://reviews.llvm.org/D28467 > > Added: > cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp > Modified: > cfe/trunk/include/clang/Basic/DiagnosticGroups.td > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/include/clang/Sema/ScopeInfo.h > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/Sema/SemaExpr.cpp > cfe/trunk/lib/Sema/SemaExprCXX.cpp > cfe/trunk/lib/Sema/SemaLambda.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp > cfe/trunk/test/SemaCXX/uninitialized.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Basic/DiagnosticGroups.td?rev=291905=291904=291905=diff > > == > --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jan 13 09:01:06 > 2017 > @@ -480,6 +480,7 @@ def UnusedFunction : DiagGroup<"unused-f > def UnusedMemberFunction : DiagGroup<"unused-member-function", > [UnneededMemberFunction]>; > def UnusedLabel : DiagGroup<"unused-label">; > +def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">; > def UnusedParameter : DiagGroup<"unused-parameter">; > def UnusedResult : DiagGroup<"unused-result">; > def PotentiallyEvaluatedExpression : DiagGroup<"potentially- > evaluated-expression">; > @@ -617,8 +618,9 @@ def Unused : DiagGroup<"unused", > [UnusedArgument, UnusedFunction, UnusedLabel, > // UnusedParameter, (matches GCC's behavior) > // UnusedMemberFunction, (clean-up llvm before > enabling) > -UnusedPrivateField, UnusedLocalTypedef, > -UnusedValue, UnusedVariable, UnusedPropertyIvar]>, > +UnusedPrivateField, UnusedLambdaCapture, > +UnusedLocalTypedef, UnusedValue, UnusedVariable, > +UnusedPropertyIvar]>, > DiagCategory<"Unused Entity Issue">; > > // Format settings. > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/ > DiagnosticSemaKinds.td?rev=291905=291904=291905=diff > > == > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 13 > 09:01:06 2017 > @@ -316,6 +316,9 @@ def warn_unneeded_member_function : Warn >InGroup, DefaultIgnore; > def warn_unused_private_field: Warning<"private field %0 is not used">, >InGroup, DefaultIgnore; > +def warn_unused_lambda_capture: Warning<"lambda capture %0 is not " > + "%select{used|required to be captured for use in an unevaluated > context}1">, > + InGroup, DefaultIgnore; > > def warn_parameter_size: Warning< >"%0 is a large (%1 bytes) pass-by-value argument; " > > Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Sema/ScopeInfo.h?rev=291905=291904=291905=diff > > == > --- cfe/trunk/include/clang/Sema/ScopeInfo.h (original) > +++ cfe/trunk/include/clang/Sema/ScopeInfo.h Fri Jan 13 09:01:06 2017 > @@ -452,6 +452,14 @@ public: > /// non-static data member that would hold the capture. > QualType CaptureType; > > +/// \brief
Re: r291905 - [Sema] Add warning for unused lambda captures
Sorry, for the noise. This is probably not the revision that caused this. On Mon, Jan 16, 2017 at 1:08 AM, Daniel Jasperwrote: > This patch seems to break on some of our code. Reproducer: > > $ cat /tmp/ctor.cc > template > struct A { > A() {} > }; > > template > class B : T { > using T::T; > }; > > struct C { > B d; > C(A b) : d(b) {} > }; > > djasper@dj:~/llvm/release$ bin/clang -cc1 -std=c++11 /tmp/ctor.cc > /tmp/ctor.cc:13:17: error: no matching constructor for initialization of > 'B' > C(A b) : d(b) {} > ^ ~ > /tmp/ctor.cc:7:7: note: candidate constructor (the implicit copy > constructor) not viable: no known conversion from 'A' to 'const > B' for 1st argument > class B : T { > ^ > /tmp/ctor.cc:7:7: note: candidate constructor (the implicit move > constructor) not viable: no known conversion from 'A' to 'B' > for 1st argument > class B : T { > ^ > /tmp/ctor.cc:7:7: note: candidate constructor (the implicit default > constructor) not viable: requires 0 arguments, but 1 was provided > 1 error generated. > > As far as I can tell, the copy constructor of class A does not get > forwarded with the "using T::T". I am not an expert on this parts of the > language, but this does seem like an unwanted side-effect. It builds find > with a version of Clang prior to this patch. > > On Fri, Jan 13, 2017 at 4:01 PM, Malcolm Parsons via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> Author: malcolm.parsons >> Date: Fri Jan 13 09:01:06 2017 >> New Revision: 291905 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=291905=rev >> Log: >> [Sema] Add warning for unused lambda captures >> >> Summary: >> Warn when a lambda explicitly captures something that is not used in its >> body. >> >> The warning is part of -Wunused and can be enabled with >> -Wunused-lambda-capture. >> >> Reviewers: rsmith, arphaman, jbcoe, aaron.ballman >> >> Subscribers: Quuxplusone, arphaman, cfe-commits >> >> Differential Revision: https://reviews.llvm.org/D28467 >> >> Added: >> cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp >> Modified: >> cfe/trunk/include/clang/Basic/DiagnosticGroups.td >> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> cfe/trunk/include/clang/Sema/ScopeInfo.h >> cfe/trunk/include/clang/Sema/Sema.h >> cfe/trunk/lib/Sema/SemaExpr.cpp >> cfe/trunk/lib/Sema/SemaExprCXX.cpp >> cfe/trunk/lib/Sema/SemaLambda.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp >> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp >> cfe/trunk/test/SemaCXX/uninitialized.cpp >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ >> Basic/DiagnosticGroups.td?rev=291905=291904=291905=diff >> >> == >> --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jan 13 >> 09:01:06 2017 >> @@ -480,6 +480,7 @@ def UnusedFunction : DiagGroup<"unused-f >> def UnusedMemberFunction : DiagGroup<"unused-member-function", >> [UnneededMemberFunction]>; >> def UnusedLabel : DiagGroup<"unused-label">; >> +def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">; >> def UnusedParameter : DiagGroup<"unused-parameter">; >> def UnusedResult : DiagGroup<"unused-result">; >> def PotentiallyEvaluatedExpression : DiagGroup<"potentially-evaluat >> ed-expression">; >> @@ -617,8 +618,9 @@ def Unused : DiagGroup<"unused", >> [UnusedArgument, UnusedFunction, UnusedLabel, >> // UnusedParameter, (matches GCC's behavior) >> // UnusedMemberFunction, (clean-up llvm before >> enabling) >> -UnusedPrivateField, UnusedLocalTypedef, >> -UnusedValue, UnusedVariable, >> UnusedPropertyIvar]>, >> +UnusedPrivateField, UnusedLambdaCapture, >> +UnusedLocalTypedef, UnusedValue, UnusedVariable, >> +UnusedPropertyIvar]>, >> DiagCategory<"Unused Entity Issue">; >> >> // Format settings. >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ >> Basic/DiagnosticSemaKinds.td?rev=291905=291904=291905=diff >> >> == >> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 13 >> 09:01:06 2017 >> @@ -316,6 +316,9 @@ def
Re: r291905 - [Sema] Add warning for unused lambda captures
This patch seems to break on some of our code. Reproducer: $ cat /tmp/ctor.cc template struct A { A() {} }; template class B : T { using T::T; }; struct C { B d; C(A b) : d(b) {} }; djasper@dj:~/llvm/release$ bin/clang -cc1 -std=c++11 /tmp/ctor.cc /tmp/ctor.cc:13:17: error: no matching constructor for initialization of 'B' C(A b) : d(b) {} ^ ~ /tmp/ctor.cc:7:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'A' to 'const B' for 1st argument class B : T { ^ /tmp/ctor.cc:7:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'A' to 'B' for 1st argument class B : T { ^ /tmp/ctor.cc:7:7: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided 1 error generated. As far as I can tell, the copy constructor of class A does not get forwarded with the "using T::T". I am not an expert on this parts of the language, but this does seem like an unwanted side-effect. It builds find with a version of Clang prior to this patch. On Fri, Jan 13, 2017 at 4:01 PM, Malcolm Parsons via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: malcolm.parsons > Date: Fri Jan 13 09:01:06 2017 > New Revision: 291905 > > URL: http://llvm.org/viewvc/llvm-project?rev=291905=rev > Log: > [Sema] Add warning for unused lambda captures > > Summary: > Warn when a lambda explicitly captures something that is not used in its > body. > > The warning is part of -Wunused and can be enabled with > -Wunused-lambda-capture. > > Reviewers: rsmith, arphaman, jbcoe, aaron.ballman > > Subscribers: Quuxplusone, arphaman, cfe-commits > > Differential Revision: https://reviews.llvm.org/D28467 > > Added: > cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp > Modified: > cfe/trunk/include/clang/Basic/DiagnosticGroups.td > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/include/clang/Sema/ScopeInfo.h > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/Sema/SemaExpr.cpp > cfe/trunk/lib/Sema/SemaExprCXX.cpp > cfe/trunk/lib/Sema/SemaLambda.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp > cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp > cfe/trunk/test/SemaCXX/uninitialized.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Basic/DiagnosticGroups.td?rev=291905=291904=291905=diff > > == > --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jan 13 09:01:06 > 2017 > @@ -480,6 +480,7 @@ def UnusedFunction : DiagGroup<"unused-f > def UnusedMemberFunction : DiagGroup<"unused-member-function", > [UnneededMemberFunction]>; > def UnusedLabel : DiagGroup<"unused-label">; > +def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">; > def UnusedParameter : DiagGroup<"unused-parameter">; > def UnusedResult : DiagGroup<"unused-result">; > def PotentiallyEvaluatedExpression : DiagGroup<"potentially- > evaluated-expression">; > @@ -617,8 +618,9 @@ def Unused : DiagGroup<"unused", > [UnusedArgument, UnusedFunction, UnusedLabel, > // UnusedParameter, (matches GCC's behavior) > // UnusedMemberFunction, (clean-up llvm before > enabling) > -UnusedPrivateField, UnusedLocalTypedef, > -UnusedValue, UnusedVariable, UnusedPropertyIvar]>, > +UnusedPrivateField, UnusedLambdaCapture, > +UnusedLocalTypedef, UnusedValue, UnusedVariable, > +UnusedPropertyIvar]>, > DiagCategory<"Unused Entity Issue">; > > // Format settings. > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/ > DiagnosticSemaKinds.td?rev=291905=291904=291905=diff > > == > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 13 > 09:01:06 2017 > @@ -316,6 +316,9 @@ def warn_unneeded_member_function : Warn >InGroup, DefaultIgnore; > def warn_unused_private_field: Warning<"private field %0 is not used">, >InGroup, DefaultIgnore; > +def warn_unused_lambda_capture: Warning<"lambda capture %0 is not " > + "%select{used|required to be captured for use in an unevaluated > context}1">, >
r291905 - [Sema] Add warning for unused lambda captures
Author: malcolm.parsons Date: Fri Jan 13 09:01:06 2017 New Revision: 291905 URL: http://llvm.org/viewvc/llvm-project?rev=291905=rev Log: [Sema] Add warning for unused lambda captures Summary: Warn when a lambda explicitly captures something that is not used in its body. The warning is part of -Wunused and can be enabled with -Wunused-lambda-capture. Reviewers: rsmith, arphaman, jbcoe, aaron.ballman Subscribers: Quuxplusone, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D28467 Added: cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/ScopeInfo.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/lib/Sema/SemaLambda.cpp cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p16.cpp cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p18.cpp cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp cfe/trunk/test/SemaCXX/uninitialized.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=291905=291904=291905=diff == --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jan 13 09:01:06 2017 @@ -480,6 +480,7 @@ def UnusedFunction : DiagGroup<"unused-f def UnusedMemberFunction : DiagGroup<"unused-member-function", [UnneededMemberFunction]>; def UnusedLabel : DiagGroup<"unused-label">; +def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">; def UnusedParameter : DiagGroup<"unused-parameter">; def UnusedResult : DiagGroup<"unused-result">; def PotentiallyEvaluatedExpression : DiagGroup<"potentially-evaluated-expression">; @@ -617,8 +618,9 @@ def Unused : DiagGroup<"unused", [UnusedArgument, UnusedFunction, UnusedLabel, // UnusedParameter, (matches GCC's behavior) // UnusedMemberFunction, (clean-up llvm before enabling) -UnusedPrivateField, UnusedLocalTypedef, -UnusedValue, UnusedVariable, UnusedPropertyIvar]>, +UnusedPrivateField, UnusedLambdaCapture, +UnusedLocalTypedef, UnusedValue, UnusedVariable, +UnusedPropertyIvar]>, DiagCategory<"Unused Entity Issue">; // Format settings. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=291905=291904=291905=diff == --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 13 09:01:06 2017 @@ -316,6 +316,9 @@ def warn_unneeded_member_function : Warn InGroup, DefaultIgnore; def warn_unused_private_field: Warning<"private field %0 is not used">, InGroup, DefaultIgnore; +def warn_unused_lambda_capture: Warning<"lambda capture %0 is not " + "%select{used|required to be captured for use in an unevaluated context}1">, + InGroup, DefaultIgnore; def warn_parameter_size: Warning< "%0 is a large (%1 bytes) pass-by-value argument; " Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=291905=291904=291905=diff == --- cfe/trunk/include/clang/Sema/ScopeInfo.h (original) +++ cfe/trunk/include/clang/Sema/ScopeInfo.h Fri Jan 13 09:01:06 2017 @@ -452,6 +452,14 @@ public: /// non-static data member that would hold the capture. QualType CaptureType; +/// \brief Whether an explicit capture has been odr-used in the body of the +/// lambda. +bool ODRUsed; + +/// \brief Whether an explicit capture has been non-odr-used in the body of +/// the lambda. +bool NonODRUsed; + public: Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, SourceLocation Loc, SourceLocation EllipsisLoc, @@ -460,7 +468,8 @@ public: InitExprAndCaptureKind( Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef : Cap_ByCopy), - Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {} + Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType), + ODRUsed(false), NonODRUsed(false) {}