@@ -307,7 +307,6 @@ public func funcB() { }\n"));
307
307
for (auto &command : CommandStr)
308
308
Command.push_back (command.c_str ());
309
309
310
- auto ScanDiagnosticConsumer = std::make_shared<DependencyScanDiagnosticCollector>();
311
310
312
311
auto DependenciesOrErr = ScannerTool.getDependencies (Command, {}, {});
313
312
@@ -329,3 +328,78 @@ public func funcB() { }\n"));
329
328
ASSERT_TRUE (Dependencies->dependencies ->modules [0 ]->link_libraries ->count == 0 );
330
329
swiftscan_dependency_graph_dispose (Dependencies);
331
330
}
331
+
332
+ TEST_F (ScanTest, TestStressConcurrentDiagnostics) {
333
+ SmallString<256 > tempDir;
334
+ ASSERT_FALSE (llvm::sys::fs::createUniqueDirectory (" ScanTest.TestStressConcurrentDiagnostics" , tempDir));
335
+ SWIFT_DEFER { llvm::sys::fs::remove_directories (tempDir); };
336
+
337
+ // Create includes
338
+ std::string IncludeDirPath = createFilename (tempDir, " include" );
339
+ ASSERT_FALSE (llvm::sys::fs::create_directory (IncludeDirPath));
340
+ std::string CHeadersDirPath = createFilename (IncludeDirPath, " CHeaders" );
341
+ ASSERT_FALSE (llvm::sys::fs::create_directory (CHeadersDirPath));
342
+
343
+ // Create test input file
344
+ std::string TestPathStr = createFilename (tempDir, " foo.swift" );
345
+
346
+ // Create imported module C modulemap/headers
347
+ std::string modulemapContent = " " ;
348
+ std::string testFileContent = " " ;
349
+ for (int i = 0 ; i < 100 ; ++i) {
350
+ std::string headerName = " A_" + std::to_string (i) + " .h" ;
351
+ std::string headerContent = " void funcA_" + std::to_string (i) + " (void);" ;
352
+ ASSERT_FALSE (
353
+ emitFileWithContents (CHeadersDirPath, headerName, headerContent));
354
+
355
+ std::string moduleMapEntry = " module A_" + std::to_string (i) + " {\n " ;
356
+ moduleMapEntry.append (" header \" A_" + std::to_string (i) + " .h\"\n " );
357
+ moduleMapEntry.append (" export *\n " );
358
+ moduleMapEntry.append (" }\n " );
359
+ modulemapContent.append (moduleMapEntry);
360
+ testFileContent.append (" import A_" + std::to_string (i) + " \n " );
361
+ }
362
+
363
+ ASSERT_FALSE (emitFileWithContents (tempDir, " foo.swift" , testFileContent));
364
+ ASSERT_FALSE (
365
+ emitFileWithContents (CHeadersDirPath, " module.modulemap" , modulemapContent));
366
+
367
+ // Paths to shims and stdlib
368
+ llvm::SmallString<128 > ShimsLibDir = StdLibDir;
369
+ llvm::sys::path::append (ShimsLibDir, " shims" );
370
+ auto Target = llvm::Triple (llvm::sys::getDefaultTargetTriple ());
371
+ llvm::sys::path::append (StdLibDir, getPlatformNameForTriple (Target));
372
+
373
+ std::vector<std::string> BaseCommandStrArr = {
374
+ TestPathStr,
375
+ std::string (" -I " ) + CHeadersDirPath,
376
+ std::string (" -I " ) + StdLibDir.str ().str (),
377
+ std::string (" -I " ) + ShimsLibDir.str ().str (),
378
+ // Pass in a flag which will cause every instantiation of
379
+ // the clang scanner to fail with "unknown argument"
380
+ " -Xcc" ,
381
+ " -foobar"
382
+ };
383
+
384
+ std::vector<std::string> CommandStr = BaseCommandStrArr;
385
+ CommandStr.push_back (" -module-name" );
386
+ CommandStr.push_back (" testConcurrentDiags" );
387
+
388
+ // On Windows we need to add an extra escape for path separator characters because otherwise
389
+ // the command line tokenizer will treat them as escape characters.
390
+ for (size_t i = 0 ; i < CommandStr.size (); ++i) {
391
+ std::replace (CommandStr[i].begin (), CommandStr[i].end (), ' \\ ' , ' /' );
392
+ }
393
+ std::vector<const char *> Command;
394
+ for (auto &command : CommandStr)
395
+ Command.push_back (command.c_str ());
396
+
397
+ auto DependenciesOrErr = ScannerTool.getDependencies (Command, {}, {});
398
+
399
+ // Ensure a hollow output with diagnostic info is produced
400
+ ASSERT_FALSE (DependenciesOrErr.getError ());
401
+ auto Dependencies = DependenciesOrErr.get ();
402
+ auto Diagnostics = Dependencies->diagnostics ;
403
+ ASSERT_TRUE (Diagnostics->count > 100 );
404
+ swiftscan_dependency_graph_dispose (Dependencies);
405
+ }
0 commit comments