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

Commit

Permalink
Merge remote-tracking branch 'origin/swift-5.1-branch' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
swift-ci committed Mar 27, 2019
2 parents 2c09040 + c72b1b5 commit f6e68ee
Show file tree
Hide file tree
Showing 18 changed files with 119 additions and 39 deletions.
2 changes: 2 additions & 0 deletions include/clang/Driver/CC1Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">;

def sys_header_deps : Flag<["-"], "sys-header-deps">,
HelpText<"Include system headers in dependency output">;
def skip_unused_modulemap_file_deps : Flag<["-"], "skip-unused-modulemap-deps">,
HelpText<"Include module map files only for imported modules in dependency output">;
def module_file_deps : Flag<["-"], "module-file-deps">,
HelpText<"Include module files in dependency output">;
def header_include_file : Separate<["-"], "header-include-file">,
Expand Down
3 changes: 2 additions & 1 deletion include/clang/Frontend/DependencyOutputOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class DependencyOutputOptions {
/// problems.
unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
unsigned SkipUnusedModuleMaps : 1; ///< Skip unused module map dependencies.

/// Destination of cl.exe style /showIncludes info.
ShowIncludesDestination ShowIncludesDest = ShowIncludesDestination::None;
Expand Down Expand Up @@ -67,7 +68,7 @@ class DependencyOutputOptions {
public:
DependencyOutputOptions()
: IncludeSystemHeaders(0), ShowHeaderIncludes(0), UsePhonyTargets(0),
AddMissingHeaderDeps(0), IncludeModuleFiles(0) {}
AddMissingHeaderDeps(0), IncludeModuleFiles(0), SkipUnusedModuleMaps(0) {}
};

} // end namespace clang
Expand Down
8 changes: 8 additions & 0 deletions include/clang/Lex/ModuleMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ class ModuleMapCallbacks {
virtual void moduleMapFileRead(SourceLocation FileStart,
const FileEntry &File, bool IsSystem) {}

/// Called when a module map file matches a module lookup
///
/// \param File The file itself.
/// \param M The module found that matches this module map.
/// \param IsSystem Whether this is a module map from a system include path.
virtual void moduleMapFoundForModule(const FileEntry &File, const Module *M,
bool IsSystem) {}

/// Called when a header is added during module map parsing.
///
/// \param Filename The header file itself.
Expand Down
16 changes: 8 additions & 8 deletions include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,13 +536,13 @@ class Sema {
/// element type here is ExprWithCleanups::Object.
SmallVector<BlockDecl*, 8> ExprCleanupObjects;

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

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

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

llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs;
MaybeODRUseExprSet SavedMaybeODRUseExprs;

/// The lambdas that are present within this context, if it
/// is indeed an unevaluated context.
Expand Down
21 changes: 13 additions & 8 deletions lib/Analysis/ThreadSafetyCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,18 +277,23 @@ til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,

// Function parameters require substitution and/or renaming.
if (const auto *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
const auto *FD =
cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
unsigned I = PV->getFunctionScopeIndex();

if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) {
// Substitute call arguments for references to function parameters
assert(I < Ctx->NumArgs);
return translate(Ctx->FunArgs[I], Ctx->Prev);
const DeclContext *D = PV->getDeclContext();
if (Ctx && Ctx->FunArgs) {
const Decl *Canonical = Ctx->AttrDecl->getCanonicalDecl();
if (isa<FunctionDecl>(D)
? (cast<FunctionDecl>(D)->getCanonicalDecl() == Canonical)
: (cast<ObjCMethodDecl>(D)->getCanonicalDecl() == Canonical)) {
// Substitute call arguments for references to function parameters
assert(I < Ctx->NumArgs);
return translate(Ctx->FunArgs[I], Ctx->Prev);
}
}
// Map the param back to the param of the original function declaration
// for consistent comparisons.
VD = FD->getParamDecl(I);
VD = isa<FunctionDecl>(D)
? cast<FunctionDecl>(D)->getCanonicalDecl()->getParamDecl(I)
: cast<ObjCMethodDecl>(D)->getCanonicalDecl()->getParamDecl(I);
}

// For non-local variables, treat it as a reference to a named object.
Expand Down
1 change: 1 addition & 0 deletions lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
}
CmdArgs.push_back("-dependency-file");
CmdArgs.push_back(DepFile);
CmdArgs.push_back("-skip-unused-modulemap-deps");

// Add a default target if one wasn't specified.
if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
Expand Down
1 change: 1 addition & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
Opts.Targets = Args.getAllArgValues(OPT_MT);
Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps);
Opts.SkipUnusedModuleMaps = Args.hasArg(OPT_skip_unused_modulemap_file_deps);
Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);
Expand Down
11 changes: 11 additions & 0 deletions lib/Frontend/DependencyFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ class DFGImpl : public PPCallbacks {
bool AddMissingHeaderDeps;
bool SeenMissingHeader;
bool IncludeModuleFiles;
bool SkipUnusedModuleMaps;
DependencyOutputFormat OutputFormat;
unsigned InputFileIndex;

Expand All @@ -177,6 +178,7 @@ class DFGImpl : public PPCallbacks {
AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
SeenMissingHeader(false),
IncludeModuleFiles(Opts.IncludeModuleFiles),
SkipUnusedModuleMaps(Opts.SkipUnusedModuleMaps),
OutputFormat(Opts.OutputFormat),
InputFileIndex(0) {
for (const auto &ExtraDep : Opts.ExtraDeps) {
Expand Down Expand Up @@ -210,6 +212,7 @@ class DFGImpl : public PPCallbacks {
bool AddFilename(StringRef Filename);
bool includeSystemHeaders() const { return IncludeSystemHeaders; }
bool includeModuleFiles() const { return IncludeModuleFiles; }
bool skipUnusedModuleMaps() const { return SkipUnusedModuleMaps; }
};

class DFGMMCallback : public ModuleMapCallbacks {
Expand All @@ -218,9 +221,17 @@ class DFGMMCallback : public ModuleMapCallbacks {
DFGMMCallback(DFGImpl &Parent) : Parent(Parent) {}
void moduleMapFileRead(SourceLocation Loc, const FileEntry &Entry,
bool IsSystem) override {
if (Parent.skipUnusedModuleMaps())
return;
if (!IsSystem || Parent.includeSystemHeaders())
Parent.AddFilename(Entry.getName());
}
void moduleMapFoundForModule(const FileEntry &Entry, const Module *M,
bool IsSystem) override {
if (Parent.skipUnusedModuleMaps() &&
(!IsSystem || Parent.includeSystemHeaders()))
Parent.AddFilename(Entry.getName());
}
};

class DFGASTReaderListener : public ASTReaderListener {
Expand Down
13 changes: 11 additions & 2 deletions lib/Lex/ModuleMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,8 +764,17 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,

Module *ModuleMap::findModule(StringRef Name) const {
llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
if (Known != Modules.end())
return Known->getValue();
if (Known != Modules.end()) {
Module *M = Known->getValue();
// Notify callbacks that we found a module map for the module.
if (!M->DefinitionLoc.isInvalid())
for (const auto &Cb : Callbacks)
Cb->moduleMapFoundForModule(
*getContainingModuleMapFile(M), M,
SourceMgr.getFileCharacteristic(M->DefinitionLoc) ==
SrcMgr::C_System_ModuleMap);
return M;
}

return nullptr;
}
Expand Down
11 changes: 8 additions & 3 deletions lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15604,7 +15604,12 @@ ExprResult Sema::ActOnConstantExpression(ExprResult Res) {
}

void Sema::CleanupVarDeclMarking() {
for (Expr *E : MaybeODRUseExprs) {
// Iterate through a local copy in case MarkVarDeclODRUsed makes a recursive
// call.
MaybeODRUseExprSet LocalMaybeODRUseExprs;
std::swap(LocalMaybeODRUseExprs, MaybeODRUseExprs);

for (Expr *E : LocalMaybeODRUseExprs) {
VarDecl *Var;
SourceLocation Loc;
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
Expand All @@ -15621,10 +15626,10 @@ void Sema::CleanupVarDeclMarking() {
/*MaxFunctionScopeIndex Pointer*/ nullptr);
}

MaybeODRUseExprs.clear();
assert(MaybeODRUseExprs.empty() &&
"MarkVarDeclODRUsed failed to cleanup MaybeODRUseExprs?");
}


static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
VarDecl *Var, Expr *E) {
assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E)) &&
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module A {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module X {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module Y {}
10 changes: 10 additions & 0 deletions test/Modules/dependency-skip-unused-modulemaps.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: rm -rf %t.cache %t.d %t.cmd
// 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
// RUN: FileCheck %s < %t.d
// CHECK-NOT: dependency-skip-unused{{.}}x{{.}}module.modulemap
// CHECK-NOT: dependency-skip-unused{{.}}y{{.}}module.modulemap

// 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
// CC1_INV: -skip-unused-modulemap-deps

@import A;
8 changes: 8 additions & 0 deletions test/SemaCXX/blocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,11 @@ namespace test6c {
A::foo(); });
}
}

namespace test7 {
struct S {};
void f() {
constexpr S s;
auto some_block = ^{ (void)s; };
}
}
15 changes: 15 additions & 0 deletions test/SemaObjCXX/no-crash-thread-safety-analysis.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -Wno-objc-root-class %s

// Thread safety analysis used to crash when used with ObjC methods.

#include "thread-safety-analysis.h"

@interface MyInterface
- (void)doIt:(class Lock *)myLock;
@end

@implementation MyInterface
- (void)doIt:(class Lock *)myLock {
AutoLock lock(*myLock);
}
@end
17 changes: 17 additions & 0 deletions test/SemaObjCXX/thread-safety-analysis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class __attribute__((lockable)) Lock {
public:
void Acquire() __attribute__((exclusive_lock_function())) {}
void Release() __attribute__((unlock_function())) {}
};

class __attribute__((scoped_lockable)) AutoLock {
public:
AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock)))
: lock_(lock) {
lock.Acquire();
}
~AutoLock() __attribute__((unlock_function())) { lock_.Release(); }

private:
Lock &lock_;
};
18 changes: 1 addition & 17 deletions test/SemaObjCXX/warn-thread-safety-analysis.mm
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s

class __attribute__((lockable)) Lock {
public:
void Acquire() __attribute__((exclusive_lock_function())) {}
void Release() __attribute__((unlock_function())) {}
};

class __attribute__((scoped_lockable)) AutoLock {
public:
AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock)))
: lock_(lock) {
lock.Acquire();
}
~AutoLock() __attribute__((unlock_function())) { lock_.Release(); }

private:
Lock &lock_;
};
#include "thread-safety-analysis.h"

@interface MyInterface {
@private
Expand Down

0 comments on commit f6e68ee

Please sign in to comment.