Skip to content

Commit 8e1bc70

Browse files
authored
Merge pull request #81337 from artemcm/DepScanVariantError-62
[6.2 🍒][Dependency Scanning] Emit a detailed error diagnostic on Clang module variant discovery
2 parents 6861f2f + 3c19103 commit 8e1bc70

File tree

6 files changed

+75
-19
lines changed

6 files changed

+75
-19
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,5 +618,16 @@ ERROR(ast_format_requires_dump_ast,none,
618618
ERROR(unknown_dump_ast_format,none,
619619
"unknown format '%0' requested with '-dump-ast-format'", (StringRef))
620620

621+
WARNING(dependency_scan_unexpected_variant, none,
622+
"unexpected module variant during dependency scanning on module '%0', "
623+
"compilation of this target is likely to fail or succeed in a way that is not deterministic", (StringRef))
624+
NOTE(dependency_scan_unexpected_variant_context_hash_note, none,
625+
"first module context hash: '%0', second module context hash: '%1'", (StringRef, StringRef))
626+
NOTE(dependency_scan_unexpected_variant_module_map_note, none,
627+
"first module module map: '%0', second module module map: '%1'", (StringRef, StringRef))
628+
NOTE(dependency_scan_unexpected_variant_extra_arg_note, none,
629+
"%select{first|second}0 module command-line has extra argument: '%1'", (bool, StringRef))
630+
631+
621632
#define UNDEFINE_DIAGNOSTIC_MACROS
622633
#include "DefineDiagnosticMacros.h"

include/swift/AST/ModuleDependencies.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class Identifier;
5555
class CompilerInstance;
5656
class IRGenOptions;
5757
class CompilerInvocation;
58+
class DiagnosticEngine;
5859

5960
/// Which kind of module dependencies we are looking for.
6061
enum class ModuleDependencyKind : int8_t {
@@ -1254,7 +1255,8 @@ class ModuleDependenciesCache {
12541255
ModuleDependencyInfo dependencies);
12551256

12561257
/// Record dependencies for the given module collection.
1257-
void recordDependencies(ModuleDependencyVector moduleDependencies);
1258+
void recordDependencies(ModuleDependencyVector moduleDependencies,
1259+
DiagnosticEngine &diags);
12581260

12591261
/// Update stored dependencies for the given module.
12601262
void updateDependency(ModuleDependencyID moduleID,

lib/AST/ASTContext.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,13 +2199,6 @@ Identifier ASTContext::getRealModuleName(Identifier key, ModuleAliasLookupOption
21992199
return value.first;
22002200
}
22012201

2202-
namespace {
2203-
static StringRef pathStringFromSearchPath(
2204-
const SearchPathOptions::SearchPath &next) {
2205-
return next.Path;
2206-
}
2207-
}
2208-
22092202
std::vector<std::string> ASTContext::getDarwinImplicitFrameworkSearchPaths()
22102203
const {
22112204
assert(LangOpts.Target.isOSDarwin());

lib/AST/ModuleDependencies.cpp

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,11 +886,61 @@ void ModuleDependenciesCache::recordDependency(
886886
}
887887

888888
void ModuleDependenciesCache::recordDependencies(
889-
ModuleDependencyVector dependencies) {
889+
ModuleDependencyVector dependencies, DiagnosticEngine &diags) {
890890
for (const auto &dep : dependencies) {
891-
if (!hasDependency(dep.first))
891+
if (hasDependency(dep.first)) {
892+
if (dep.first.Kind == ModuleDependencyKind::Clang) {
893+
auto priorClangModuleDetails =
894+
findKnownDependency(dep.first).getAsClangModule();
895+
auto newClangModuleDetails = dep.second.getAsClangModule();
896+
auto priorContextHash = priorClangModuleDetails->contextHash;
897+
auto newContextHash = newClangModuleDetails->contextHash;
898+
if (priorContextHash != newContextHash) {
899+
// This situation means that within the same scanning action, Clang
900+
// Dependency Scanner has produced two different variants of the same
901+
// module. This is not supposed to happen, but we are currently
902+
// hunting down the rare cases where it does, seemingly due to
903+
// differences in Clang Scanner direct by-name queries and transitive
904+
// header lookup queries.
905+
//
906+
// Emit a failure diagnostic here that is hopefully more actionable
907+
// for the time being.
908+
diags.diagnose(SourceLoc(), diag::dependency_scan_unexpected_variant,
909+
dep.first.ModuleName);
910+
diags.diagnose(
911+
SourceLoc(),
912+
diag::dependency_scan_unexpected_variant_context_hash_note,
913+
priorContextHash, newContextHash);
914+
diags.diagnose(
915+
SourceLoc(),
916+
diag::dependency_scan_unexpected_variant_module_map_note,
917+
priorClangModuleDetails->moduleMapFile,
918+
newClangModuleDetails->moduleMapFile);
919+
920+
auto diagnoseExtraCommandLineFlags =
921+
[&diags](const ClangModuleDependencyStorage *checkModuleDetails,
922+
const ClangModuleDependencyStorage *baseModuleDetails,
923+
bool isNewlyDiscovered) -> void {
924+
std::unordered_set<std::string> baseCommandLineSet(
925+
baseModuleDetails->buildCommandLine.begin(),
926+
baseModuleDetails->buildCommandLine.end());
927+
for (const auto &checkArg : checkModuleDetails->buildCommandLine)
928+
if (baseCommandLineSet.find(checkArg) == baseCommandLineSet.end())
929+
diags.diagnose(
930+
SourceLoc(),
931+
diag::dependency_scan_unexpected_variant_extra_arg_note,
932+
isNewlyDiscovered, checkArg);
933+
};
934+
diagnoseExtraCommandLineFlags(priorClangModuleDetails,
935+
newClangModuleDetails, true);
936+
diagnoseExtraCommandLineFlags(newClangModuleDetails,
937+
priorClangModuleDetails, false);
938+
}
939+
}
940+
} else
892941
recordDependency(dep.first.ModuleName, dep.second);
893-
if (dep.second.getKind() == ModuleDependencyKind::Clang) {
942+
943+
if (dep.first.Kind == ModuleDependencyKind::Clang) {
894944
auto clangModuleDetails = dep.second.getAsClangModule();
895945
addSeenClangModule(clang::tooling::dependencies::ModuleID{
896946
dep.first.ModuleName, clangModuleDetails->contextHash});

lib/ClangImporter/ClangModuleDependencyScanner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ bool ClangImporter::getHeaderDependencies(
516516
[&cache](StringRef path) {
517517
return cache.getScanService().remapPath(path);
518518
});
519-
cache.recordDependencies(bridgedDeps);
519+
cache.recordDependencies(bridgedDeps, Impl.SwiftContext.Diags);
520520

521521
llvm::copy(dependencies->FileDeps, std::back_inserter(headerFileInputs));
522522
auto bridgedDependencyIDs =

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ ModuleDependencyScanner::getNamedClangModuleDependencyInfo(
532532
for (const auto &dep : moduleDependencies)
533533
discoveredClangModules.insert(dep.first);
534534

535-
cache.recordDependencies(moduleDependencies);
535+
cache.recordDependencies(moduleDependencies, Diagnostics);
536536
return cache.findDependency(moduleID);
537537
}
538538

@@ -566,7 +566,7 @@ ModuleDependencyScanner::getNamedSwiftModuleDependencyInfo(
566566
if (moduleDependencies.empty())
567567
return std::nullopt;
568568

569-
cache.recordDependencies(moduleDependencies);
569+
cache.recordDependencies(moduleDependencies, Diagnostics);
570570
return cache.findDependency(moduleName);
571571
}
572572

@@ -927,7 +927,7 @@ ModuleDependencyScanner::resolveAllClangModuleDependencies(
927927
std::lock_guard<std::mutex> guard(cacheAccessLock);
928928
moduleLookupResult.insert_or_assign(moduleName, moduleDependencies);
929929
if (!moduleDependencies.empty())
930-
cache.recordDependencies(moduleDependencies);
930+
cache.recordDependencies(moduleDependencies, Diagnostics);
931931
}
932932
};
933933

@@ -1138,7 +1138,7 @@ void ModuleDependencyScanner::resolveSwiftImportsForModule(
11381138
ScanningThreadPool.wait();
11391139

11401140
auto recordResolvedModuleImport =
1141-
[&cache, &moduleLookupResult, &importedSwiftDependencies,
1141+
[this, &cache, &moduleLookupResult, &importedSwiftDependencies,
11421142
moduleID](const ScannerImportStatementInfo &moduleImport) {
11431143
if (moduleID.ModuleName == moduleImport.importIdentifier)
11441144
return;
@@ -1152,7 +1152,7 @@ void ModuleDependencyScanner::resolveSwiftImportsForModule(
11521152
} else {
11531153
// Cache discovered module dependencies.
11541154
if (!lookupResult.value().empty()) {
1155-
cache.recordDependencies(lookupResult.value());
1155+
cache.recordDependencies(lookupResult.value(), Diagnostics);
11561156
importedSwiftDependencies.insert({moduleImport.importIdentifier,
11571157
lookupResult.value()[0].first.Kind});
11581158
}
@@ -1306,7 +1306,7 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependenciesForModule(
13061306
ScanningThreadPool.wait();
13071307

13081308
// Aggregate both previously-cached and freshly-scanned module results
1309-
auto recordResult = [&cache, &swiftOverlayLookupResult,
1309+
auto recordResult = [this, &cache, &swiftOverlayLookupResult,
13101310
&swiftOverlayDependencies,
13111311
moduleID](const std::string &moduleName) {
13121312
auto lookupResult = swiftOverlayLookupResult[moduleName];
@@ -1318,7 +1318,7 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependenciesForModule(
13181318
{moduleName, cachedInfo.value()->getKind()});
13191319
} else {
13201320
// Cache discovered module dependencies.
1321-
cache.recordDependencies(lookupResult.value());
1321+
cache.recordDependencies(lookupResult.value(), Diagnostics);
13221322
if (!lookupResult.value().empty())
13231323
swiftOverlayDependencies.insert({moduleName, lookupResult.value()[0].first.Kind});
13241324
}

0 commit comments

Comments
 (0)