[clang-tools-extra] [clang-tidy] Add support for lambda-expression in `use-trailing-return-type` check (PR #135383)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 11 07:47:38 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tidy
Author: Baranov Victor (vbvictor)
<details>
<summary>Changes</summary>
Add support for lambda-expression in `use-trailing-return-type` check.
Added two new options:
1. `TransformFunctions` will trigger function declarations to use trailing return type. Values can be `true` or `false`. Default is `true`.
2. `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 emit `auto` type. `AllExceptAuto` will emit trailing return type for all lambdas excluding those with `auto` type. `None` will provide no diagnostics for lambdas. Default is `All`.
Addresses https://github.com/llvm/llvm-project/issues/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:
- (modified) clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp (+134-3)
- (modified) clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h (+13-2)
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+6)
- (modified) clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst (+25-1)
- (added) clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas-cxx20.cpp (+35)
- (added) clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas.cpp (+91)
- (added) clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-wrong-config.cpp (+5)
- (modified) clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type.cpp (-2)
``````````diff
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]
``````````
</details>
https://github.com/llvm/llvm-project/pull/135383
More information about the cfe-commits
mailing list