aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td2
-rw-r--r--lib/AST/ASTContext.cpp23
-rw-r--r--lib/Driver/Driver.cpp24
-rw-r--r--lib/Driver/ToolChains/Clang.cpp26
-rw-r--r--lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp16
5 files changed, 65 insertions, 26 deletions
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index eab453ee20ec..12f1a7f6c488 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -91,8 +91,6 @@ def err_no_external_assembler : Error<
"there is no external assembler that can be used on this platform">;
def err_drv_unable_to_remove_file : Error<
"unable to remove file: %0">;
-def err_drv_unable_to_set_working_directory : Error <
- "unable to set working directory: %0">;
def err_drv_command_failure : Error<
"unable to execute command: %0">;
def err_drv_invalid_darwin_version : Error<
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 468c7f47657d..93bdaafc2ac6 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -9814,10 +9814,25 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
return StrongLinkage;
case TSK_ExplicitSpecialization:
- return Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- VD->isStaticDataMember()
- ? GVA_StrongODR
- : StrongLinkage;
+ if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+ // If this is a fully specialized constexpr variable template, pretend it
+ // was marked inline. MSVC 14.21.27702 headers define _Is_integral in a
+ // header this way, and we don't want to emit non-discardable definitions
+ // of these variables in every TU that includes <type_traits>. This
+ // behavior is non-conforming, since another TU could use an extern
+ // template declaration for this variable, but for constexpr variables,
+ // it's unlikely for a user to want to do that. This behavior can be
+ // removed if the headers change to explicitly mark such variable template
+ // specializations inline.
+ if (isa<VarTemplateSpecializationDecl>(VD) && VD->isConstexpr())
+ return GVA_DiscardableODR;
+
+ // Use ODR linkage for static data members of fully specialized templates
+ // to prevent duplicate definition errors with MSVC.
+ if (VD->isStaticDataMember())
+ return GVA_StrongODR;
+ }
+ return StrongLinkage;
case TSK_ExplicitInstantiationDefinition:
return GVA_StrongODR;
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 396ddf4dd816..a9a273529b46 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -133,7 +133,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
// Provide a sane fallback if no VFS is specified.
if (!this->VFS)
- this->VFS = llvm::vfs::createPhysicalFileSystem().release();
+ this->VFS = llvm::vfs::getRealFileSystem();
Name = llvm::sys::path::filename(ClangExecutable);
Dir = llvm::sys::path::parent_path(ClangExecutable);
@@ -1010,11 +1010,6 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
}
}
- // Check for working directory option before accessing any files
- if (Arg *WD = Args.getLastArg(options::OPT_working_directory))
- if (VFS->setCurrentWorkingDirectory(WD->getValue()))
- Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue();
-
// FIXME: This stuff needs to go into the Compilation, not the driver.
bool CCCPrintPhases;
@@ -1995,11 +1990,20 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value,
if (Value == "-")
return true;
- if (getVFS().exists(Value))
+ SmallString<64> Path(Value);
+ if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) {
+ if (!llvm::sys::path::is_absolute(Path)) {
+ SmallString<64> Directory(WorkDir->getValue());
+ llvm::sys::path::append(Directory, Value);
+ Path.assign(Directory);
+ }
+ }
+
+ if (getVFS().exists(Path))
return true;
if (IsCLMode()) {
- if (!llvm::sys::path::is_absolute(Twine(Value)) &&
+ if (!llvm::sys::path::is_absolute(Twine(Path)) &&
llvm::sys::Process::FindInEnvPath("LIB", Value))
return true;
@@ -2025,12 +2029,12 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value,
if (getOpts().findNearest(Value, Nearest, IncludedFlagsBitmask,
ExcludedFlagsBitmask) <= 1) {
Diag(clang::diag::err_drv_no_such_file_with_suggestion)
- << Value << Nearest;
+ << Path << Nearest;
return false;
}
}
- Diag(clang::diag::err_drv_no_such_file) << Value;
+ Diag(clang::diag::err_drv_no_such_file) << Path;
return false;
}
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 2508178423bf..dd461a1976d9 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -603,15 +603,16 @@ static bool shouldUseLeafFramePointer(const ArgList &Args,
}
/// Add a CC1 option to specify the debug compilation directory.
-static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs,
- const llvm::vfs::FileSystem &VFS) {
+static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
if (Arg *A = Args.getLastArg(options::OPT_fdebug_compilation_dir)) {
CmdArgs.push_back("-fdebug-compilation-dir");
CmdArgs.push_back(A->getValue());
- } else if (llvm::ErrorOr<std::string> CWD =
- VFS.getCurrentWorkingDirectory()) {
- CmdArgs.push_back("-fdebug-compilation-dir");
- CmdArgs.push_back(Args.MakeArgString(*CWD));
+ } else {
+ SmallString<128> cwd;
+ if (!llvm::sys::fs::current_path(cwd)) {
+ CmdArgs.push_back("-fdebug-compilation-dir");
+ CmdArgs.push_back(Args.MakeArgString(cwd));
+ }
}
}
@@ -877,8 +878,13 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
else
OutputFilename = llvm::sys::path::filename(Output.getBaseInput());
SmallString<128> CoverageFilename = OutputFilename;
- if (llvm::sys::path::is_relative(CoverageFilename))
- (void)D.getVFS().makeAbsolute(CoverageFilename);
+ if (llvm::sys::path::is_relative(CoverageFilename)) {
+ SmallString<128> Pwd;
+ if (!llvm::sys::fs::current_path(Pwd)) {
+ llvm::sys::path::append(Pwd, CoverageFilename);
+ CoverageFilename.swap(Pwd);
+ }
+ }
llvm::sys::path::replace_extension(CoverageFilename, "gcno");
CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
@@ -4365,7 +4371,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fno-autolink");
// Add in -fdebug-compilation-dir if necessary.
- addDebugCompDirArg(Args, CmdArgs, D.getVFS());
+ addDebugCompDirArg(Args, CmdArgs);
addDebugPrefixMapArg(D, Args, CmdArgs);
@@ -6092,7 +6098,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
DebugInfoKind = (WantDebug ? codegenoptions::LimitedDebugInfo
: codegenoptions::NoDebugInfo);
// Add the -fdebug-compilation-dir flag if needed.
- addDebugCompDirArg(Args, CmdArgs, C.getDriver().getVFS());
+ addDebugCompDirArg(Args, CmdArgs);
addDebugPrefixMapArg(getToolChain().getDriver(), Args, CmdArgs);
diff --git a/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp b/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
index 736d80ef9ec7..a6539098c89a 100644
--- a/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
@@ -91,6 +91,22 @@ void EnumCastOutOfRangeChecker::reportWarning(CheckerContext &C) const {
void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE,
CheckerContext &C) const {
+
+ // Only perform enum range check on casts where such checks are valid. For
+ // all other cast kinds (where enum range checks are unnecessary or invalid),
+ // just return immediately. TODO: The set of casts whitelisted for enum
+ // range checking may be incomplete. Better to add a missing cast kind to
+ // enable a missing check than to generate false negatives and have to remove
+ // those later.
+ switch (CE->getCastKind()) {
+ case CK_IntegralCast:
+ break;
+
+ default:
+ return;
+ break;
+ }
+
// Get the value of the expression to cast.
const llvm::Optional<DefinedOrUnknownSVal> ValueToCast =
C.getSVal(CE->getSubExpr()).getAs<DefinedOrUnknownSVal>();