Skip to content

Commit 9f8b3e0

Browse files
author
Erich Keane
committed
Merge from 'master' to 'sycl-web' (#6)
CONFLICT (content): Merge conflict in clang/lib/CodeGen/CGClass.cpp
2 parents b8b9c2c + 51e09e1 commit 9f8b3e0

File tree

1,414 files changed

+36810
-10298
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,414 files changed

+36810
-10298
lines changed

clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ void SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
7777
}
7878

7979
void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
80+
// FIXME:
81+
// Some of the checks should not match in template code to avoid false
82+
// positives if sizeof is applied on template argument.
83+
8084
const auto IntegerExpr = ignoringParenImpCasts(integerLiteral());
8185
const auto ConstantExpr = expr(ignoringParenImpCasts(
8286
anyOf(integerLiteral(), unaryOperator(hasUnaryOperand(IntegerExpr)),
@@ -132,6 +136,7 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
132136
this);
133137

134138
// Detect sizeof(ptr) where ptr points to an aggregate (i.e. sizeof(&S)).
139+
// Do not find it if RHS of a 'sizeof(arr) / sizeof(arr[0])' expression.
135140
const auto ArrayExpr = expr(ignoringParenImpCasts(
136141
expr(hasType(qualType(hasCanonicalType(arrayType()))))));
137142
const auto ArrayCastExpr = expr(anyOf(
@@ -151,13 +156,31 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
151156
hasType(qualType(hasCanonicalType(PointerToStructType))),
152157
unless(cxxThisExpr()))));
153158

154-
Finder->addMatcher(
155-
expr(anyOf(sizeOfExpr(has(expr(ignoringParenImpCasts(
156-
anyOf(ArrayCastExpr, PointerToArrayExpr, StructAddrOfExpr,
157-
PointerToStructExpr))))),
158-
sizeOfExpr(has(PointerToStructType))))
159-
.bind("sizeof-pointer-to-aggregate"),
160-
this);
159+
const auto ArrayOfPointersExpr = expr(ignoringParenImpCasts(expr(hasType(
160+
qualType(hasCanonicalType(arrayType(hasElementType(pointerType()))
161+
.bind("type-of-array-of-pointers")))))));
162+
const auto ArrayOfSamePointersExpr =
163+
expr(ignoringParenImpCasts(expr(hasType(qualType(hasCanonicalType(
164+
arrayType(equalsBoundNode("type-of-array-of-pointers"))))))));
165+
const auto ZeroLiteral =
166+
expr(ignoringParenImpCasts(integerLiteral(equals(0))));
167+
const auto ArrayOfSamePointersZeroSubscriptExpr =
168+
expr(ignoringParenImpCasts(arraySubscriptExpr(
169+
hasBase(ArrayOfSamePointersExpr), hasIndex(ZeroLiteral))));
170+
const auto ArrayLengthExprDenom =
171+
expr(hasParent(expr(ignoringParenImpCasts(
172+
binaryOperator(hasOperatorName("/"),
173+
hasLHS(expr(ignoringParenImpCasts(expr(
174+
sizeOfExpr(has(ArrayOfPointersExpr)))))))))),
175+
sizeOfExpr(has(ArrayOfSamePointersZeroSubscriptExpr)));
176+
177+
Finder->addMatcher(expr(anyOf(sizeOfExpr(has(expr(ignoringParenImpCasts(anyOf(
178+
ArrayCastExpr, PointerToArrayExpr,
179+
StructAddrOfExpr, PointerToStructExpr))))),
180+
sizeOfExpr(has(PointerToStructType))),
181+
unless(ArrayLengthExprDenom))
182+
.bind("sizeof-pointer-to-aggregate"),
183+
this);
161184

162185
// Detect expression like: sizeof(epxr) <= k for a suspicious constant 'k'.
163186
if (WarnOnSizeOfCompareToConstant) {
@@ -178,6 +201,12 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
178201
this);
179202

180203
// Detect sizeof(...) /sizeof(...));
204+
// FIXME:
205+
// Re-evaluate what cases to handle by the checker.
206+
// Probably any sizeof(A)/sizeof(B) should be error if
207+
// 'A' is not an array (type) and 'B' the (type of the) first element of it.
208+
// Except if 'A' and 'B' are non-pointers, then use the existing size division
209+
// rule.
181210
const auto ElemType =
182211
arrayType(hasElementType(recordType().bind("elem-type")));
183212
const auto ElemPtrType = pointerType(pointee(type().bind("elem-ptr-type")));

clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "StringConstructorCheck.h"
10+
#include "../utils/OptionsUtils.h"
1011
#include "clang/AST/ASTContext.h"
1112
#include "clang/ASTMatchers/ASTMatchFinder.h"
1213
#include "clang/Tooling/FixIt.h"
@@ -21,17 +22,36 @@ namespace {
2122
AST_MATCHER_P(IntegerLiteral, isBiggerThan, unsigned, N) {
2223
return Node.getValue().getZExtValue() > N;
2324
}
25+
26+
const char DefaultStringNames[] =
27+
"::std::basic_string;::std::basic_string_view";
28+
29+
static std::vector<StringRef>
30+
removeNamespaces(const std::vector<std::string> &Names) {
31+
std::vector<StringRef> Result;
32+
Result.reserve(Names.size());
33+
for (StringRef Name : Names) {
34+
std::string::size_type ColonPos = Name.rfind(':');
35+
Result.push_back(
36+
Name.substr(ColonPos == std::string::npos ? 0 : ColonPos + 1));
37+
}
38+
return Result;
39+
}
40+
2441
} // namespace
2542

2643
StringConstructorCheck::StringConstructorCheck(StringRef Name,
2744
ClangTidyContext *Context)
2845
: ClangTidyCheck(Name, Context),
2946
WarnOnLargeLength(Options.get("WarnOnLargeLength", true)),
30-
LargeLengthThreshold(Options.get("LargeLengthThreshold", 0x800000)) {}
47+
LargeLengthThreshold(Options.get("LargeLengthThreshold", 0x800000)),
48+
StringNames(utils::options::parseStringList(
49+
Options.get("StringNames", DefaultStringNames))) {}
3150

3251
void StringConstructorCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
3352
Options.store(Opts, "WarnOnLargeLength", WarnOnLargeLength);
3453
Options.store(Opts, "LargeLengthThreshold", LargeLengthThreshold);
54+
Options.store(Opts, "StringNames", DefaultStringNames);
3555
}
3656

3757
void StringConstructorCheck::registerMatchers(MatchFinder *Finder) {
@@ -80,7 +100,8 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) {
80100
// parameters. [i.e. string (const char* s, size_t n);]
81101
Finder->addMatcher(
82102
cxxConstructExpr(
83-
hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
103+
hasDeclaration(cxxConstructorDecl(ofClass(
104+
cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)))))),
84105
hasArgument(0, hasType(CharPtrType)),
85106
hasArgument(1, hasType(isInteger())),
86107
anyOf(
@@ -100,11 +121,17 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) {
100121
// Check the literal string constructor with char pointer.
101122
// [i.e. string (const char* s);]
102123
Finder->addMatcher(
103-
traverse(TK_AsIs,
104-
cxxConstructExpr(hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
105-
hasArgument(0, expr().bind("from-ptr")),
106-
hasArgument(1, unless(hasType(isInteger()))))
107-
.bind("constructor")),
124+
traverse(TK_AsIs,
125+
cxxConstructExpr(
126+
hasDeclaration(cxxConstructorDecl(ofClass(cxxRecordDecl(
127+
hasAnyName(removeNamespaces(StringNames)))))),
128+
hasArgument(0, expr().bind("from-ptr")),
129+
// do not match std::string(ptr, int)
130+
// match std::string(ptr, alloc)
131+
// match std::string(ptr)
132+
anyOf(hasArgument(1, unless(hasType(isInteger()))),
133+
argumentCountIs(1)))
134+
.bind("constructor")),
108135
this);
109136
}
110137

clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class StringConstructorCheck : public ClangTidyCheck {
3232
private:
3333
const bool WarnOnLargeLength;
3434
const unsigned int LargeLengthThreshold;
35+
std::vector<std::string> StringNames;
3536
};
3637

3738
} // namespace bugprone

clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp

Lines changed: 96 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "clang/AST/ASTContext.h"
1111
#include "clang/ASTMatchers/ASTMatchFinder.h"
1212
#include "clang/Lex/Lexer.h"
13+
#include "clang/Lex/Preprocessor.h"
1314
#include "clang/Tooling/FixIt.h"
1415
#include "llvm/ADT/SmallVector.h"
1516

@@ -19,10 +20,30 @@ namespace clang {
1920
namespace tidy {
2021
namespace readability {
2122

22-
static const char ReturnStr[] = "return";
23-
static const char ContinueStr[] = "continue";
24-
static const char BreakStr[] = "break";
25-
static const char ThrowStr[] = "throw";
23+
namespace {
24+
25+
class PPConditionalCollector : public PPCallbacks {
26+
public:
27+
PPConditionalCollector(
28+
ElseAfterReturnCheck::ConditionalBranchMap &Collections,
29+
const SourceManager &SM)
30+
: Collections(Collections), SM(SM) {}
31+
void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
32+
if (!SM.isWrittenInSameFile(Loc, IfLoc))
33+
return;
34+
SmallVectorImpl<SourceRange> &Collection = Collections[SM.getFileID(Loc)];
35+
assert(Collection.empty() || Collection.back().getEnd() < Loc);
36+
Collection.emplace_back(IfLoc, Loc);
37+
}
38+
39+
private:
40+
ElseAfterReturnCheck::ConditionalBranchMap &Collections;
41+
const SourceManager &SM;
42+
};
43+
44+
} // namespace
45+
46+
static const char InterruptingStr[] = "interrupting";
2647
static const char WarningMessage[] = "do not use 'else' after '%0'";
2748
static const char WarnOnUnfixableStr[] = "WarnOnUnfixable";
2849
static const char WarnOnConditionVariablesStr[] = "WarnOnConditionVariables";
@@ -140,11 +161,18 @@ void ElseAfterReturnCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
140161
Options.store(Opts, WarnOnConditionVariablesStr, WarnOnConditionVariables);
141162
}
142163

164+
void ElseAfterReturnCheck::registerPPCallbacks(const SourceManager &SM,
165+
Preprocessor *PP,
166+
Preprocessor *ModuleExpanderPP) {
167+
PP->addPPCallbacks(
168+
std::make_unique<PPConditionalCollector>(this->PPConditionals, SM));
169+
}
170+
143171
void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {
144-
const auto InterruptsControlFlow =
145-
stmt(anyOf(returnStmt().bind(ReturnStr), continueStmt().bind(ContinueStr),
146-
breakStmt().bind(BreakStr),
147-
expr(ignoringImplicit(cxxThrowExpr().bind(ThrowStr)))));
172+
const auto InterruptsControlFlow = stmt(anyOf(
173+
returnStmt().bind(InterruptingStr), continueStmt().bind(InterruptingStr),
174+
breakStmt().bind(InterruptingStr),
175+
expr(ignoringImplicit(cxxThrowExpr().bind(InterruptingStr)))));
148176
Finder->addMatcher(
149177
compoundStmt(
150178
forEach(ifStmt(unless(isConstexpr()),
@@ -157,21 +185,72 @@ void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {
157185
this);
158186
}
159187

188+
static bool hasPreprocessorBranchEndBetweenLocations(
189+
const ElseAfterReturnCheck::ConditionalBranchMap &ConditionalBranchMap,
190+
const SourceManager &SM, SourceLocation StartLoc, SourceLocation EndLoc) {
191+
192+
SourceLocation ExpandedStartLoc = SM.getExpansionLoc(StartLoc);
193+
SourceLocation ExpandedEndLoc = SM.getExpansionLoc(EndLoc);
194+
if (!SM.isWrittenInSameFile(ExpandedStartLoc, ExpandedEndLoc))
195+
return false;
196+
197+
// StartLoc and EndLoc expand to the same macro.
198+
if (ExpandedStartLoc == ExpandedEndLoc)
199+
return false;
200+
201+
assert(ExpandedStartLoc < ExpandedEndLoc);
202+
203+
auto Iter = ConditionalBranchMap.find(SM.getFileID(ExpandedEndLoc));
204+
205+
if (Iter == ConditionalBranchMap.end() || Iter->getSecond().empty())
206+
return false;
207+
208+
const SmallVectorImpl<SourceRange> &ConditionalBranches = Iter->getSecond();
209+
210+
assert(llvm::is_sorted(ConditionalBranches,
211+
[](const SourceRange &LHS, const SourceRange &RHS) {
212+
return LHS.getEnd() < RHS.getEnd();
213+
}));
214+
215+
// First conditional block that ends after ExpandedStartLoc.
216+
const auto *Begin =
217+
llvm::lower_bound(ConditionalBranches, ExpandedStartLoc,
218+
[](const SourceRange &LHS, const SourceLocation &RHS) {
219+
return LHS.getEnd() < RHS;
220+
});
221+
const auto *End = ConditionalBranches.end();
222+
for (; Begin != End && Begin->getEnd() < ExpandedEndLoc; ++Begin)
223+
if (Begin->getBegin() < ExpandedStartLoc)
224+
return true;
225+
return false;
226+
}
227+
228+
static StringRef getControlFlowString(const Stmt &Stmt) {
229+
if (isa<ReturnStmt>(Stmt))
230+
return "return";
231+
if (isa<ContinueStmt>(Stmt))
232+
return "continue";
233+
if (isa<BreakStmt>(Stmt))
234+
return "break";
235+
if (isa<CXXThrowExpr>(Stmt))
236+
return "throw";
237+
llvm_unreachable("Unknown control flow interruptor");
238+
}
239+
160240
void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) {
161241
const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
162242
const auto *Else = Result.Nodes.getNodeAs<Stmt>("else");
163243
const auto *OuterScope = Result.Nodes.getNodeAs<CompoundStmt>("cs");
164-
165-
bool IsLastInScope = OuterScope->body_back() == If;
244+
const auto *Interrupt = Result.Nodes.getNodeAs<Stmt>(InterruptingStr);
166245
SourceLocation ElseLoc = If->getElseLoc();
167246

168-
auto ControlFlowInterruptor = [&]() -> llvm::StringRef {
169-
for (llvm::StringRef BindingName :
170-
{ReturnStr, ContinueStr, BreakStr, ThrowStr})
171-
if (Result.Nodes.getNodeAs<Stmt>(BindingName))
172-
return BindingName;
173-
return {};
174-
}();
247+
if (hasPreprocessorBranchEndBetweenLocations(
248+
PPConditionals, *Result.SourceManager, Interrupt->getBeginLoc(),
249+
ElseLoc))
250+
return;
251+
252+
bool IsLastInScope = OuterScope->body_back() == If;
253+
StringRef ControlFlowInterruptor = getControlFlowString(*Interrupt);
175254

176255
if (!IsLastInScope && containsDeclInScope(Else)) {
177256
if (WarnOnUnfixable) {

clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ELSEAFTERRETURNCHECK_H
1111

1212
#include "../ClangTidyCheck.h"
13+
#include "llvm/ADT/DenseMap.h"
1314

1415
namespace clang {
1516
namespace tidy {
@@ -23,12 +24,18 @@ class ElseAfterReturnCheck : public ClangTidyCheck {
2324
ElseAfterReturnCheck(StringRef Name, ClangTidyContext *Context);
2425

2526
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
27+
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
28+
Preprocessor *ModuleExpanderPP) override;
2629
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
2730
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
2831

32+
using ConditionalBranchMap =
33+
llvm::DenseMap<FileID, SmallVector<SourceRange, 1>>;
34+
2935
private:
3036
const bool WarnOnUnfixable;
3137
const bool WarnOnConditionVariables;
38+
ConditionalBranchMap PPConditionals;
3239
};
3340

3441
} // namespace readability

clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ namespace clang {
1818
namespace tidy {
1919
namespace readability {
2020

21-
const char DefaultStringNames[] = "::std::basic_string";
21+
const char DefaultStringNames[] =
22+
"::std::basic_string_view;::std::basic_string";
2223

2324
static ast_matchers::internal::Matcher<NamedDecl>
2425
hasAnyNameStdString(std::vector<std::string> Names) {

0 commit comments

Comments
 (0)