Skip to content
This repository was archived by the owner on Oct 24, 2019. It is now read-only.

Commit f6ae6ad

Browse files
committed
Merge remote-tracking branch 'origin/swift-5.1-branch' into stable
2 parents 3ca8cf0 + 61879a5 commit f6ae6ad

File tree

23 files changed

+382
-81
lines changed

23 files changed

+382
-81
lines changed

include/clang/Basic/PlistSupport.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,11 @@ inline void EmitRange(raw_ostream &o, const SourceManager &SM,
128128
assert(R.isCharRange() && "cannot handle a token range");
129129
Indent(o, indent) << "<array>\n";
130130
EmitLocation(o, SM, R.getBegin(), FM, indent + 1);
131-
EmitLocation(o, SM, R.getEnd(), FM, indent + 1);
131+
132+
// The ".getLocWithOffset(-1)" emulates the behavior of an off-by-one bug
133+
// in Lexer that is already fixed. It is here for backwards compatibility
134+
// even though it is incorrect.
135+
EmitLocation(o, SM, R.getEnd().getLocWithOffset(-1), FM, indent + 1);
132136
Indent(o, indent) << "</array>\n";
133137
}
134138

include/clang/Lex/Lexer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ class Lexer : public PreprocessorLexer {
385385
SourceLocation End = getLocForEndOfToken(Range.getEnd(), 0, SM, LangOpts);
386386
return End.isInvalid() ? CharSourceRange()
387387
: CharSourceRange::getCharRange(
388-
Range.getBegin(), End.getLocWithOffset(-1));
388+
Range.getBegin(), End);
389389
}
390390
static CharSourceRange getAsCharRange(CharSourceRange Range,
391391
const SourceManager &SM,

include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,10 @@ def CXXSelfAssignmentChecker : Checker<"SelfAssignment">,
445445
HelpText<"Checks C++ copy and move assignment operators for self assignment">,
446446
Documentation<NotDocumented>;
447447

448+
def SmartPtrModeling: Checker<"SmartPtr">,
449+
HelpText<"Model behavior of C++ smart pointers">,
450+
Documentation<NotDocumented>;
451+
448452
def MoveChecker: Checker<"Move">,
449453
HelpText<"Find use-after-move bugs in C++">,
450454
Documentation<HasDocumentation>;

include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ class PathDiagnosticLocation {
314314

315315
bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; }
316316

317+
bool hasValidLocation() const { return asLocation().isValid(); }
318+
317319
void invalidate() {
318320
*this = PathDiagnosticLocation();
319321
}
@@ -469,7 +471,7 @@ class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
469471
PathDiagnosticPiece::Kind k,
470472
bool addPosRange = true)
471473
: PathDiagnosticPiece(s, k), Pos(pos) {
472-
assert(Pos.isValid() && Pos.asLocation().isValid() &&
474+
assert(Pos.isValid() && Pos.hasValidLocation() &&
473475
"PathDiagnosticSpotPiece's must have a valid location.");
474476
if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
475477
}

lib/Analysis/BodyFarm.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,8 +666,6 @@ static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D)
666666
}
667667

668668
Stmt *BodyFarm::getBody(const FunctionDecl *D) {
669-
D = D->getCanonicalDecl();
670-
671669
Optional<Stmt *> &Val = Bodies[D];
672670
if (Val.hasValue())
673671
return Val.getValue();

lib/Analysis/RetainSummaryManager.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -229,29 +229,36 @@ RetainSummaryManager::isKnownSmartPointer(QualType QT) {
229229
const RetainSummary *
230230
RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD,
231231
StringRef FName, QualType RetTy) {
232+
assert(TrackOSObjects &&
233+
"Requesting a summary for an OSObject but OSObjects are not tracked");
234+
232235
if (RetTy->isPointerType()) {
233236
const CXXRecordDecl *PD = RetTy->getPointeeType()->getAsCXXRecordDecl();
234237
if (PD && isOSObjectSubclass(PD)) {
235-
if (const IdentifierInfo *II = FD->getIdentifier()) {
236-
StringRef FuncName = II->getName();
237-
if (isOSObjectDynamicCast(FuncName) || isOSObjectThisCast(FuncName))
238-
return getDefaultSummary();
239-
240-
// All objects returned with functions *not* starting with
241-
// get, or iterators, are returned at +1.
242-
if ((!FuncName.startswith("get") && !FuncName.startswith("Get")) ||
243-
isOSIteratorSubclass(PD)) {
244-
return getOSSummaryCreateRule(FD);
245-
} else {
246-
return getOSSummaryGetRule(FD);
247-
}
238+
if (isOSObjectDynamicCast(FName) || isOSObjectThisCast(FName))
239+
return getDefaultSummary();
240+
241+
// TODO: Add support for the slightly common *Matching(table) idiom.
242+
// Cf. IOService::nameMatching() etc. - these function have an unusual
243+
// contract of returning at +0 or +1 depending on their last argument.
244+
if (FName.endswith("Matching")) {
245+
return getPersistentStopSummary();
246+
}
247+
248+
// All objects returned with functions *not* starting with 'get',
249+
// or iterators, are returned at +1.
250+
if ((!FName.startswith("get") && !FName.startswith("Get")) ||
251+
isOSIteratorSubclass(PD)) {
252+
return getOSSummaryCreateRule(FD);
253+
} else {
254+
return getOSSummaryGetRule(FD);
248255
}
249256
}
250257
}
251258

252259
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
253260
const CXXRecordDecl *Parent = MD->getParent();
254-
if (TrackOSObjects && Parent && isOSObjectSubclass(Parent)) {
261+
if (Parent && isOSObjectSubclass(Parent)) {
255262
if (FName == "release" || FName == "taggedRelease")
256263
return getOSSummaryReleaseRule(FD);
257264

lib/Frontend/FrontendAction.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,6 @@ static std::error_code collectModuleHeaderIncludes(
344344
llvm::sys::path::native(UmbrellaDir.Entry->getName(), DirNative);
345345

346346
llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
347-
SmallVector<std::pair<std::string, const FileEntry *>, 8> Headers;
348347
for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
349348
Dir != End && !EC; Dir.increment(EC)) {
350349
// Check whether this entry has an extension typically associated with
@@ -375,20 +374,13 @@ static std::error_code collectModuleHeaderIncludes(
375374
++It)
376375
llvm::sys::path::append(RelativeHeader, *It);
377376

378-
Headers.push_back(std::make_pair(RelativeHeader.str(), Header));
377+
// Include this header as part of the umbrella directory.
378+
Module->addTopHeader(Header);
379+
addHeaderInclude(RelativeHeader, Includes, LangOpts, Module->IsExternC);
379380
}
380381

381382
if (EC)
382383
return EC;
383-
384-
// Sort header paths and make the header inclusion order deterministic
385-
// across different OSs and filesystems.
386-
llvm::array_pod_sort(Headers.begin(), Headers.end());
387-
for (auto &H : Headers) {
388-
// Include this header as part of the umbrella directory.
389-
Module->addTopHeader(H.second);
390-
addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC);
391-
}
392384
}
393385

394386
// Recurse into submodules.

lib/StaticAnalyzer/Checkers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ add_clang_library(clangStaticAnalyzerCheckers
8383
ReturnUndefChecker.cpp
8484
RunLoopAutoreleaseLeakChecker.cpp
8585
SimpleStreamChecker.cpp
86+
SmartPtrModeling.cpp
8687
StackAddrEscapeChecker.cpp
8788
StdLibraryFunctionsChecker.cpp
8889
StreamChecker.cpp

lib/StaticAnalyzer/Checkers/Move.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//=== Move.h - Tracking moved-from objects. ------------------------*- C++ -*-//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Defines inter-checker API for the use-after-move checker. It allows
10+
// dependent checkers to figure out if an object is in a moved-from state.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MOVE_H
15+
#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MOVE_H
16+
17+
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
18+
19+
namespace clang {
20+
namespace ento {
21+
namespace move {
22+
23+
/// Returns true if the object is known to have been recently std::moved.
24+
bool isMovedFrom(ProgramStateRef State, const MemRegion *Region);
25+
26+
} // namespace move
27+
} // namespace ento
28+
} // namespace clang
29+
30+
#endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MOVE_H

lib/StaticAnalyzer/Checkers/MoveChecker.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,18 @@ class MoveChecker
223223

224224
REGISTER_MAP_WITH_PROGRAMSTATE(TrackedRegionMap, const MemRegion *, RegionState)
225225

226+
// Define the inter-checker API.
227+
namespace clang {
228+
namespace ento {
229+
namespace move {
230+
bool isMovedFrom(ProgramStateRef State, const MemRegion *Region) {
231+
const RegionState *RS = State->get<TrackedRegionMap>(Region);
232+
return RS && (RS->isMoved() || RS->isReported());
233+
}
234+
} // namespace move
235+
} // namespace ento
236+
} // namespace clang
237+
226238
// If a region is removed all of the subregions needs to be removed too.
227239
static ProgramStateRef removeFromState(ProgramStateRef State,
228240
const MemRegion *Region) {

0 commit comments

Comments
 (0)