Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit f6e68ee

Browse files
committed
Merge remote-tracking branch 'origin/swift-5.1-branch' into stable
2 parents 2c09040 + c72b1b5 commit f6e68ee

18 files changed

+119
-39
lines changed

include/clang/Driver/CC1Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,8 @@ def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">;
385385

386386
def sys_header_deps : Flag<["-"], "sys-header-deps">,
387387
HelpText<"Include system headers in dependency output">;
388+
def skip_unused_modulemap_file_deps : Flag<["-"], "skip-unused-modulemap-deps">,
389+
HelpText<"Include module map files only for imported modules in dependency output">;
388390
def module_file_deps : Flag<["-"], "module-file-deps">,
389391
HelpText<"Include module files in dependency output">;
390392
def header_include_file : Separate<["-"], "header-include-file">,

include/clang/Frontend/DependencyOutputOptions.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class DependencyOutputOptions {
3232
/// problems.
3333
unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
3434
unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
35+
unsigned SkipUnusedModuleMaps : 1; ///< Skip unused module map dependencies.
3536

3637
/// Destination of cl.exe style /showIncludes info.
3738
ShowIncludesDestination ShowIncludesDest = ShowIncludesDestination::None;
@@ -67,7 +68,7 @@ class DependencyOutputOptions {
6768
public:
6869
DependencyOutputOptions()
6970
: IncludeSystemHeaders(0), ShowHeaderIncludes(0), UsePhonyTargets(0),
70-
AddMissingHeaderDeps(0), IncludeModuleFiles(0) {}
71+
AddMissingHeaderDeps(0), IncludeModuleFiles(0), SkipUnusedModuleMaps(0) {}
7172
};
7273

7374
} // end namespace clang

include/clang/Lex/ModuleMap.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ class ModuleMapCallbacks {
5959
virtual void moduleMapFileRead(SourceLocation FileStart,
6060
const FileEntry &File, bool IsSystem) {}
6161

62+
/// Called when a module map file matches a module lookup
63+
///
64+
/// \param File The file itself.
65+
/// \param M The module found that matches this module map.
66+
/// \param IsSystem Whether this is a module map from a system include path.
67+
virtual void moduleMapFoundForModule(const FileEntry &File, const Module *M,
68+
bool IsSystem) {}
69+
6270
/// Called when a header is added during module map parsing.
6371
///
6472
/// \param Filename The header file itself.

include/clang/Sema/Sema.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -536,13 +536,13 @@ class Sema {
536536
/// element type here is ExprWithCleanups::Object.
537537
SmallVector<BlockDecl*, 8> ExprCleanupObjects;
538538

539-
/// Store a list of either DeclRefExprs or MemberExprs
540-
/// that contain a reference to a variable (constant) that may or may not
541-
/// be odr-used in this Expr, and we won't know until all lvalue-to-rvalue
542-
/// and discarded value conversions have been applied to all subexpressions
543-
/// of the enclosing full expression. This is cleared at the end of each
544-
/// full expression.
545-
llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs;
539+
/// Store a set of either DeclRefExprs or MemberExprs that contain a reference
540+
/// to a variable (constant) that may or may not be odr-used in this Expr, and
541+
/// we won't know until all lvalue-to-rvalue and discarded value conversions
542+
/// have been applied to all subexpressions of the enclosing full expression.
543+
/// This is cleared at the end of each full expression.
544+
using MaybeODRUseExprSet = llvm::SmallPtrSet<Expr *, 2>;
545+
MaybeODRUseExprSet MaybeODRUseExprs;
546546

547547
std::unique_ptr<sema::FunctionScopeInfo> PreallocatedFunctionScope;
548548

@@ -982,7 +982,7 @@ class Sema {
982982
/// context (i.e. the number of TypoExprs created).
983983
unsigned NumTypos;
984984

985-
llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs;
985+
MaybeODRUseExprSet SavedMaybeODRUseExprs;
986986

987987
/// The lambdas that are present within this context, if it
988988
/// is indeed an unevaluated context.

lib/Analysis/ThreadSafetyCommon.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,23 @@ til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,
277277

278278
// Function parameters require substitution and/or renaming.
279279
if (const auto *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
280-
const auto *FD =
281-
cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
282280
unsigned I = PV->getFunctionScopeIndex();
283-
284-
if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) {
285-
// Substitute call arguments for references to function parameters
286-
assert(I < Ctx->NumArgs);
287-
return translate(Ctx->FunArgs[I], Ctx->Prev);
281+
const DeclContext *D = PV->getDeclContext();
282+
if (Ctx && Ctx->FunArgs) {
283+
const Decl *Canonical = Ctx->AttrDecl->getCanonicalDecl();
284+
if (isa<FunctionDecl>(D)
285+
? (cast<FunctionDecl>(D)->getCanonicalDecl() == Canonical)
286+
: (cast<ObjCMethodDecl>(D)->getCanonicalDecl() == Canonical)) {
287+
// Substitute call arguments for references to function parameters
288+
assert(I < Ctx->NumArgs);
289+
return translate(Ctx->FunArgs[I], Ctx->Prev);
290+
}
288291
}
289292
// Map the param back to the param of the original function declaration
290293
// for consistent comparisons.
291-
VD = FD->getParamDecl(I);
294+
VD = isa<FunctionDecl>(D)
295+
? cast<FunctionDecl>(D)->getCanonicalDecl()->getParamDecl(I)
296+
: cast<ObjCMethodDecl>(D)->getCanonicalDecl()->getParamDecl(I);
292297
}
293298

294299
// For non-local variables, treat it as a reference to a named object.

lib/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
10431043
}
10441044
CmdArgs.push_back("-dependency-file");
10451045
CmdArgs.push_back(DepFile);
1046+
CmdArgs.push_back("-skip-unused-modulemap-deps");
10461047

10471048
// Add a default target if one wasn't specified.
10481049
if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
13371337
Opts.Targets = Args.getAllArgValues(OPT_MT);
13381338
Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
13391339
Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps);
1340+
Opts.SkipUnusedModuleMaps = Args.hasArg(OPT_skip_unused_modulemap_file_deps);
13401341
Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
13411342
Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
13421343
Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);

lib/Frontend/DependencyFile.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class DFGImpl : public PPCallbacks {
161161
bool AddMissingHeaderDeps;
162162
bool SeenMissingHeader;
163163
bool IncludeModuleFiles;
164+
bool SkipUnusedModuleMaps;
164165
DependencyOutputFormat OutputFormat;
165166
unsigned InputFileIndex;
166167

@@ -177,6 +178,7 @@ class DFGImpl : public PPCallbacks {
177178
AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
178179
SeenMissingHeader(false),
179180
IncludeModuleFiles(Opts.IncludeModuleFiles),
181+
SkipUnusedModuleMaps(Opts.SkipUnusedModuleMaps),
180182
OutputFormat(Opts.OutputFormat),
181183
InputFileIndex(0) {
182184
for (const auto &ExtraDep : Opts.ExtraDeps) {
@@ -210,6 +212,7 @@ class DFGImpl : public PPCallbacks {
210212
bool AddFilename(StringRef Filename);
211213
bool includeSystemHeaders() const { return IncludeSystemHeaders; }
212214
bool includeModuleFiles() const { return IncludeModuleFiles; }
215+
bool skipUnusedModuleMaps() const { return SkipUnusedModuleMaps; }
213216
};
214217

215218
class DFGMMCallback : public ModuleMapCallbacks {
@@ -218,9 +221,17 @@ class DFGMMCallback : public ModuleMapCallbacks {
218221
DFGMMCallback(DFGImpl &Parent) : Parent(Parent) {}
219222
void moduleMapFileRead(SourceLocation Loc, const FileEntry &Entry,
220223
bool IsSystem) override {
224+
if (Parent.skipUnusedModuleMaps())
225+
return;
221226
if (!IsSystem || Parent.includeSystemHeaders())
222227
Parent.AddFilename(Entry.getName());
223228
}
229+
void moduleMapFoundForModule(const FileEntry &Entry, const Module *M,
230+
bool IsSystem) override {
231+
if (Parent.skipUnusedModuleMaps() &&
232+
(!IsSystem || Parent.includeSystemHeaders()))
233+
Parent.AddFilename(Entry.getName());
234+
}
224235
};
225236

226237
class DFGASTReaderListener : public ASTReaderListener {

lib/Lex/ModuleMap.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,8 +764,17 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
764764

765765
Module *ModuleMap::findModule(StringRef Name) const {
766766
llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
767-
if (Known != Modules.end())
768-
return Known->getValue();
767+
if (Known != Modules.end()) {
768+
Module *M = Known->getValue();
769+
// Notify callbacks that we found a module map for the module.
770+
if (!M->DefinitionLoc.isInvalid())
771+
for (const auto &Cb : Callbacks)
772+
Cb->moduleMapFoundForModule(
773+
*getContainingModuleMapFile(M), M,
774+
SourceMgr.getFileCharacteristic(M->DefinitionLoc) ==
775+
SrcMgr::C_System_ModuleMap);
776+
return M;
777+
}
769778

770779
return nullptr;
771780
}

lib/Sema/SemaExpr.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15604,7 +15604,12 @@ ExprResult Sema::ActOnConstantExpression(ExprResult Res) {
1560415604
}
1560515605

1560615606
void Sema::CleanupVarDeclMarking() {
15607-
for (Expr *E : MaybeODRUseExprs) {
15607+
// Iterate through a local copy in case MarkVarDeclODRUsed makes a recursive
15608+
// call.
15609+
MaybeODRUseExprSet LocalMaybeODRUseExprs;
15610+
std::swap(LocalMaybeODRUseExprs, MaybeODRUseExprs);
15611+
15612+
for (Expr *E : LocalMaybeODRUseExprs) {
1560815613
VarDecl *Var;
1560915614
SourceLocation Loc;
1561015615
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
@@ -15621,10 +15626,10 @@ void Sema::CleanupVarDeclMarking() {
1562115626
/*MaxFunctionScopeIndex Pointer*/ nullptr);
1562215627
}
1562315628

15624-
MaybeODRUseExprs.clear();
15629+
assert(MaybeODRUseExprs.empty() &&
15630+
"MarkVarDeclODRUsed failed to cleanup MaybeODRUseExprs?");
1562515631
}
1562615632

15627-
1562815633
static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
1562915634
VarDecl *Var, Expr *E) {
1563015635
assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E)) &&
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module A {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module X {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module Y {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: rm -rf %t.cache %t.d %t.cmd
2+
// RUN: %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.cache -dependency-file %t.d -MT dependencies -I%S/Inputs/dependency-skip-unused/x -I%S/Inputs/dependency-skip-unused/y -I%S/Inputs/dependency-skip-unused -skip-unused-modulemap-deps %s
3+
// RUN: FileCheck %s < %t.d
4+
// CHECK-NOT: dependency-skip-unused{{.}}x{{.}}module.modulemap
5+
// CHECK-NOT: dependency-skip-unused{{.}}y{{.}}module.modulemap
6+
7+
// RUN: %clang -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.cache -MMD -MT dependencies -MF %t.d -I%S/Inputs/dependency-skip-unused/x -I%S/Inputs/dependency-skip-unused/y -I%S/Inputs/dependency-skip-unused %s -### 2>&1 | FileCheck -check-prefix=CC1_INV %s
8+
// CC1_INV: -skip-unused-modulemap-deps
9+
10+
@import A;

test/SemaCXX/blocks.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,11 @@ namespace test6c {
145145
A::foo(); });
146146
}
147147
}
148+
149+
namespace test7 {
150+
struct S {};
151+
void f() {
152+
constexpr S s;
153+
auto some_block = ^{ (void)s; };
154+
}
155+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -Wno-objc-root-class %s
2+
3+
// Thread safety analysis used to crash when used with ObjC methods.
4+
5+
#include "thread-safety-analysis.h"
6+
7+
@interface MyInterface
8+
- (void)doIt:(class Lock *)myLock;
9+
@end
10+
11+
@implementation MyInterface
12+
- (void)doIt:(class Lock *)myLock {
13+
AutoLock lock(*myLock);
14+
}
15+
@end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class __attribute__((lockable)) Lock {
2+
public:
3+
void Acquire() __attribute__((exclusive_lock_function())) {}
4+
void Release() __attribute__((unlock_function())) {}
5+
};
6+
7+
class __attribute__((scoped_lockable)) AutoLock {
8+
public:
9+
AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock)))
10+
: lock_(lock) {
11+
lock.Acquire();
12+
}
13+
~AutoLock() __attribute__((unlock_function())) { lock_.Release(); }
14+
15+
private:
16+
Lock &lock_;
17+
};

test/SemaObjCXX/warn-thread-safety-analysis.mm

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,6 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s
22

3-
class __attribute__((lockable)) Lock {
4-
public:
5-
void Acquire() __attribute__((exclusive_lock_function())) {}
6-
void Release() __attribute__((unlock_function())) {}
7-
};
8-
9-
class __attribute__((scoped_lockable)) AutoLock {
10-
public:
11-
AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock)))
12-
: lock_(lock) {
13-
lock.Acquire();
14-
}
15-
~AutoLock() __attribute__((unlock_function())) { lock_.Release(); }
16-
17-
private:
18-
Lock &lock_;
19-
};
3+
#include "thread-safety-analysis.h"
204

215
@interface MyInterface {
226
@private

0 commit comments

Comments
 (0)