mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-19 11:35:51 -04:00
Added readability-qualified-auto check
Adds a check that detects any auto variables that are deduced to a pointer or a const pointer then adds in the const and asterisk according. Will also check auto L value references that could be written as const. This relates to the coding standard https://llvm.org/docs/CodingStandards.html#beware-unnecessary-copies-with-auto
This commit is contained in:
parent
cd800f3b22
commit
36fcbb838c
@ -10,6 +10,7 @@
|
|||||||
#include "../ClangTidyModule.h"
|
#include "../ClangTidyModule.h"
|
||||||
#include "../ClangTidyModuleRegistry.h"
|
#include "../ClangTidyModuleRegistry.h"
|
||||||
#include "../readability/NamespaceCommentCheck.h"
|
#include "../readability/NamespaceCommentCheck.h"
|
||||||
|
#include "../readability/QualifiedAutoCheck.h"
|
||||||
#include "HeaderGuardCheck.h"
|
#include "HeaderGuardCheck.h"
|
||||||
#include "IncludeOrderCheck.h"
|
#include "IncludeOrderCheck.h"
|
||||||
#include "PreferIsaOrDynCastInConditionalsCheck.h"
|
#include "PreferIsaOrDynCastInConditionalsCheck.h"
|
||||||
@ -31,6 +32,8 @@ public:
|
|||||||
"llvm-prefer-isa-or-dyn-cast-in-conditionals");
|
"llvm-prefer-isa-or-dyn-cast-in-conditionals");
|
||||||
CheckFactories.registerCheck<PreferRegisterOverUnsignedCheck>(
|
CheckFactories.registerCheck<PreferRegisterOverUnsignedCheck>(
|
||||||
"llvm-prefer-register-over-unsigned");
|
"llvm-prefer-register-over-unsigned");
|
||||||
|
CheckFactories.registerCheck<readability::QualifiedAutoCheck>(
|
||||||
|
"llvm-qualified-auto");
|
||||||
CheckFactories.registerCheck<TwineLocalCheck>("llvm-twine-local");
|
CheckFactories.registerCheck<TwineLocalCheck>("llvm-twine-local");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@ add_clang_library(clangTidyReadabilityModule
|
|||||||
NamedParameterCheck.cpp
|
NamedParameterCheck.cpp
|
||||||
NamespaceCommentCheck.cpp
|
NamespaceCommentCheck.cpp
|
||||||
NonConstParameterCheck.cpp
|
NonConstParameterCheck.cpp
|
||||||
|
QualifiedAutoCheck.cpp
|
||||||
ReadabilityTidyModule.cpp
|
ReadabilityTidyModule.cpp
|
||||||
RedundantAccessSpecifiersCheck.cpp
|
RedundantAccessSpecifiersCheck.cpp
|
||||||
RedundantControlFlowCheck.cpp
|
RedundantControlFlowCheck.cpp
|
||||||
|
294
clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp
Normal file
294
clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
//===--- QualifiedAutoCheck.cpp - clang-tidy ------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "QualifiedAutoCheck.h"
|
||||||
|
#include "../utils/LexerUtils.h"
|
||||||
|
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
|
||||||
|
using namespace clang::ast_matchers;
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
namespace tidy {
|
||||||
|
namespace readability {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// FIXME move to ASTMatchers
|
||||||
|
AST_MATCHER_P(QualType, hasUnqualifiedType,
|
||||||
|
ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
|
||||||
|
return InnerMatcher.matches(Node.getUnqualifiedType(), Finder, Builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Qualifier { Const, Volatile, Restrict };
|
||||||
|
|
||||||
|
llvm::Optional<Token> findQualToken(const VarDecl *Decl, Qualifier Qual,
|
||||||
|
const MatchFinder::MatchResult &Result) {
|
||||||
|
// Since either of the locs can be in a macro, use `makeFileCharRange` to be
|
||||||
|
// sure that we have a consistent `CharSourceRange`, located entirely in the
|
||||||
|
// source file.
|
||||||
|
|
||||||
|
assert(Qual == Qualifier::Const || Qual == Qualifier::Volatile ||
|
||||||
|
Qual == Qualifier::Restrict && "Invalid Qualifier");
|
||||||
|
|
||||||
|
SourceLocation BeginLoc = Decl->getQualifierLoc().getBeginLoc();
|
||||||
|
if (BeginLoc.isInvalid())
|
||||||
|
BeginLoc = Decl->getBeginLoc();
|
||||||
|
SourceLocation EndLoc = Decl->getLocation();
|
||||||
|
|
||||||
|
CharSourceRange FileRange = Lexer::makeFileCharRange(
|
||||||
|
CharSourceRange::getCharRange(BeginLoc, EndLoc), *Result.SourceManager,
|
||||||
|
Result.Context->getLangOpts());
|
||||||
|
|
||||||
|
if (FileRange.isInvalid())
|
||||||
|
return llvm::None;
|
||||||
|
|
||||||
|
tok::TokenKind Tok =
|
||||||
|
Qual == Qualifier::Const
|
||||||
|
? tok::kw_const
|
||||||
|
: Qual == Qualifier::Volatile ? tok::kw_volatile : tok::kw_restrict;
|
||||||
|
|
||||||
|
return utils::lexer::getQualifyingToken(Tok, FileRange, *Result.Context,
|
||||||
|
*Result.SourceManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Optional<SourceRange>
|
||||||
|
getTypeSpecifierLocation(const VarDecl *Var,
|
||||||
|
const MatchFinder::MatchResult &Result) {
|
||||||
|
SourceRange TypeSpecifier(
|
||||||
|
Var->getTypeSpecStartLoc(),
|
||||||
|
Var->getTypeSpecEndLoc().getLocWithOffset(Lexer::MeasureTokenLength(
|
||||||
|
Var->getTypeSpecEndLoc(), *Result.SourceManager,
|
||||||
|
Result.Context->getLangOpts())));
|
||||||
|
|
||||||
|
if (TypeSpecifier.getBegin().isMacroID() ||
|
||||||
|
TypeSpecifier.getEnd().isMacroID())
|
||||||
|
return llvm::None;
|
||||||
|
return TypeSpecifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Optional<SourceRange> mergeReplacementRange(SourceRange &TypeSpecifier,
|
||||||
|
const Token &ConstToken) {
|
||||||
|
if (TypeSpecifier.getBegin().getLocWithOffset(-1) == ConstToken.getEndLoc()) {
|
||||||
|
TypeSpecifier.setBegin(ConstToken.getLocation());
|
||||||
|
return llvm::None;
|
||||||
|
}
|
||||||
|
if (TypeSpecifier.getEnd().getLocWithOffset(1) == ConstToken.getLocation()) {
|
||||||
|
TypeSpecifier.setEnd(ConstToken.getEndLoc());
|
||||||
|
return llvm::None;
|
||||||
|
}
|
||||||
|
return SourceRange(ConstToken.getLocation(), ConstToken.getEndLoc());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPointerConst(QualType QType) {
|
||||||
|
QualType Pointee = QType->getPointeeType();
|
||||||
|
assert(!Pointee.isNull() && "can't have a null Pointee");
|
||||||
|
return Pointee.isConstQualified();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAutoPointerConst(QualType QType) {
|
||||||
|
QualType Pointee =
|
||||||
|
cast<AutoType>(QType->getPointeeType().getTypePtr())->desugar();
|
||||||
|
assert(!Pointee.isNull() && "can't have a null Pointee");
|
||||||
|
return Pointee.isConstQualified();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
|
if (!getLangOpts().CPlusPlus11)
|
||||||
|
return; // Auto deduction not used in 'C or C++03 and earlier', so don't
|
||||||
|
// register Matchers.
|
||||||
|
auto ExplicitSingleVarDecl =
|
||||||
|
[](const ast_matchers::internal::Matcher<VarDecl> &InnerMatcher,
|
||||||
|
llvm::StringRef ID) {
|
||||||
|
return declStmt(
|
||||||
|
unless(isInTemplateInstantiation()),
|
||||||
|
hasSingleDecl(
|
||||||
|
varDecl(unless(isImplicit()), InnerMatcher).bind(ID)));
|
||||||
|
};
|
||||||
|
auto ExplicitSingleVarDeclInTemplate =
|
||||||
|
[](const ast_matchers::internal::Matcher<VarDecl> &InnerMatcher,
|
||||||
|
llvm::StringRef ID) {
|
||||||
|
return declStmt(
|
||||||
|
isInTemplateInstantiation(),
|
||||||
|
hasSingleDecl(
|
||||||
|
varDecl(unless(isImplicit()), InnerMatcher).bind(ID)));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto IsBoundToType = refersToType(equalsBoundNode("type"));
|
||||||
|
|
||||||
|
Finder->addMatcher(
|
||||||
|
ExplicitSingleVarDecl(hasType(autoType(hasDeducedType(
|
||||||
|
pointerType(pointee(unless(functionType())))))),
|
||||||
|
"auto"),
|
||||||
|
this);
|
||||||
|
|
||||||
|
Finder->addMatcher(
|
||||||
|
ExplicitSingleVarDeclInTemplate(
|
||||||
|
allOf(hasType(autoType(hasDeducedType(pointerType(
|
||||||
|
pointee(hasUnqualifiedType(qualType().bind("type")),
|
||||||
|
unless(functionType())))))),
|
||||||
|
anyOf(hasAncestor(
|
||||||
|
functionDecl(hasAnyTemplateArgument(IsBoundToType))),
|
||||||
|
hasAncestor(classTemplateSpecializationDecl(
|
||||||
|
hasAnyTemplateArgument(IsBoundToType))))),
|
||||||
|
"auto"),
|
||||||
|
this);
|
||||||
|
Finder->addMatcher(ExplicitSingleVarDecl(
|
||||||
|
hasType(pointerType(pointee(autoType()))), "auto_ptr"),
|
||||||
|
this);
|
||||||
|
Finder->addMatcher(
|
||||||
|
ExplicitSingleVarDecl(hasType(lValueReferenceType(pointee(autoType()))),
|
||||||
|
"auto_ref"),
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto")) {
|
||||||
|
SourceRange TypeSpecifier;
|
||||||
|
if (llvm::Optional<SourceRange> TypeSpec =
|
||||||
|
getTypeSpecifierLocation(Var, Result)) {
|
||||||
|
TypeSpecifier = *TypeSpec;
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
|
||||||
|
llvm::SmallVector<SourceRange, 4> RemoveQualifiersRange;
|
||||||
|
auto CheckQualifier = [&](bool IsPresent, Qualifier Qual) {
|
||||||
|
if (IsPresent) {
|
||||||
|
llvm::Optional<Token> Token = findQualToken(Var, Qual, Result);
|
||||||
|
if (!Token || Token->getLocation().isMacroID())
|
||||||
|
return true; // Disregard this VarDecl.
|
||||||
|
if (llvm::Optional<SourceRange> Result =
|
||||||
|
mergeReplacementRange(TypeSpecifier, *Token))
|
||||||
|
RemoveQualifiersRange.push_back(*Result);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool IsLocalConst = Var->getType().isLocalConstQualified();
|
||||||
|
bool IsLocalVolatile = Var->getType().isLocalVolatileQualified();
|
||||||
|
bool IsLocalRestrict = Var->getType().isLocalRestrictQualified();
|
||||||
|
|
||||||
|
if (CheckQualifier(IsLocalConst, Qualifier::Const))
|
||||||
|
return;
|
||||||
|
if (CheckQualifier(IsLocalVolatile, Qualifier::Volatile))
|
||||||
|
return;
|
||||||
|
if (CheckQualifier(IsLocalRestrict, Qualifier::Restrict))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check for bridging the gap between the asterisk and name.
|
||||||
|
if (Var->getLocation() == TypeSpecifier.getEnd().getLocWithOffset(1))
|
||||||
|
TypeSpecifier.setEnd(TypeSpecifier.getEnd().getLocWithOffset(1));
|
||||||
|
|
||||||
|
CharSourceRange FixItRange = CharSourceRange::getCharRange(TypeSpecifier);
|
||||||
|
if (FixItRange.isInvalid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SourceLocation FixitLoc = FixItRange.getBegin();
|
||||||
|
for (SourceRange &Range : RemoveQualifiersRange) {
|
||||||
|
if (Range.getBegin() < FixitLoc)
|
||||||
|
FixitLoc = Range.getBegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ReplStr = [&] {
|
||||||
|
llvm::StringRef PtrConst = isPointerConst(Var->getType()) ? "const " : "";
|
||||||
|
llvm::StringRef LocalConst = IsLocalConst ? "const " : "";
|
||||||
|
llvm::StringRef LocalVol = IsLocalVolatile ? "volatile " : "";
|
||||||
|
llvm::StringRef LocalRestrict = IsLocalRestrict ? "__restrict " : "";
|
||||||
|
return (PtrConst + "auto *" + LocalConst + LocalVol + LocalRestrict)
|
||||||
|
.str();
|
||||||
|
}();
|
||||||
|
|
||||||
|
DiagnosticBuilder Diag =
|
||||||
|
diag(FixitLoc, "'%0%1%2auto %3' can be declared as '%4%3'")
|
||||||
|
<< (IsLocalConst ? "const " : "")
|
||||||
|
<< (IsLocalVolatile ? "volatile " : "")
|
||||||
|
<< (IsLocalRestrict ? "__restrict " : "") << Var->getName() << ReplStr;
|
||||||
|
|
||||||
|
for (SourceRange &Range : RemoveQualifiersRange) {
|
||||||
|
Diag << FixItHint::CreateRemoval(
|
||||||
|
CharSourceRange::getCharRange(Range.getBegin(), Range.getEnd()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Diag << FixItHint::CreateReplacement(FixItRange, ReplStr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto_ptr")) {
|
||||||
|
if (!isPointerConst(Var->getType()))
|
||||||
|
return; // Pointer isn't const, no need to add const qualifier.
|
||||||
|
if (!isAutoPointerConst(Var->getType()))
|
||||||
|
return; // Const isnt wrapped in the auto type, so must be declared
|
||||||
|
// explicitly.
|
||||||
|
|
||||||
|
if (Var->getType().isLocalConstQualified()) {
|
||||||
|
llvm::Optional<Token> Token =
|
||||||
|
findQualToken(Var, Qualifier::Const, Result);
|
||||||
|
if (!Token || Token->getLocation().isMacroID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Var->getType().isLocalVolatileQualified()) {
|
||||||
|
llvm::Optional<Token> Token =
|
||||||
|
findQualToken(Var, Qualifier::Volatile, Result);
|
||||||
|
if (!Token || Token->getLocation().isMacroID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Var->getType().isLocalRestrictQualified()) {
|
||||||
|
llvm::Optional<Token> Token =
|
||||||
|
findQualToken(Var, Qualifier::Restrict, Result);
|
||||||
|
if (!Token || Token->getLocation().isMacroID())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CharSourceRange FixItRange;
|
||||||
|
if (llvm::Optional<SourceRange> TypeSpec =
|
||||||
|
getTypeSpecifierLocation(Var, Result)) {
|
||||||
|
FixItRange = CharSourceRange::getCharRange(*TypeSpec);
|
||||||
|
if (FixItRange.isInvalid())
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
|
||||||
|
DiagnosticBuilder Diag =
|
||||||
|
diag(FixItRange.getBegin(),
|
||||||
|
"'auto *%0%1%2' can be declared as 'const auto *%0%1%2'")
|
||||||
|
<< (Var->getType().isLocalConstQualified() ? "const " : "")
|
||||||
|
<< (Var->getType().isLocalVolatileQualified() ? "volatile " : "")
|
||||||
|
<< Var->getName();
|
||||||
|
Diag << FixItHint::CreateReplacement(FixItRange, "const auto *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto_ref")) {
|
||||||
|
if (!isPointerConst(Var->getType()))
|
||||||
|
return; // Pointer isn't const, no need to add const qualifier.
|
||||||
|
if (!isAutoPointerConst(Var->getType()))
|
||||||
|
// Const isnt wrapped in the auto type, so must be declared explicitly.
|
||||||
|
return;
|
||||||
|
|
||||||
|
CharSourceRange FixItRange;
|
||||||
|
if (llvm::Optional<SourceRange> TypeSpec =
|
||||||
|
getTypeSpecifierLocation(Var, Result)) {
|
||||||
|
FixItRange = CharSourceRange::getCharRange(*TypeSpec);
|
||||||
|
if (FixItRange.isInvalid())
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
|
||||||
|
DiagnosticBuilder Diag =
|
||||||
|
diag(FixItRange.getBegin(),
|
||||||
|
"'auto &%0' can be declared as 'const auto &%0'")
|
||||||
|
<< Var->getName();
|
||||||
|
Diag << FixItHint::CreateReplacement(FixItRange, "const auto &");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace readability
|
||||||
|
} // namespace tidy
|
||||||
|
} // namespace clang
|
@ -0,0 +1,36 @@
|
|||||||
|
//===--- QualifiedAutoCheck.h - clang-tidy ----------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_QUALIFIEDAUTOCHECK_H
|
||||||
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_QUALIFIEDAUTOCHECK_H
|
||||||
|
|
||||||
|
#include "../ClangTidyCheck.h"
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
namespace tidy {
|
||||||
|
namespace readability {
|
||||||
|
|
||||||
|
/// Finds variables declared as auto that could be declared as:
|
||||||
|
/// 'auto*' or 'const auto *' and reference variables declared as:
|
||||||
|
/// 'const auto &'.
|
||||||
|
///
|
||||||
|
/// For the user-facing documentation see:
|
||||||
|
/// http://clang.llvm.org/extra/clang-tidy/checks/readability-qualified-auto.html
|
||||||
|
class QualifiedAutoCheck : public ClangTidyCheck {
|
||||||
|
public:
|
||||||
|
QualifiedAutoCheck(StringRef Name, ClangTidyContext *Context)
|
||||||
|
: ClangTidyCheck(Name, Context) {}
|
||||||
|
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
||||||
|
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace readability
|
||||||
|
} // namespace tidy
|
||||||
|
} // namespace clang
|
||||||
|
|
||||||
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_QUALIFIEDAUTOCHECK_H
|
@ -28,6 +28,7 @@
|
|||||||
#include "MisplacedArrayIndexCheck.h"
|
#include "MisplacedArrayIndexCheck.h"
|
||||||
#include "NamedParameterCheck.h"
|
#include "NamedParameterCheck.h"
|
||||||
#include "NonConstParameterCheck.h"
|
#include "NonConstParameterCheck.h"
|
||||||
|
#include "QualifiedAutoCheck.h"
|
||||||
#include "RedundantAccessSpecifiersCheck.h"
|
#include "RedundantAccessSpecifiersCheck.h"
|
||||||
#include "RedundantControlFlowCheck.h"
|
#include "RedundantControlFlowCheck.h"
|
||||||
#include "RedundantDeclarationCheck.h"
|
#include "RedundantDeclarationCheck.h"
|
||||||
@ -86,6 +87,8 @@ public:
|
|||||||
"readability-misleading-indentation");
|
"readability-misleading-indentation");
|
||||||
CheckFactories.registerCheck<MisplacedArrayIndexCheck>(
|
CheckFactories.registerCheck<MisplacedArrayIndexCheck>(
|
||||||
"readability-misplaced-array-index");
|
"readability-misplaced-array-index");
|
||||||
|
CheckFactories.registerCheck<QualifiedAutoCheck>(
|
||||||
|
"readability-qualified-auto");
|
||||||
CheckFactories.registerCheck<RedundantAccessSpecifiersCheck>(
|
CheckFactories.registerCheck<RedundantAccessSpecifiersCheck>(
|
||||||
"readability-redundant-access-specifiers");
|
"readability-redundant-access-specifiers");
|
||||||
CheckFactories.registerCheck<RedundantFunctionPtrDereferenceCheck>(
|
CheckFactories.registerCheck<RedundantFunctionPtrDereferenceCheck>(
|
||||||
|
@ -165,6 +165,12 @@ New checks
|
|||||||
Finds non-static member functions that can be made ``const``
|
Finds non-static member functions that can be made ``const``
|
||||||
because the functions don't use ``this`` in a non-const way.
|
because the functions don't use ``this`` in a non-const way.
|
||||||
|
|
||||||
|
- New :doc:`readability-qualified-auto
|
||||||
|
<clang-tidy/checks/readability-qualified-auto>` check.
|
||||||
|
|
||||||
|
Adds pointer and ``const`` qualifications to ``auto``-typed variables
|
||||||
|
that are deduced to pointers and ``const`` pointers.
|
||||||
|
|
||||||
- New :doc:`readability-redundant-access-specifiers
|
- New :doc:`readability-redundant-access-specifiers
|
||||||
<clang-tidy/checks/readability-redundant-access-specifiers>` check.
|
<clang-tidy/checks/readability-redundant-access-specifiers>` check.
|
||||||
|
|
||||||
@ -179,6 +185,11 @@ New aliases
|
|||||||
:doc:`bugprone-bad-signal-to-kill-thread
|
:doc:`bugprone-bad-signal-to-kill-thread
|
||||||
<clang-tidy/checks/bugprone-bad-signal-to-kill-thread>` was added.
|
<clang-tidy/checks/bugprone-bad-signal-to-kill-thread>` was added.
|
||||||
|
|
||||||
|
- New alias :doc:`llvm-qualified-auto
|
||||||
|
<clang-tidy/checks/llvm-qualified-auto>` to
|
||||||
|
:doc:`readability-qualified-auto
|
||||||
|
<clang-tidy/checks/readability-qualified-auto>` was added.
|
||||||
|
|
||||||
Changes in existing checks
|
Changes in existing checks
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -270,6 +270,7 @@ Clang-Tidy Checks
|
|||||||
`readability-misplaced-array-index <readability-misplaced-array-index.html>`_, "Yes"
|
`readability-misplaced-array-index <readability-misplaced-array-index.html>`_, "Yes"
|
||||||
`readability-named-parameter <readability-named-parameter.html>`_, "Yes"
|
`readability-named-parameter <readability-named-parameter.html>`_, "Yes"
|
||||||
`readability-non-const-parameter <readability-non-const-parameter.html>`_, "Yes"
|
`readability-non-const-parameter <readability-non-const-parameter.html>`_, "Yes"
|
||||||
|
`readability-qualified-auto <readability-qualified-auto.html>`_, "Yes"
|
||||||
`readability-redundant-access-specifiers <readability-redundant-access-specifiers.html>`_, "Yes"
|
`readability-redundant-access-specifiers <readability-redundant-access-specifiers.html>`_, "Yes"
|
||||||
`readability-redundant-control-flow <readability-redundant-control-flow.html>`_, "Yes"
|
`readability-redundant-control-flow <readability-redundant-control-flow.html>`_, "Yes"
|
||||||
`readability-redundant-declaration <readability-redundant-declaration.html>`_, "Yes"
|
`readability-redundant-declaration <readability-redundant-declaration.html>`_, "Yes"
|
||||||
@ -402,3 +403,4 @@ Clang-Tidy Checks
|
|||||||
`hicpp-use-nullptr <hicpp-use-nullptr.html>`_, `modernize-use-nullptr <modernize-use-nullptr.html>`_, "Yes"
|
`hicpp-use-nullptr <hicpp-use-nullptr.html>`_, `modernize-use-nullptr <modernize-use-nullptr.html>`_, "Yes"
|
||||||
`hicpp-use-override <hicpp-use-override.html>`_, `modernize-use-override <modernize-use-override.html>`_, "Yes"
|
`hicpp-use-override <hicpp-use-override.html>`_, `modernize-use-override <modernize-use-override.html>`_, "Yes"
|
||||||
`hicpp-vararg <hicpp-vararg.html>`_, `cppcoreguidelines-pro-type-vararg <cppcoreguidelines-pro-type-vararg.html>`_,
|
`hicpp-vararg <hicpp-vararg.html>`_, `cppcoreguidelines-pro-type-vararg <cppcoreguidelines-pro-type-vararg.html>`_,
|
||||||
|
`llvm-qualified-auto <llvm-qualified-auto.html>`_, `readability-qualified-auto <readability-qualified-auto.html>`_, "Yes"
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
.. title:: clang-tidy - llvm-qualified-auto
|
||||||
|
.. meta::
|
||||||
|
:http-equiv=refresh: 5;URL=readability-qualified-auto.html
|
||||||
|
|
||||||
|
llvm-qualified-auto
|
||||||
|
===================
|
||||||
|
|
||||||
|
The llvm-qualified-auto check is an alias, please see
|
||||||
|
`readability-qualified-auto <readability-qualified-auto.html>`_
|
||||||
|
for more information.
|
@ -0,0 +1,64 @@
|
|||||||
|
.. title:: clang-tidy - readability-qualified-auto
|
||||||
|
|
||||||
|
readability-qualified-auto
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Adds pointer and ``const`` qualifications to ``auto``-typed variables that are deduced
|
||||||
|
to pointers and ``const`` pointers.
|
||||||
|
|
||||||
|
`LLVM Coding Standards <https://llvm.org/docs/CodingStandards.html>`_ advises to
|
||||||
|
make it obvious if a ``auto`` typed variable is a pointer, constant pointer or
|
||||||
|
constant reference. This check will transform ``auto`` to ``auto *`` when the
|
||||||
|
type is deduced to be a pointer, as well as adding ``const`` when applicable to
|
||||||
|
``auto`` pointers or references
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
for (auto &Data : MutatableContainer) {
|
||||||
|
change(Data);
|
||||||
|
}
|
||||||
|
for (auto &Data : ConstantContainer) {
|
||||||
|
observe(Data);
|
||||||
|
}
|
||||||
|
for (auto Data : MutatablePtrContainer) {
|
||||||
|
change(*Data);
|
||||||
|
}
|
||||||
|
for (auto Data : ConstantPtrContainer) {
|
||||||
|
observe(*Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Would be transformed into:
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
for (auto &Data : MutatableContainer) {
|
||||||
|
change(Data);
|
||||||
|
}
|
||||||
|
for (const auto &Data : ConstantContainer) {
|
||||||
|
observe(Data);
|
||||||
|
}
|
||||||
|
for (auto *Data : MutatablePtrContainer) {
|
||||||
|
change(*Data);
|
||||||
|
}
|
||||||
|
for (const auto *Data : ConstantPtrContainer) {
|
||||||
|
observe(*Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Note const volatile qualified types will retain their const and volatile qualifiers.
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
const auto Foo = cast<int *>(Baz1);
|
||||||
|
const auto Bar = cast<const int *>(Baz2);
|
||||||
|
volatile auto FooBar = cast<int*>(Baz3);
|
||||||
|
|
||||||
|
Would be transformed into:
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
auto *const Foo = cast<int *>(Baz1);
|
||||||
|
const auto *const Bar = cast<const int *>(Baz2);
|
||||||
|
auto *volatile FooBar = cast<int*>(Baz3);
|
||||||
|
|
||||||
|
This check helps to enforce this `LLVM Coding Standards recommendation
|
||||||
|
<https://llvm.org/docs/CodingStandards.html#beware-unnecessary-copies-with-auto>`_.
|
@ -0,0 +1,49 @@
|
|||||||
|
// RUN: %check_clang_tidy %s readability-qualified-auto %t -- -- -std=c++20
|
||||||
|
namespace std {
|
||||||
|
template <typename T>
|
||||||
|
class vector { // dummy impl
|
||||||
|
T _data[1];
|
||||||
|
|
||||||
|
public:
|
||||||
|
T *begin() { return _data; }
|
||||||
|
const T *begin() const { return _data; }
|
||||||
|
T *end() { return &_data[1]; }
|
||||||
|
const T *end() const { return &_data[1]; }
|
||||||
|
unsigned size() const { return 0; }
|
||||||
|
};
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
std::vector<int> *getVec();
|
||||||
|
const std::vector<int> *getCVec();
|
||||||
|
void foo() {
|
||||||
|
if (auto X = getVec(); X->size() > 0) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'auto X' can be declared as 'auto *X'
|
||||||
|
// CHECK-FIXES: {{^}} if (auto *X = getVec(); X->size() > 0) {
|
||||||
|
}
|
||||||
|
switch (auto X = getVec(); X->size()) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 'auto X' can be declared as 'auto *X'
|
||||||
|
// CHECK-FIXES: {{^}} switch (auto *X = getVec(); X->size()) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (auto X = getVec(); auto Xi : *X) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto X' can be declared as 'auto *X'
|
||||||
|
// CHECK-FIXES: {{^}} for (auto *X = getVec(); auto Xi : *X) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void bar() {
|
||||||
|
if (auto X = getCVec(); X->size() > 0) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'auto X' can be declared as 'const auto *X'
|
||||||
|
// CHECK-FIXES: {{^}} if (const auto *X = getCVec(); X->size() > 0) {
|
||||||
|
}
|
||||||
|
switch (auto X = getCVec(); X->size()) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 'auto X' can be declared as 'const auto *X'
|
||||||
|
// CHECK-FIXES: {{^}} switch (const auto *X = getCVec(); X->size()) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (auto X = getCVec(); auto Xi : *X) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto X' can be declared as 'const auto *X'
|
||||||
|
// CHECK-FIXES: {{^}} for (const auto *X = getCVec(); auto Xi : *X) {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,240 @@
|
|||||||
|
// RUN: %check_clang_tidy %s readability-qualified-auto %t
|
||||||
|
|
||||||
|
namespace typedefs {
|
||||||
|
typedef int *MyPtr;
|
||||||
|
typedef int &MyRef;
|
||||||
|
typedef const int *CMyPtr;
|
||||||
|
typedef const int &CMyRef;
|
||||||
|
|
||||||
|
MyPtr getPtr();
|
||||||
|
MyRef getRef();
|
||||||
|
CMyPtr getCPtr();
|
||||||
|
CMyRef getCRef();
|
||||||
|
|
||||||
|
void foo() {
|
||||||
|
auto TdNakedPtr = getPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto TdNakedPtr' can be declared as 'auto *TdNakedPtr'
|
||||||
|
// CHECK-FIXES: {{^}} auto *TdNakedPtr = getPtr();
|
||||||
|
auto &TdNakedRef = getRef();
|
||||||
|
auto TdNakedRefDeref = getRef();
|
||||||
|
auto TdNakedCPtr = getCPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto TdNakedCPtr' can be declared as 'const auto *TdNakedCPtr'
|
||||||
|
// CHECK-FIXES: {{^}} const auto *TdNakedCPtr = getCPtr();
|
||||||
|
auto &TdNakedCRef = getCRef();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto &TdNakedCRef' can be declared as 'const auto &TdNakedCRef'
|
||||||
|
// CHECK-FIXES: {{^}} const auto &TdNakedCRef = getCRef();
|
||||||
|
auto TdNakedCRefDeref = getCRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace typedefs
|
||||||
|
|
||||||
|
namespace usings {
|
||||||
|
using MyPtr = int *;
|
||||||
|
using MyRef = int &;
|
||||||
|
using CMyPtr = const int *;
|
||||||
|
using CMyRef = const int &;
|
||||||
|
|
||||||
|
MyPtr getPtr();
|
||||||
|
MyRef getRef();
|
||||||
|
CMyPtr getCPtr();
|
||||||
|
CMyRef getCRef();
|
||||||
|
|
||||||
|
void foo() {
|
||||||
|
auto UNakedPtr = getPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto UNakedPtr' can be declared as 'auto *UNakedPtr'
|
||||||
|
// CHECK-FIXES: {{^}} auto *UNakedPtr = getPtr();
|
||||||
|
auto &UNakedRef = getRef();
|
||||||
|
auto UNakedRefDeref = getRef();
|
||||||
|
auto UNakedCPtr = getCPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto UNakedCPtr' can be declared as 'const auto *UNakedCPtr'
|
||||||
|
// CHECK-FIXES: {{^}} const auto *UNakedCPtr = getCPtr();
|
||||||
|
auto &UNakedCRef = getCRef();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto &UNakedCRef' can be declared as 'const auto &UNakedCRef'
|
||||||
|
// CHECK-FIXES: {{^}} const auto &UNakedCRef = getCRef();
|
||||||
|
auto UNakedCRefDeref = getCRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace usings
|
||||||
|
|
||||||
|
int getInt();
|
||||||
|
int *getIntPtr();
|
||||||
|
const int *getCIntPtr();
|
||||||
|
|
||||||
|
void foo() {
|
||||||
|
// make sure check disregards named types
|
||||||
|
int TypedInt = getInt();
|
||||||
|
int *TypedPtr = getIntPtr();
|
||||||
|
const int *TypedConstPtr = getCIntPtr();
|
||||||
|
int &TypedRef = *getIntPtr();
|
||||||
|
const int &TypedConstRef = *getCIntPtr();
|
||||||
|
|
||||||
|
// make sure check disregards auto types that aren't pointers or references
|
||||||
|
auto AutoInt = getInt();
|
||||||
|
|
||||||
|
auto NakedPtr = getIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto NakedPtr' can be declared as 'auto *NakedPtr'
|
||||||
|
// CHECK-FIXES: {{^}} auto *NakedPtr = getIntPtr();
|
||||||
|
auto NakedCPtr = getCIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto NakedCPtr' can be declared as 'const auto *NakedCPtr'
|
||||||
|
// CHECK-FIXES: {{^}} const auto *NakedCPtr = getCIntPtr();
|
||||||
|
|
||||||
|
const auto ConstPtr = getIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'const auto ConstPtr' can be declared as 'auto *const ConstPtr'
|
||||||
|
// CHECK-FIXES: {{^}} auto *const ConstPtr = getIntPtr();
|
||||||
|
const auto ConstCPtr = getCIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'const auto ConstCPtr' can be declared as 'const auto *const ConstCPtr'
|
||||||
|
// CHECK-FIXES: {{^}} const auto *const ConstCPtr = getCIntPtr();
|
||||||
|
|
||||||
|
volatile auto VolatilePtr = getIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'volatile auto VolatilePtr' can be declared as 'auto *volatile VolatilePtr'
|
||||||
|
// CHECK-FIXES: {{^}} auto *volatile VolatilePtr = getIntPtr();
|
||||||
|
volatile auto VolatileCPtr = getCIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'volatile auto VolatileCPtr' can be declared as 'const auto *volatile VolatileCPtr'
|
||||||
|
// CHECK-FIXES: {{^}} const auto *volatile VolatileCPtr = getCIntPtr();
|
||||||
|
|
||||||
|
auto *QualPtr = getIntPtr();
|
||||||
|
auto *QualCPtr = getCIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto *QualCPtr' can be declared as 'const auto *QualCPtr'
|
||||||
|
// CHECK-FIXES: {{^}} const auto *QualCPtr = getCIntPtr();
|
||||||
|
auto *const ConstantQualCPtr = getCIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto *const ConstantQualCPtr' can be declared as 'const auto *const ConstantQualCPtr'
|
||||||
|
// CHECK-FIXES: {{^}} const auto *const ConstantQualCPtr = getCIntPtr();
|
||||||
|
auto *volatile VolatileQualCPtr = getCIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto *volatile VolatileQualCPtr' can be declared as 'const auto *volatile VolatileQualCPtr'
|
||||||
|
// CHECK-FIXES: {{^}} const auto *volatile VolatileQualCPtr = getCIntPtr();
|
||||||
|
const auto *ConstQualCPtr = getCIntPtr();
|
||||||
|
|
||||||
|
auto &Ref = *getIntPtr();
|
||||||
|
auto &CRef = *getCIntPtr();
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'auto &CRef' can be declared as 'const auto &CRef'
|
||||||
|
// CHECK-FIXES: {{^}} const auto &CRef = *getCIntPtr();
|
||||||
|
const auto &ConstCRef = *getCIntPtr();
|
||||||
|
|
||||||
|
if (auto X = getCIntPtr()) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'auto X' can be declared as 'const auto *X'
|
||||||
|
// CHECK-FIXES: {{^}} if (const auto *X = getCIntPtr()) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void macroTest() {
|
||||||
|
#define _AUTO auto
|
||||||
|
#define _CONST const
|
||||||
|
_AUTO AutoMACROPtr = getIntPtr();
|
||||||
|
const _AUTO ConstAutoMacroPtr = getIntPtr();
|
||||||
|
_CONST _AUTO ConstMacroAutoMacroPtr = getIntPtr();
|
||||||
|
_CONST auto ConstMacroAutoPtr = getIntPtr();
|
||||||
|
#undef _AUTO
|
||||||
|
#undef _CONST
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <typename T>
|
||||||
|
class vector { // dummy impl
|
||||||
|
T _data[1];
|
||||||
|
|
||||||
|
public:
|
||||||
|
T *begin() { return _data; }
|
||||||
|
const T *begin() const { return _data; }
|
||||||
|
T *end() { return &_data[1]; }
|
||||||
|
const T *end() const { return &_data[1]; }
|
||||||
|
};
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
void change(int &);
|
||||||
|
void observe(const int &);
|
||||||
|
|
||||||
|
void loopRef(std::vector<int> &Mutate, const std::vector<int> &Constant) {
|
||||||
|
for (auto &Data : Mutate) {
|
||||||
|
change(Data);
|
||||||
|
}
|
||||||
|
for (auto &Data : Constant) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto &Data' can be declared as 'const auto &Data'
|
||||||
|
// CHECK-FIXES: {{^}} for (const auto &Data : Constant) {
|
||||||
|
observe(Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loopPtr(const std::vector<int *> &Mutate, const std::vector<const int *> &Constant) {
|
||||||
|
for (auto Data : Mutate) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto Data' can be declared as 'auto *Data'
|
||||||
|
// CHECK-FIXES: {{^}} for (auto *Data : Mutate) {
|
||||||
|
change(*Data);
|
||||||
|
}
|
||||||
|
for (auto Data : Constant) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto Data' can be declared as 'const auto *Data'
|
||||||
|
// CHECK-FIXES: {{^}} for (const auto *Data : Constant) {
|
||||||
|
observe(*Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void tempLoopPtr(std::vector<T *> &MutateTemplate, std::vector<const T *> &ConstantTemplate) {
|
||||||
|
for (auto Data : MutateTemplate) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto Data' can be declared as 'auto *Data'
|
||||||
|
// CHECK-FIXES: {{^}} for (auto *Data : MutateTemplate) {
|
||||||
|
change(*Data);
|
||||||
|
}
|
||||||
|
//FixMe
|
||||||
|
for (auto Data : ConstantTemplate) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'auto Data' can be declared as 'const auto *Data'
|
||||||
|
// CHECK-FIXES: {{^}} for (const auto *Data : ConstantTemplate) {
|
||||||
|
observe(*Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class TemplateLoopPtr {
|
||||||
|
public:
|
||||||
|
void operator()(const std::vector<T *> &MClassTemplate, const std::vector<const T *> &CClassTemplate) {
|
||||||
|
for (auto Data : MClassTemplate) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'auto Data' can be declared as 'auto *Data'
|
||||||
|
// CHECK-FIXES: {{^}} for (auto *Data : MClassTemplate) {
|
||||||
|
change(*Data);
|
||||||
|
}
|
||||||
|
//FixMe
|
||||||
|
for (auto Data : CClassTemplate) {
|
||||||
|
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'auto Data' can be declared as 'const auto *Data'
|
||||||
|
// CHECK-FIXES: {{^}} for (const auto *Data : CClassTemplate) {
|
||||||
|
observe(*Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void bar() {
|
||||||
|
std::vector<int> Vec;
|
||||||
|
std::vector<int *> PtrVec;
|
||||||
|
std::vector<const int *> CPtrVec;
|
||||||
|
loopRef(Vec, Vec);
|
||||||
|
loopPtr(PtrVec, CPtrVec);
|
||||||
|
tempLoopPtr(PtrVec, CPtrVec);
|
||||||
|
TemplateLoopPtr<int>()(PtrVec, CPtrVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int *(*functionRetPtr)();
|
||||||
|
typedef int (*functionRetVal)();
|
||||||
|
|
||||||
|
functionRetPtr getPtrFunction();
|
||||||
|
functionRetVal getValFunction();
|
||||||
|
|
||||||
|
void baz() {
|
||||||
|
auto MyFunctionPtr = getPtrFunction();
|
||||||
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto MyFunctionPtr' can be declared as 'auto *MyFunctionPtr'
|
||||||
|
// CHECK-FIXES-NOT: {{^}} auto *MyFunctionPtr = getPtrFunction();
|
||||||
|
auto MyFunctionVal = getValFunction();
|
||||||
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto MyFunctionVal' can be declared as 'auto *MyFunctionVal'
|
||||||
|
// CHECK-FIXES-NOT: {{^}} auto *MyFunctionVal = getValFunction();
|
||||||
|
|
||||||
|
auto LambdaTest = [] { return 0; };
|
||||||
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto LambdaTest' can be declared as 'auto *LambdaTest'
|
||||||
|
// CHECK-FIXES-NOT: {{^}} auto *LambdaTest = [] { return 0; };
|
||||||
|
|
||||||
|
auto LambdaTest2 = +[] { return 0; };
|
||||||
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto LambdaTest2' can be declared as 'auto *LambdaTest2'
|
||||||
|
// CHECK-FIXES-NOT: {{^}} auto *LambdaTest2 = +[] { return 0; };
|
||||||
|
|
||||||
|
auto MyFunctionRef = *getPtrFunction();
|
||||||
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: 'auto MyFunctionRef' can be declared as 'auto *MyFunctionRef'
|
||||||
|
// CHECK-FIXES-NOT: {{^}} auto *MyFunctionRef = *getPtrFunction();
|
||||||
|
|
||||||
|
auto &MyFunctionRef2 = *getPtrFunction();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user