From 16f0c0ab9dbb96735e6faf83d5188a8b73ae31b3 Mon Sep 17 00:00:00 2001 From: Sean Silva Date: Thu, 30 Jul 2015 00:26:34 +0000 Subject: [PATCH] Avoid failure to canonicalize '..'. Also fix completely broken and untested code which was hiding the primary bug. The !LLVM_ON_UNIX branch of the ifdef was actually a no-op. I ran into this in the wild. It was causing failures in our SDK build. Ideally we'd have a perfect llvm::sys::fs::canonical, but at least this is a step in the right direction, and fixes an obviously broken case. In some sense the test case I've added here is an integration test. We should have these routines thoroughly unit tested in llvm::sys::fs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@243597 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Basic/FileManager.cpp | 19 +++++++++++-------- test/Modules/Inputs/module-map-path-hash/a.h | 2 ++ .../module-map-path-hash/module.modulemap | 3 +++ test/Modules/module-map-path-hash.cpp | 9 +++++++++ 4 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 test/Modules/Inputs/module-map-path-hash/a.h create mode 100644 test/Modules/Inputs/module-map-path-hash/module.modulemap create mode 100644 test/Modules/module-map-path-hash.cpp diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp index d4927443aa..3d160569bc 100644 --- a/lib/Basic/FileManager.cpp +++ b/lib/Basic/FileManager.cpp @@ -514,7 +514,7 @@ void FileManager::modifyFileEntry(FileEntry *File, File->ModTime = ModificationTime; } -/// Remove '.' path components from the given absolute path. +/// Remove '.' and '..' path components from the given absolute path. /// \return \c true if any changes were made. // FIXME: Move this to llvm::sys::path. bool FileManager::removeDotPaths(SmallVectorImpl &Path) { @@ -525,24 +525,24 @@ bool FileManager::removeDotPaths(SmallVectorImpl &Path) { // Skip the root path, then look for traversal in the components. StringRef Rel = path::relative_path(P); - bool AnyDots = false; for (StringRef C : llvm::make_range(path::begin(Rel), path::end(Rel))) { - if (C == ".") { - AnyDots = true; + if (C == ".") + continue; + if (C == "..") { + if (!ComponentStack.empty()) + ComponentStack.pop_back(); continue; } ComponentStack.push_back(C); } - if (!AnyDots) - return false; - SmallString<256> Buffer = path::root_path(P); for (StringRef C : ComponentStack) path::append(Buffer, C); + bool Changed = (Path != Buffer); Path.swap(Buffer); - return true; + return Changed; } StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { @@ -567,6 +567,9 @@ StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { llvm::sys::fs::make_absolute(CanonicalNameBuf); llvm::sys::path::native(CanonicalNameBuf); removeDotPaths(CanonicalNameBuf); + char *Mem = CanonicalNameStorage.Allocate(CanonicalNameBuf.size()); + memcpy(Mem, CanonicalNameBuf.data(), CanonicalNameBuf.size()); + CanonicalName = StringRef(Mem, CanonicalNameBuf.size()); #endif CanonicalDirNames.insert(std::make_pair(Dir, CanonicalName)); diff --git a/test/Modules/Inputs/module-map-path-hash/a.h b/test/Modules/Inputs/module-map-path-hash/a.h new file mode 100644 index 0000000000..f1373543a2 --- /dev/null +++ b/test/Modules/Inputs/module-map-path-hash/a.h @@ -0,0 +1,2 @@ +#pragma once +int a = 42; diff --git a/test/Modules/Inputs/module-map-path-hash/module.modulemap b/test/Modules/Inputs/module-map-path-hash/module.modulemap new file mode 100644 index 0000000000..514d745d14 --- /dev/null +++ b/test/Modules/Inputs/module-map-path-hash/module.modulemap @@ -0,0 +1,3 @@ +module a { + header "a.h" +} diff --git a/test/Modules/module-map-path-hash.cpp b/test/Modules/module-map-path-hash.cpp new file mode 100644 index 0000000000..1d889db805 --- /dev/null +++ b/test/Modules/module-map-path-hash.cpp @@ -0,0 +1,9 @@ +// rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs/module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s +// xUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs//module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s +// xUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs/./module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -Rmodule-build -I%S/Inputs/../Inputs/module-map-path-hash -fmodules-cache-path=%t -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s + +#include "a.h" + +// CHECK-NOT: remark: building module -- 2.40.0