forked from OSchip/llvm-project
Fix readability-const-return-type identifying the wrong `const` token
Replace tidy::utils::lexer::getConstQualifyingToken with a corrected and also generalized to other qualifiers variant - getQualifyingToken. Fixes PR44326
This commit is contained in:
parent
c16b3ec597
commit
f58f39137c
|
@ -47,8 +47,8 @@ findConstToRemove(const FunctionDecl *Def,
|
|||
if (FileRange.isInvalid())
|
||||
return None;
|
||||
|
||||
return utils::lexer::getConstQualifyingToken(FileRange, *Result.Context,
|
||||
*Result.SourceManager);
|
||||
return utils::lexer::getQualifyingToken(
|
||||
tok::kw_const, FileRange, *Result.Context, *Result.SourceManager);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -102,15 +102,20 @@ bool rangeContainsExpansionsOrDirectives(SourceRange Range,
|
|||
return false;
|
||||
}
|
||||
|
||||
llvm::Optional<Token> getConstQualifyingToken(CharSourceRange Range,
|
||||
const ASTContext &Context,
|
||||
const SourceManager &SM) {
|
||||
llvm::Optional<Token> getQualifyingToken(tok::TokenKind TK,
|
||||
CharSourceRange Range,
|
||||
const ASTContext &Context,
|
||||
const SourceManager &SM) {
|
||||
assert((TK == tok::kw_const || TK == tok::kw_volatile ||
|
||||
TK == tok::kw_restrict) &&
|
||||
"TK is not a qualifier keyword");
|
||||
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Range.getBegin());
|
||||
StringRef File = SM.getBufferData(LocInfo.first);
|
||||
Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(),
|
||||
File.begin(), File.data() + LocInfo.second, File.end());
|
||||
llvm::Optional<Token> FirstConstTok;
|
||||
Token LastTokInRange;
|
||||
llvm::Optional<Token> LastMatchBeforeTemplate;
|
||||
llvm::Optional<Token> LastMatchAfterTemplate;
|
||||
bool SawTemplate = false;
|
||||
Token Tok;
|
||||
while (!RawLexer.LexFromRawLexer(Tok) &&
|
||||
Range.getEnd() != Tok.getLocation() &&
|
||||
|
@ -121,13 +126,19 @@ llvm::Optional<Token> getConstQualifyingToken(CharSourceRange Range,
|
|||
Tok.setIdentifierInfo(&Info);
|
||||
Tok.setKind(Info.getTokenID());
|
||||
}
|
||||
if (Tok.is(tok::kw_const) && !FirstConstTok)
|
||||
FirstConstTok = Tok;
|
||||
LastTokInRange = Tok;
|
||||
if (Tok.is(tok::less))
|
||||
SawTemplate = true;
|
||||
else if (Tok.isOneOf(tok::greater, tok::greatergreater))
|
||||
LastMatchAfterTemplate = None;
|
||||
else if (Tok.is(TK)) {
|
||||
if (SawTemplate)
|
||||
LastMatchAfterTemplate = Tok;
|
||||
else
|
||||
LastMatchBeforeTemplate = Tok;
|
||||
}
|
||||
}
|
||||
// If the last token in the range is a `const`, then it const qualifies the
|
||||
// type. Otherwise, the first `const` token, if any, is the qualifier.
|
||||
return LastTokInRange.is(tok::kw_const) ? LastTokInRange : FirstConstTok;
|
||||
return LastMatchAfterTemplate != None ? LastMatchAfterTemplate
|
||||
: LastMatchBeforeTemplate;
|
||||
}
|
||||
} // namespace lexer
|
||||
} // namespace utils
|
||||
|
|
|
@ -92,13 +92,15 @@ bool rangeContainsExpansionsOrDirectives(SourceRange Range,
|
|||
const SourceManager &SM,
|
||||
const LangOptions &LangOpts);
|
||||
|
||||
/// Assuming that ``Range`` spans a const-qualified type, returns the ``const``
|
||||
/// token in ``Range`` that is responsible for const qualification. ``Range``
|
||||
/// must be valid with respect to ``SM``. Returns ``None`` if no ``const``
|
||||
/// Assuming that ``Range`` spans a CVR-qualified type, returns the
|
||||
/// token in ``Range`` that is responsible for the qualification. ``Range``
|
||||
/// must be valid with respect to ``SM``. Returns ``None`` if no qualifying
|
||||
/// tokens are found.
|
||||
llvm::Optional<Token> getConstQualifyingToken(CharSourceRange Range,
|
||||
const ASTContext &Context,
|
||||
const SourceManager &SM);
|
||||
/// \note: doesn't support member function qualifiers.
|
||||
llvm::Optional<Token> getQualifyingToken(tok::TokenKind TK,
|
||||
CharSourceRange Range,
|
||||
const ASTContext &Context,
|
||||
const SourceManager &SM);
|
||||
|
||||
} // namespace lexer
|
||||
} // namespace utils
|
||||
|
|
|
@ -37,6 +37,9 @@ const T p32(T t) { return t; }
|
|||
template <typename T>
|
||||
typename std::add_const<T>::type n15(T v) { return v; }
|
||||
|
||||
template <bool B>
|
||||
struct MyStruct {};
|
||||
|
||||
template <typename A>
|
||||
class Klazz {
|
||||
public:
|
||||
|
@ -128,10 +131,46 @@ const Klazz<const int> p12() {}
|
|||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const int>'
|
||||
// CHECK-FIXES: Klazz<const int> p12() {}
|
||||
|
||||
const Klazz<const Klazz<const int>> p33() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<
|
||||
// CHECK-FIXES: Klazz<const Klazz<const int>> p33() {}
|
||||
|
||||
const Klazz<const int>* const p13() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const int> *
|
||||
// CHECK-FIXES: const Klazz<const int>* p13() {}
|
||||
|
||||
const Klazz<const int>* const volatile p14() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const int> *
|
||||
// CHECK-FIXES: const Klazz<const int>* volatile p14() {}
|
||||
|
||||
const MyStruct<0 < 1> p34() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const MyStruct<0 < 1>'
|
||||
// CHECK-FIXES: MyStruct<0 < 1> p34() {}
|
||||
|
||||
MyStruct<0 < 1> const p35() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const MyStruct<0 < 1>'
|
||||
// CHECK-FIXES: MyStruct<0 < 1> p35() {}
|
||||
|
||||
Klazz<MyStruct<0 < 1> const> const p36() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const MyStru
|
||||
// CHECK-FIXES: Klazz<MyStruct<0 < 1> const> p36() {}
|
||||
|
||||
const Klazz<MyStruct<0 < 1> const> *const p37() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const MyStru
|
||||
// CHECK-FIXES: const Klazz<MyStruct<0 < 1> const> *p37() {}
|
||||
|
||||
Klazz<const MyStruct<0 < 1>> const p38() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const MyStru
|
||||
// CHECK-FIXES: Klazz<const MyStruct<0 < 1>> p38() {}
|
||||
|
||||
const Klazz<const MyStruct<0 < 1>> p39() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<
|
||||
// CHECK-FIXES: Klazz<const MyStruct<0 < 1>> p39() {}
|
||||
|
||||
const Klazz<const MyStruct<(0 > 1)>> p40() {}
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const MyStru
|
||||
// CHECK-FIXES: Klazz<const MyStruct<(0 > 1)>> p40() {}
|
||||
|
||||
// re-declaration of p15.
|
||||
const int p15();
|
||||
// CHECK-FIXES: int p15();
|
||||
|
|
Loading…
Reference in New Issue