-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[clang-tidy] Add support for lambda-expression in use-trailing-return-type
check
#135383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang-tools-extra @llvm/pr-subscribers-clang-tidy Author: Baranov Victor (vbvictor) ChangesAdd support for lambda-expression in Added two new options:
Addresses #95711 Patch is 23.09 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135383.diff 8 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
index 9774e988d71e2..ca0d05a86d453 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
@@ -17,6 +17,30 @@
#include <cctype>
#include <optional>
+namespace clang::tidy {
+
+template <>
+struct OptionEnumMapping<
+ modernize::UseTrailingReturnTypeCheck::TransformLambda> {
+ static llvm::ArrayRef<std::pair<
+ modernize::UseTrailingReturnTypeCheck::TransformLambda, StringRef>>
+ getEnumMapping() {
+ static constexpr std::pair<
+ modernize::UseTrailingReturnTypeCheck::TransformLambda, StringRef>
+ Mapping[] = {
+ {modernize::UseTrailingReturnTypeCheck::TransformLambda::All,
+ "All"},
+ {modernize::UseTrailingReturnTypeCheck::TransformLambda::
+ AllExceptAuto,
+ "AllExceptAuto"},
+ {modernize::UseTrailingReturnTypeCheck::TransformLambda::None,
+ "None"}};
+ return Mapping;
+ }
+};
+
+} // namespace clang::tidy
+
using namespace clang::ast_matchers;
namespace clang::tidy::modernize {
@@ -111,6 +135,11 @@ struct UnqualNameVisitor : public RecursiveASTVisitor<UnqualNameVisitor> {
private:
const FunctionDecl &F;
};
+
+AST_MATCHER(LambdaExpr, hasExplicitResultType) {
+ return Node.hasExplicitResultType();
+}
+
} // namespace
constexpr llvm::StringLiteral Message =
@@ -383,14 +412,40 @@ void UseTrailingReturnTypeCheck::keepSpecifiers(
}
}
+UseTrailingReturnTypeCheck::UseTrailingReturnTypeCheck(
+ StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ TransformFunctions(Options.get("TransformFunctions", true)),
+ TransformLambdas(Options.get("TransformLambdas", TransformLambda::All)) {
+
+ if (TransformFunctions == false && TransformLambdas == TransformLambda::None)
+ this->configurationDiag(
+ "The check 'modernize-use-trailing-return-type' will not perform any "
+ "analysis because 'TransformFunctions' and 'TransformLambdas' are "
+ "disabled.");
+}
+
+void UseTrailingReturnTypeCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "TransformFunctions", TransformFunctions);
+ Options.store(Opts, "TransformLambdas", TransformLambdas);
+}
+
void UseTrailingReturnTypeCheck::registerMatchers(MatchFinder *Finder) {
auto F = functionDecl(
unless(anyOf(hasTrailingReturn(), returns(voidType()),
cxxConversionDecl(), cxxMethodDecl(isImplicit()))))
.bind("Func");
- Finder->addMatcher(F, this);
- Finder->addMatcher(friendDecl(hasDescendant(F)).bind("Friend"), this);
+ if (TransformFunctions) {
+ Finder->addMatcher(F, this);
+ Finder->addMatcher(friendDecl(hasDescendant(F)).bind("Friend"), this);
+ }
+
+ if (TransformLambdas != TransformLambda::None) {
+ Finder->addMatcher(
+ lambdaExpr(unless(hasExplicitResultType())).bind("Lambda"), this);
+ }
}
void UseTrailingReturnTypeCheck::registerPPCallbacks(
@@ -402,8 +457,13 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
assert(PP && "Expected registerPPCallbacks() to have been called before so "
"preprocessor is available");
- const auto *F = Result.Nodes.getNodeAs<FunctionDecl>("Func");
+ if (const auto *Lambda = Result.Nodes.getNodeAs<LambdaExpr>("Lambda")) {
+ diagOnLambda(Lambda, Result);
+ return;
+ }
+
const auto *Fr = Result.Nodes.getNodeAs<FriendDecl>("Friend");
+ const auto *F = Result.Nodes.getNodeAs<FunctionDecl>("Func");
assert(F && "Matcher is expected to find only FunctionDecls");
// Three-way comparison operator<=> is syntactic sugar and generates implicit
@@ -494,4 +554,75 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
<< FixItHint::CreateInsertion(InsertionLoc, " -> " + ReturnType);
}
+void UseTrailingReturnTypeCheck::diagOnLambda(
+ const LambdaExpr *Lambda,
+ const ast_matchers::MatchFinder::MatchResult &Result) {
+
+ const CXXMethodDecl *Method = Lambda->getCallOperator();
+ if (!Method || Lambda->hasExplicitResultType())
+ return;
+
+ const QualType ReturnType = Method->getReturnType();
+ if (ReturnType->isUndeducedAutoType() &&
+ TransformLambdas == TransformLambda::AllExceptAuto)
+ return;
+
+ const SourceLocation TrailingReturnInsertLoc =
+ findLambdaTrailingReturnInsertLoc(Method, *Result.SourceManager,
+ getLangOpts(), *Result.Context);
+
+ if (TrailingReturnInsertLoc.isValid())
+ diag(Lambda->getBeginLoc(), "use a trailing return type for this lambda")
+ << FixItHint::CreateInsertion(
+ TrailingReturnInsertLoc,
+ " -> " +
+ ReturnType.getAsString(Result.Context->getPrintingPolicy()));
+ else
+ diag(Lambda->getBeginLoc(), "use a trailing return type for this lambda");
+}
+
+SourceLocation UseTrailingReturnTypeCheck::findLambdaTrailingReturnInsertLoc(
+ const CXXMethodDecl *Method, const SourceManager &SM,
+ const LangOptions &LangOpts, const ASTContext &Ctx) {
+ // 'requires' keyword is present in lambda declaration
+ if (Method->getTrailingRequiresClause()) {
+ SourceLocation ParamEndLoc;
+ if (Method->param_empty()) {
+ ParamEndLoc = Method->getBeginLoc();
+ } else {
+ ParamEndLoc = Method->getParametersSourceRange().getEnd();
+ }
+
+ std::pair<FileID, unsigned> ParamEndLocInfo =
+ SM.getDecomposedLoc(ParamEndLoc);
+ StringRef Buffer = SM.getBufferData(ParamEndLocInfo.first);
+
+ Lexer Lexer(SM.getLocForStartOfFile(ParamEndLocInfo.first), LangOpts,
+ Buffer.begin(), Buffer.data() + ParamEndLocInfo.second,
+ Buffer.end());
+
+ Token Token;
+ while (!Lexer.LexFromRawLexer(Token)) {
+ if (Token.is(tok::raw_identifier)) {
+ IdentifierInfo &Info = Ctx.Idents.get(StringRef(
+ SM.getCharacterData(Token.getLocation()), Token.getLength()));
+ Token.setIdentifierInfo(&Info);
+ Token.setKind(Info.getTokenID());
+ }
+
+ if (Token.is(tok::kw_requires)) {
+ return Token.getLocation().getLocWithOffset(-1);
+ }
+ }
+
+ return {};
+ }
+
+ // If no requires clause, insert before the body
+ if (const Stmt *Body = Method->getBody())
+ return Body->getBeginLoc().getLocWithOffset(-1);
+
+ return {};
+}
+
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h
index 5fb6ae945f466..5a340707e8558 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h
@@ -27,18 +27,22 @@ struct ClassifiedToken {
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-trailing-return-type.html
class UseTrailingReturnTypeCheck : public ClangTidyCheck {
public:
- UseTrailingReturnTypeCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
+ UseTrailingReturnTypeCheck(StringRef Name, ClangTidyContext *Context);
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus11;
}
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ enum TransformLambda { All, AllExceptAuto, None };
+
private:
Preprocessor *PP = nullptr;
+ const bool TransformFunctions;
+ const TransformLambda TransformLambdas;
SourceLocation findTrailingReturnTypeSourceLocation(
const FunctionDecl &F, const FunctionTypeLoc &FTL, const ASTContext &Ctx,
@@ -56,6 +60,13 @@ class UseTrailingReturnTypeCheck : public ClangTidyCheck {
SourceRange ReturnTypeCVRange, const FunctionDecl &F,
const FriendDecl *Fr, const ASTContext &Ctx,
const SourceManager &SM, const LangOptions &LangOpts);
+
+ void diagOnLambda(const LambdaExpr *Lambda,
+ const ast_matchers::MatchFinder::MatchResult &Result);
+ SourceLocation findLambdaTrailingReturnInsertLoc(const CXXMethodDecl *Method,
+ const SourceManager &SM,
+ const LangOptions &LangOpts,
+ const ASTContext &Ctx);
};
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index fefb085409b44..41dfbd871e023 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -185,6 +185,12 @@ Changes in existing checks
<clang-tidy/checks/modernize/use-std-numbers>` check to support math
functions of different precisions.
+- Improved :doc:`modernize-use-trailing-return-type
+ <clang-tidy/checks/modernize/use-trailing-return-type>` check by adding
+ support for modifying lambda signatures to use trailing return type and adding
+ two new options: `TransformFunctions` and `TransformLambdas` to control
+ whether function declarations and lambdas should be transformed by the check.
+
- Improved :doc:`performance-move-const-arg
<clang-tidy/checks/performance/move-const-arg>` check by fixing false
negatives on ternary operators calling ``std::move``.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst
index 0593a35326aaa..5001859994e1e 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst
@@ -3,7 +3,7 @@
modernize-use-trailing-return-type
==================================
-Rewrites function signatures to use a trailing return type
+Rewrites function and lambda signatures to use a trailing return type
(introduced in C++11). This transformation is purely stylistic.
The return type before the function name is replaced by ``auto``
and inserted after the function parameter list (and qualifiers).
@@ -16,6 +16,7 @@ Example
int f1();
inline int f2(int arg) noexcept;
virtual float f3() const && = delete;
+ auto lambda = []() {};
transforms to:
@@ -24,6 +25,7 @@ transforms to:
auto f1() -> int;
inline auto f2(int arg) -> int noexcept;
virtual auto f3() const && -> float = delete;
+ auto lambda = []() -> void {};
Known Limitations
-----------------
@@ -66,3 +68,25 @@ a careless rewrite would produce the following output:
This code fails to compile because the S in the context of f refers to the equally named function parameter.
Similarly, the S in the context of m refers to the equally named class member.
The check can currently only detect and avoid a clash with a function parameter name.
+
+Options
+-------
+
+.. option:: TransformFunctions
+
+ When set to `true`, function declarations will be transformed to use trailing
+ return. Default is `true`.
+
+.. option:: TransformLambdas
+
+ Controls how lambda expressions are transformed to use trailing
+ return type. Possible values are:
+
+ * `All` - Transform all lambda expressions without an explicit return type
+ to use trailing return type. If type can not be deduced, ``auto`` will be
+ used.
+ * `AllExceptAuto` - Transform all lambda expressions except those whose return
+ type can not be deduced (``auto`` type).
+ * `None` - Do not transform any lambda expressions.
+
+ Default is `All`.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas-cxx20.cpp
new file mode 100644
index 0000000000000..aa56e317bdfce
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas-cxx20.cpp
@@ -0,0 +1,35 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-trailing-return-type %t
+
+namespace std {
+template <typename T, typename U>
+struct is_same { static constexpr auto value = false; };
+
+template <typename T>
+struct is_same<T, T> { static constexpr auto value = true; };
+
+template <typename T>
+concept floating_point = std::is_same<T, float>::value || std::is_same<T, double>::value || std::is_same<T, long double>::value;
+}
+
+void test_lambda_positive() {
+ auto l1 = []<typename T, typename U>(T x, U y) { return x + y; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES: {{^}} auto l1 = []<typename T, typename U>(T x, U y) -> auto { return x + y; };{{$}}
+ auto l2 = [](auto x) requires requires { x + x; } { return x; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES: {{^}} auto l2 = [](auto x) -> auto requires requires { x + x; } { return x; };{{$}}
+ auto l3 = [](auto x) requires std::floating_point<decltype(x)> { return x; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES: {{^}} auto l3 = [](auto x) -> auto requires std::floating_point<decltype(x)> { return x; };{{$}}
+ auto l4 = [](int x) consteval { return x; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES: {{^}} auto l4 = [](int x) consteval -> int { return x; };{{$}}
+ // Complete complex example
+ auto l5 = []<typename T, typename U>(T x, U y) constexpr noexcept
+ requires std::floating_point<T> && std::floating_point<U>
+ { return x * y; };
+ // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES: {{^}} auto l5 = []<typename T, typename U>(T x, U y) constexpr noexcept{{$}}
+ // CHECK-FIXES: {{^}} -> auto requires std::floating_point<T> && std::floating_point<U>{{$}}
+ // CHECK-FIXES: {{^}} { return x * y; };{{$}}
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas.cpp
new file mode 100644
index 0000000000000..4143e9d610c3a
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas.cpp
@@ -0,0 +1,91 @@
+// RUN: %check_clang_tidy -check-suffix=ALL -std=c++14 %s modernize-use-trailing-return-type %t \
+// RUN: -config="{CheckOptions: {modernize-use-trailing-return-type.TransformLambdas: All, \
+// RUN: modernize-use-trailing-return-type.TransformFunctions: false}}"
+// RUN: %check_clang_tidy -check-suffix=NOAUTO -std=c++14 %s modernize-use-trailing-return-type %t \
+// RUN: -config="{CheckOptions: {modernize-use-trailing-return-type.TransformLambdas: AllExceptAuto, \
+// RUN: modernize-use-trailing-return-type.TransformFunctions: false}}"
+// RUN: %check_clang_tidy -check-suffix=NONE -std=c++14 %s modernize-use-trailing-return-type %t \
+// RUN: -config="{CheckOptions: {modernize-use-trailing-return-type.TransformLambdas: None, \
+// RUN: modernize-use-trailing-return-type.TransformFunctions: true}}"
+
+namespace std {
+ template <typename T>
+ class vector {};
+
+ class string {};
+} // namespace std
+
+void test_lambda_positive() {
+ auto l01 = [] {};
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:14: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l01 = [] -> void {};{{$}}
+ auto l1 = []() {};
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l1 = []() -> void {};{{$}}
+ auto l2 = []() { return 42; };
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l2 = []() -> int { return 42; };{{$}}
+ auto l3 = [](int x, double y) { return x * y; };
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l3 = [](int x, double y) -> double { return x * y; };{{$}}
+
+ int capture_int = 10;
+ double capture_double = 3.14;
+ int* capture_ptr = nullptr;
+
+ auto l4 = [capture_int]() { return capture_int; };
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l4 = [capture_int]() -> int { return capture_int; };{{$}}
+ auto l5 = [capture_int, &capture_double](char c) { return capture_int + capture_double + c; };
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l5 = [capture_int, &capture_double](char c) -> double { return capture_int + capture_double + c; };{{$}}
+ auto l6 = [capture_int]() constexpr mutable noexcept { return ++capture_int; };
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l6 = [capture_int]() constexpr mutable noexcept -> int { return ++capture_int; };{{$}}
+ auto l7 = [&capture_ptr]() { return capture_ptr; };
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l7 = [&capture_ptr]() -> int * { return capture_ptr; };{{$}}
+ auto l8 = [&capture_int]() { return capture_int; };
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l8 = [&capture_int]() -> int { return capture_int; };{{$}}
+ auto l9 = [] { return std::vector<std::vector<int>>{}; };
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+ // CHECK-FIXES-ALL: {{^}} auto l9 = [] -> std::vector<std::vector<int>> { return std::vector<std::vecto...
[truncated]
|
ParamEndLoc = Method->getParametersSourceRange().getEnd(); | ||
} | ||
|
||
std::pair<FileID, unsigned> ParamEndLocInfo = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is very similar to findTrailingReturnTypeSourceLocation
function. Here I find the position of requires
keyword.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided not to make generic implementation of this piece of code as for now.
Converted to draft to fix windows tests |
ae6cedc
to
4a7cdb4
Compare
Ping:) |
Ping |
Add support for lambda-expression in
use-trailing-return-type
check.Added two new options:
TransformFunctions
will trigger function declarations to use trailing return type. Values can betrue
orfalse
. Default istrue
.TransformLambdas
will trigger lambda expression to use trailing return type if it was not stated explicitly. This option can have the following values:All
will emit trailing return type for all lambdas, including generic-lambdas that will emitauto
type.AllExceptAuto
will emit trailing return type for all lambdas excluding those withauto
type.None
will provide no diagnostics for lambdas. Default isAll
.Fixed false positives when lambda was matched as a function in C++11 mode. https://godbolt.org/z/dh6so4Y18
Addresses #95711