]> granicus.if.org Git - clang/commitdiff
[VFS] Handle empty entries in directory traversal
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Wed, 30 Mar 2016 23:54:00 +0000 (23:54 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Wed, 30 Mar 2016 23:54:00 +0000 (23:54 +0000)
The VFS YAML files contain empty directory entries to describe that it's
returning from a subdirectory before describing new files in the parent.
In the future, we should properly sort and write YAML files avoiding
such empty dirs and mitigate the extra recurson cost. However, since
this is used by previous existing YAMLs, make the traversal work in
their presence.

rdar://problem/24499339

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@264970 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Basic/VirtualFileSystem.cpp
test/Modules/Inputs/crash-recovery/usr/include/module.map
test/Modules/Inputs/crash-recovery/usr/include/pthread.h [new file with mode: 0644]
test/Modules/Inputs/crash-recovery/usr/include/pthread/pthread_impl.h [new file with mode: 0644]
test/Modules/Inputs/crash-recovery/usr/include/pthread_impl.h [new file with mode: 0644]
test/Modules/crash-vfs-path-emptydir-entries.m [new file with mode: 0644]

index 325e5eb7bb7e48e1f771a922dc73d11b74cef3b8..a44111a388577a98cabc710ceb5fd2e29d5c815a 100644 (file)
@@ -1358,16 +1358,21 @@ RedirectingFileSystem::lookupPath(sys::path::const_iterator Start,
     ++Start;
 #endif
 
-  if (CaseSensitive ? !Start->equals(From->getName())
-                    : !Start->equals_lower(From->getName()))
-    // failure to match
-    return make_error_code(llvm::errc::no_such_file_or_directory);
+  StringRef FromName = From->getName();
 
-  ++Start;
+  // Forward the search to the next component in case this is an empty one.
+  if (!FromName.empty()) {
+    if (CaseSensitive ? !Start->equals(FromName)
+                      : !Start->equals_lower(FromName))
+      // failure to match
+      return make_error_code(llvm::errc::no_such_file_or_directory);
 
-  if (Start == End) {
-    // Match!
-    return From;
+    ++Start;
+
+    if (Start == End) {
+      // Match!
+      return From;
+    }
   }
 
   auto *DE = dyn_cast<RedirectingDirectoryEntry>(From);
index 70aae494eff2ead6a0e21131cc236188c1762d1f..9b429160db5020adbd1a50c00ba1245d735b3043 100644 (file)
@@ -3,4 +3,14 @@ module cstd [system] {
   module stdio {
     header "stdio.h"
   }
+
+  module pthread {
+    header "pthread.h"
+    export *
+
+    module impl {
+      header "pthread_impl.h"
+      export *
+    }
+  }
 }
diff --git a/test/Modules/Inputs/crash-recovery/usr/include/pthread.h b/test/Modules/Inputs/crash-recovery/usr/include/pthread.h
new file mode 100644 (file)
index 0000000..44ac9fc
--- /dev/null
@@ -0,0 +1 @@
+#include "pthread/pthread_impl.h"
diff --git a/test/Modules/Inputs/crash-recovery/usr/include/pthread/pthread_impl.h b/test/Modules/Inputs/crash-recovery/usr/include/pthread/pthread_impl.h
new file mode 100644 (file)
index 0000000..21a720a
--- /dev/null
@@ -0,0 +1 @@
+#define _PTHREAD_MUTEX_SIG_init   0x32AAABA7
diff --git a/test/Modules/Inputs/crash-recovery/usr/include/pthread_impl.h b/test/Modules/Inputs/crash-recovery/usr/include/pthread_impl.h
new file mode 100644 (file)
index 0000000..21a720a
--- /dev/null
@@ -0,0 +1 @@
+#define _PTHREAD_MUTEX_SIG_init   0x32AAABA7
diff --git a/test/Modules/crash-vfs-path-emptydir-entries.m b/test/Modules/crash-vfs-path-emptydir-entries.m
new file mode 100644 (file)
index 0000000..444c455
--- /dev/null
@@ -0,0 +1,48 @@
+// REQUIRES: crash-recovery, shell
+
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+// Test clang can collect symbolic link headers used in modules.
+// crash reproducer if there's a symbolic link header file used in a module.
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/i %t/m %t %t/sysroot
+// RUN: cp -a %S/Inputs/crash-recovery/usr %t/i/
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only %s -I %/t/i -isysroot %/t/sysroot/ \
+// RUN:     -fmodules -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-vfs-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN:   grep "usr/include/stdio.h" | count 1
+
+#include "usr/include/stdio.h"
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import cstd.stdio;
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "-isysroot" "{{[^"]*}}/sysroot/"
+// CHECKSH-NOT: "-fmodules-cache-path="
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+
+// CHECKYAML: 'type': 'directory',
+// CHECKYAML: 'name': "",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT:   {
+// CHECKYAML-NEXT:     'type': 'file',
+// CHECKYAML-NEXT:     'name': "pthread_impl.h",
+// CHECKYAML-NEXT:     'external-contents': "/{{.*}}/i/usr/include/pthread_impl.h"
+// CHECKYAML-NEXT:   },