[PATCH] D49518: [VFS] Emit an error when a file isn't located in any directory.

Volodymyr Sapsai via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 18 16:26:25 PDT 2018


vsapsai created this revision.
vsapsai added reviewers: bruno, benlangmuir.
Herald added a subscriber: dexonsmith.

Orphaned files prevent us from building a file system tree and cause the
assertion

> Assertion failed: (NewParentE && "Parent entry must exist"), function uniqueOverlayTree, file clang/lib/Basic/VirtualFileSystem.cpp, line 1303.

rdar://problem/28990865


https://reviews.llvm.org/D49518

Files:
  clang/lib/Basic/VirtualFileSystem.cpp
  clang/test/VFS/Inputs/invalid-file.yaml
  clang/test/VFS/parse-errors.c


Index: clang/test/VFS/parse-errors.c
===================================================================
--- clang/test/VFS/parse-errors.c
+++ clang/test/VFS/parse-errors.c
@@ -12,3 +12,7 @@
 // RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/unknown-value.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-VALUE %s
 // CHECK-UNKNOWN-VALUE: expected boolean value
 // CHECK-UNKNOWN-VALUE: invalid virtual filesystem overlay file
+
+// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/invalid-file.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-INVALID-FILE %s
+// CHECK-INVALID-FILE: file is not located in any directory
+// CHECK-INVALID-FILE: invalid virtual filesystem overlay file
Index: clang/test/VFS/Inputs/invalid-file.yaml
===================================================================
--- /dev/null
+++ clang/test/VFS/Inputs/invalid-file.yaml
@@ -0,0 +1,8 @@
+{
+  'version': 0,
+  'roots': [
+    { 'name': 'file-not-in-directory.h', 'type': 'file',
+      'external-contents': 'foo'
+    }
+  ]
+}
Index: clang/lib/Basic/VirtualFileSystem.cpp
===================================================================
--- clang/lib/Basic/VirtualFileSystem.cpp
+++ clang/lib/Basic/VirtualFileSystem.cpp
@@ -1244,7 +1244,8 @@
     }
   }
 
-  std::unique_ptr<Entry> parseEntry(yaml::Node *N, RedirectingFileSystem *FS) {
+  std::unique_ptr<Entry> parseEntry(yaml::Node *N, RedirectingFileSystem *FS,
+                                    bool IsRootEntry) {
     auto *M = dyn_cast<yaml::MappingNode>(N);
     if (!M) {
       error(N, "expected mapping node for file or directory entry");
@@ -1265,6 +1266,7 @@
     std::vector<std::unique_ptr<Entry>> EntryArrayContents;
     std::string ExternalContentsPath;
     std::string Name;
+    yaml::Node *NameValueNode;
     auto UseExternalName = RedirectingFileEntry::NK_NotSet;
     EntryKind Kind;
 
@@ -1284,6 +1286,7 @@
         if (!parseScalarString(I.getValue(), Value, Buffer))
           return nullptr;
 
+        NameValueNode = I.getValue();
         if (FS->UseCanonicalizedPaths) {
           SmallString<256> Path(Value);
           // Guarantee that old YAML files containing paths with ".." and "."
@@ -1320,7 +1323,8 @@
         }
 
         for (auto &I : *Contents) {
-          if (std::unique_ptr<Entry> E = parseEntry(&I, FS))
+          if (std::unique_ptr<Entry> E =
+                  parseEntry(&I, FS, /*IsRootEntry*/ false))
             EntryArrayContents.push_back(std::move(E));
           else
             return nullptr;
@@ -1405,8 +1409,15 @@
     }
 
     StringRef Parent = sys::path::parent_path(Trimmed);
-    if (Parent.empty())
+    if (Parent.empty()) {
+      // File entry is at the root level, outside of any directory.
+      if (IsRootEntry && Kind == EK_File) {
+        if (NameValueNode)
+          error(NameValueNode, "file is not located in any directory");
+        return nullptr;
+      }
       return Result;
+    }
 
     // if 'name' contains multiple components, create implicit directory entries
     for (sys::path::reverse_iterator I = sys::path::rbegin(Parent),
@@ -1463,7 +1474,8 @@
         }
 
         for (auto &I : *Roots) {
-          if (std::unique_ptr<Entry> E = parseEntry(&I, FS))
+          if (std::unique_ptr<Entry> E =
+                  parseEntry(&I, FS, /*IsRootEntry*/ true))
             RootEntries.push_back(std::move(E));
           else
             return false;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49518.156176.patch
Type: text/x-patch
Size: 3429 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180718/3c80cddc/attachment.bin>


More information about the cfe-commits mailing list