Skip to content

Commit 986afef

Browse files
authored
Merge pull request #84132 from rmaz/jsonerr
Add error messages for Swift module map parser
2 parents 7f1256d + 0b829bf commit 986afef

File tree

5 files changed

+114
-25
lines changed

5 files changed

+114
-25
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ ERROR(explicit_swift_module_map_missing,none,
360360
(StringRef))
361361

362362
ERROR(explicit_swift_module_map_corrupted,none,
363-
"explicit Swift module map from %0 is malformed",
364-
(StringRef))
363+
"explicit Swift module map from %0 is malformed: %1",
364+
(StringRef, StringRef))
365365

366366
ERROR(const_extract_protocol_list_input_file_missing,none,
367367
"cannot open constant extraction protocol list input file from %0",

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@
111111
#include "swift/Frontend/Frontend.h"
112112
#include "swift/Frontend/ModuleInterfaceSupport.h"
113113
#include "swift/Serialization/SerializedModuleLoader.h"
114+
#include "llvm/Support/Error.h"
115+
#include "llvm/Support/FormatVariadic.h"
114116
#include "llvm/Support/MemoryBuffer.h"
115117
#include "llvm/Support/StringSaver.h"
116118
#include "llvm/Support/YAMLTraits.h"
@@ -317,7 +319,7 @@ class ExplicitModuleMapParser {
317319
public:
318320
ExplicitModuleMapParser(llvm::BumpPtrAllocator &Allocator) : Saver(Allocator) {}
319321

320-
std::error_code parseSwiftExplicitModuleMap(
322+
llvm::Error parseSwiftExplicitModuleMap(
321323
llvm::MemoryBufferRef BufferRef,
322324
llvm::StringMap<ExplicitSwiftModuleInputInfo> &swiftModuleMap,
323325
llvm::StringMap<ExplicitClangModuleInputInfo> &clangModuleMap,
@@ -331,16 +333,15 @@ class ExplicitModuleMapParser {
331333
assert(DI != Stream.end() && "Failed to read a document");
332334
if (auto *MN = dyn_cast_or_null<SequenceNode>(DI->getRoot())) {
333335
for (auto &entry : *MN) {
334-
if (parseSingleModuleEntry(entry, swiftModuleMap, clangModuleMap,
335-
moduleAliases)) {
336-
return std::make_error_code(std::errc::invalid_argument);
337-
}
336+
if (auto Err = parseSingleModuleEntry(entry, swiftModuleMap,
337+
clangModuleMap, moduleAliases))
338+
return Err;
338339
}
339340
} else {
340-
return std::make_error_code(std::errc::invalid_argument);
341+
return llvm::createStringError("invalid JSON root object");
341342
}
342343
}
343-
return std::error_code{}; // success
344+
return llvm::Error::success(); // success
344345
}
345346

346347
private:
@@ -360,15 +361,15 @@ class ExplicitModuleMapParser {
360361
llvm_unreachable("Unexpected JSON value for isFramework");
361362
}
362363

363-
bool parseSingleModuleEntry(
364+
llvm::Error parseSingleModuleEntry(
364365
llvm::yaml::Node &node,
365366
llvm::StringMap<ExplicitSwiftModuleInputInfo> &swiftModuleMap,
366367
llvm::StringMap<ExplicitClangModuleInputInfo> &clangModuleMap,
367368
llvm::StringMap<std::string> &moduleAliases) {
368369
using namespace llvm::yaml;
369370
auto *mapNode = dyn_cast<MappingNode>(&node);
370371
if (!mapNode)
371-
return true;
372+
return llvm::createStringError("incorrect entry type");
372373
StringRef moduleName;
373374
std::optional<std::string> swiftModulePath, swiftModuleDocPath,
374375
swiftModuleSourceInfoPath, swiftModuleCacheKey, clangModuleCacheKey,
@@ -418,7 +419,7 @@ class ExplicitModuleMapParser {
418419
}
419420
}
420421
if (moduleName.empty())
421-
return true;
422+
return llvm::createStringError("entry is missing module name");
422423

423424
bool didInsert;
424425
if (swiftModulePath.has_value()) {
@@ -445,11 +446,15 @@ class ExplicitModuleMapParser {
445446
clangModuleCacheKey);
446447
didInsert = clangModuleMap.try_emplace(moduleName, std::move(entry)).second;
447448
}
448-
if (didInsert && moduleAlias.has_value()) {
449+
if (!didInsert)
450+
return llvm::createStringError(llvm::formatv(
451+
"duplicate {0} module with name {1}",
452+
swiftModulePath.has_value() ? "Swift" : "Clang", moduleName));
453+
454+
if (moduleAlias.has_value()) {
449455
moduleAliases[*moduleAlias] = moduleName;
450456
}
451-
// Prevent duplicate module names.
452-
return !didInsert;
457+
return llvm::Error::success();
453458
}
454459

455460
llvm::StringSaver Saver;

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,13 +2258,14 @@ struct ExplicitSwiftModuleLoader::Implementation {
22582258
return;
22592259
}
22602260

2261-
auto hasError = parser.parseSwiftExplicitModuleMap(
2261+
auto error = parser.parseSwiftExplicitModuleMap(
22622262
(*fileBufOrErr)->getMemBufferRef(), ExplicitModuleMap,
22632263
ExplicitClangModuleMap, ModuleAliases);
2264-
2265-
if (hasError)
2264+
llvm::handleAllErrors(std::move(error), [this, &fileName](
2265+
const llvm::StringError &E) {
22662266
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted,
2267-
fileName);
2267+
fileName, E.getMessage());
2268+
});
22682269

22692270
// A single module map can define multiple modules; keep track of the ones
22702271
// we've seen so that we don't generate duplicate flags.
@@ -2536,13 +2537,14 @@ struct ExplicitCASModuleLoader::Implementation {
25362537
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
25372538
llvm::MemoryBuffer::getFile(ID);
25382539

2539-
auto hasError = parser.parseSwiftExplicitModuleMap(
2540+
auto error = parser.parseSwiftExplicitModuleMap(
25402541
buf->getMemBufferRef(), ExplicitModuleMap, ExplicitClangModuleMap,
25412542
ModuleAliases);
2542-
2543-
if (hasError)
2543+
llvm::handleAllErrors(std::move(error), [this,
2544+
&ID](const llvm::StringError &E) {
25442545
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted,
2545-
ID);
2546+
ID, E.getMessage());
2547+
});
25462548

25472549
std::set<std::string> moduleMapsSeen;
25482550
std::vector<std::string> &extraClangArgs = Ctx.ClangImporterOpts.ExtraArgs;

lib/FrontendTool/FrontendTool.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,8 +1604,12 @@ static bool generateReproducer(CompilerInstance &Instance,
16041604
}
16051605
auto map = llvm::json::parse(mapProxy->getData());
16061606
if (!map) {
1607-
diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_corrupted,
1608-
mapOpts);
1607+
llvm::handleAllErrors(
1608+
map.takeError(), [&diags, &mapOpts](const llvm::json::ParseError &E) {
1609+
diags.diagnose(SourceLoc(),
1610+
diag::explicit_swift_module_map_corrupted, mapOpts,
1611+
E.message());
1612+
});
16091613
return true;
16101614
}
16111615
if (auto array = map->getAsArray()) {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: not %target-swift-frontend -typecheck %t/test.swift \
5+
// RUN: -explicit-swift-module-map-file %t/invalid_root_object.json \
6+
// RUN: 2>&1 | %FileCheck %s -check-prefix=CHECK-ROOT
7+
8+
// CHECK-ROOT: malformed: invalid JSON root object
9+
10+
// RUN: not %target-swift-frontend -typecheck %t/test.swift \
11+
// RUN: -explicit-swift-module-map-file %t/invalid_entry_type.json \
12+
// RUN: 2>&1 | %FileCheck %s -check-prefix=CHECK-ENTRY-TYPE
13+
14+
// CHECK-ENTRY-TYPE: malformed: incorrect entry type
15+
16+
// RUN: not %target-swift-frontend -typecheck %t/test.swift \
17+
// RUN: -explicit-swift-module-map-file %t/missing_module_name.json \
18+
// RUN: 2>&1 | %FileCheck %s -check-prefix=CHECK-NAME
19+
20+
// CHECK-NAME: malformed: entry is missing module name
21+
22+
// RUN: not %target-swift-frontend -typecheck %t/test.swift \
23+
// RUN: -explicit-swift-module-map-file %t/duplicate_swift_module.json \
24+
// RUN: 2>&1 | %FileCheck %s -check-prefix=CHECK-DUP-SWIFT
25+
26+
// CHECK-DUP-SWIFT: malformed: duplicate Swift module with name SwiftMod
27+
28+
// RUN: not %target-swift-frontend -typecheck %t/test.swift \
29+
// RUN: -explicit-swift-module-map-file %t/duplicate_clang_module.json \
30+
// RUN: 2>&1 | %FileCheck %s -check-prefix=CHECK-DUP-CLANG
31+
32+
// CHECK-DUP-CLANG: malformed: duplicate Clang module with name ClangMod
33+
34+
//--- invalid_root_object.json
35+
{
36+
"some_key": "some_val"
37+
}
38+
//--- invalid_entry_type.json
39+
[
40+
[
41+
{"some_key": "some_val"}
42+
]
43+
]
44+
//--- missing_module_name.json
45+
[
46+
{
47+
"isFramework": false,
48+
"modulePath": "/some/path"
49+
}
50+
]
51+
//--- duplicate_swift_module.json
52+
[
53+
{
54+
"isFramework": false,
55+
"moduleName": "SwiftMod",
56+
"modulePath": "/some/path"
57+
},
58+
{
59+
"isFramework": false,
60+
"moduleName": "SwiftMod",
61+
"modulePath": "/some/path"
62+
}
63+
]
64+
//--- duplicate_clang_module.json
65+
[
66+
{
67+
"isFramework": false,
68+
"moduleName": "ClangMod",
69+
"clangModulePath": "/some/path"
70+
},
71+
{
72+
"isFramework": false,
73+
"moduleName": "ClangMod",
74+
"clangModulePath": "/some/path"
75+
}
76+
]
77+
//--- test.swift
78+
import Swift

0 commit comments

Comments
 (0)