@@ -450,4 +450,205 @@ TEST(ToolChainTest, ConfigFileSearch) {
450
450
}
451
451
}
452
452
453
+ struct FileSystemWithError : public llvm ::vfs::FileSystem {
454
+ llvm::ErrorOr<llvm::vfs::Status> status (const Twine &Path) override {
455
+ return std::make_error_code (std::errc::no_such_file_or_directory);
456
+ }
457
+ llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
458
+ openFileForRead (const Twine &Path) override {
459
+ return std::make_error_code (std::errc::permission_denied);
460
+ }
461
+ llvm::vfs::directory_iterator dir_begin (const Twine &Dir,
462
+ std::error_code &EC) override {
463
+ return llvm::vfs::directory_iterator ();
464
+ }
465
+ std::error_code setCurrentWorkingDirectory (const Twine &Path) override {
466
+ return std::make_error_code (std::errc::permission_denied);
467
+ }
468
+ llvm::ErrorOr<std::string> getCurrentWorkingDirectory () const override {
469
+ return std::make_error_code (std::errc::permission_denied);
470
+ }
471
+ };
472
+
473
+ TEST (ToolChainTest, ConfigFileError) {
474
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions ();
475
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID (new DiagnosticIDs ());
476
+ std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer (
477
+ new SimpleDiagnosticConsumer ());
478
+ DiagnosticsEngine Diags (DiagID, &*DiagOpts, DiagConsumer.get (), false );
479
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS (new FileSystemWithError);
480
+
481
+ Driver TheDriver (" /home/test/bin/clang" , " arm-linux-gnueabi" , Diags,
482
+ " clang LLVM compiler" , FS);
483
+ std::unique_ptr<Compilation> C (
484
+ TheDriver.BuildCompilation ({" /home/test/bin/clang" , " --no-default-config" ,
485
+ " --config" , " ./root.cfg" , " --version" }));
486
+ ASSERT_TRUE (C);
487
+ ASSERT_TRUE (C->containsError ());
488
+ EXPECT_EQ (1U , Diags.getNumErrors ());
489
+ EXPECT_STREQ (" configuration file './root.cfg' cannot be opened: cannot get "
490
+ " absolute path" ,
491
+ DiagConsumer->Errors [0 ].c_str ());
492
+ }
493
+
494
+ TEST (ToolChainTest, BadConfigFile) {
495
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions ();
496
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID (new DiagnosticIDs ());
497
+ std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer (
498
+ new SimpleDiagnosticConsumer ());
499
+ DiagnosticsEngine Diags (DiagID, &*DiagOpts, DiagConsumer.get (), false );
500
+ IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS (
501
+ new llvm::vfs::InMemoryFileSystem);
502
+
503
+ #ifdef _WIN32
504
+ const char *TestRoot = " C:\\ " ;
505
+ #define FILENAME " C:/opt/root.cfg"
506
+ #define DIRNAME " C:/opt"
507
+ #else
508
+ const char *TestRoot = " /" ;
509
+ #define FILENAME " /opt/root.cfg"
510
+ #define DIRNAME " /opt"
511
+ #endif
512
+ // UTF-16 string must be aligned on 2-byte boundary. Strings and char arrays
513
+ // do not provide necessary alignment, so copy constant string into properly
514
+ // allocated memory in heap.
515
+ llvm::BumpPtrAllocator Alloc;
516
+ char *StrBuff = (char *)Alloc.Allocate (16 , 4 );
517
+ std::memset (StrBuff, 0 , 16 );
518
+ std::memcpy (StrBuff, " \xFF\xFE\x00\xD8\x00\x00 " , 6 );
519
+ StringRef BadUTF (StrBuff, 6 );
520
+ FS->setCurrentWorkingDirectory (TestRoot);
521
+ FS->addFile (" /opt/root.cfg" , 0 , llvm::MemoryBuffer::getMemBuffer (BadUTF));
522
+ FS->addFile (" /home/user/test.cfg" , 0 ,
523
+ llvm::MemoryBuffer::getMemBuffer (" @file.rsp" ));
524
+
525
+ {
526
+ Driver TheDriver (" /home/test/bin/clang" , " arm-linux-gnueabi" , Diags,
527
+ " clang LLVM compiler" , FS);
528
+ std::unique_ptr<Compilation> C (TheDriver.BuildCompilation (
529
+ {" /home/test/bin/clang" , " --config" , " /opt/root.cfg" , " --version" }));
530
+ ASSERT_TRUE (C);
531
+ ASSERT_TRUE (C->containsError ());
532
+ EXPECT_EQ (1U , DiagConsumer->Errors .size ());
533
+ EXPECT_STREQ (" cannot read configuration file '" FILENAME
534
+ " ': Could not convert UTF16 to UTF8" ,
535
+ DiagConsumer->Errors [0 ].c_str ());
536
+ }
537
+ DiagConsumer->clear ();
538
+ {
539
+ Driver TheDriver (" /home/test/bin/clang" , " arm-linux-gnueabi" , Diags,
540
+ " clang LLVM compiler" , FS);
541
+ std::unique_ptr<Compilation> C (TheDriver.BuildCompilation (
542
+ {" /home/test/bin/clang" , " --config" , " /opt" , " --version" }));
543
+ ASSERT_TRUE (C);
544
+ ASSERT_TRUE (C->containsError ());
545
+ EXPECT_EQ (1U , DiagConsumer->Errors .size ());
546
+ EXPECT_STREQ (" configuration file '" DIRNAME
547
+ " ' cannot be opened: not a regular file" ,
548
+ DiagConsumer->Errors [0 ].c_str ());
549
+ }
550
+ DiagConsumer->clear ();
551
+ {
552
+ Driver TheDriver (" /home/test/bin/clang" , " arm-linux-gnueabi" , Diags,
553
+ " clang LLVM compiler" , FS);
554
+ std::unique_ptr<Compilation> C (TheDriver.BuildCompilation (
555
+ {" /home/test/bin/clang" , " --config" , " root" ,
556
+ " --config-system-dir=" , " --config-user-dir=" , " --version" }));
557
+ ASSERT_TRUE (C);
558
+ ASSERT_TRUE (C->containsError ());
559
+ EXPECT_EQ (1U , DiagConsumer->Errors .size ());
560
+ EXPECT_STREQ (" configuration file 'root' cannot be found" ,
561
+ DiagConsumer->Errors [0 ].c_str ());
562
+ }
563
+
564
+ #undef FILENAME
565
+ #undef DIRNAME
566
+ }
567
+
568
+ TEST (ToolChainTest, ConfigInexistentInclude) {
569
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions ();
570
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID (new DiagnosticIDs ());
571
+ std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer (
572
+ new SimpleDiagnosticConsumer ());
573
+ DiagnosticsEngine Diags (DiagID, &*DiagOpts, DiagConsumer.get (), false );
574
+ IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS (
575
+ new llvm::vfs::InMemoryFileSystem);
576
+
577
+ #ifdef _WIN32
578
+ const char *TestRoot = " C:\\ " ;
579
+ #define USERCONFIG " C:\\ home\\ user\\ test.cfg"
580
+ #define UNEXISTENT " C:\\ home\\ user\\ file.rsp"
581
+ #else
582
+ const char *TestRoot = " /" ;
583
+ #define USERCONFIG " /home/user/test.cfg"
584
+ #define UNEXISTENT " /home/user/file.rsp"
585
+ #endif
586
+ FS->setCurrentWorkingDirectory (TestRoot);
587
+ FS->addFile (" /home/user/test.cfg" , 0 ,
588
+ llvm::MemoryBuffer::getMemBuffer (" @file.rsp" ));
589
+
590
+ {
591
+ Driver TheDriver (" /home/test/bin/clang" , " arm-linux-gnueabi" , Diags,
592
+ " clang LLVM compiler" , FS);
593
+ std::unique_ptr<Compilation> C (TheDriver.BuildCompilation (
594
+ {" /home/test/bin/clang" , " --config" , " test.cfg" ,
595
+ " --config-system-dir=" , " --config-user-dir=/home/user" , " --version" }));
596
+ ASSERT_TRUE (C);
597
+ ASSERT_TRUE (C->containsError ());
598
+ EXPECT_EQ (1U , DiagConsumer->Errors .size ());
599
+ EXPECT_STREQ (" cannot read configuration file '" USERCONFIG
600
+ " ': cannot not open file '" UNEXISTENT " '" ,
601
+ DiagConsumer->Errors [0 ].c_str ());
602
+ }
603
+
604
+ #undef USERCONFIG
605
+ #undef UNEXISTENT
606
+ }
607
+
608
+ TEST (ToolChainTest, ConfigRecursiveInclude) {
609
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions ();
610
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID (new DiagnosticIDs ());
611
+ std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer (
612
+ new SimpleDiagnosticConsumer ());
613
+ DiagnosticsEngine Diags (DiagID, &*DiagOpts, DiagConsumer.get (), false );
614
+ IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS (
615
+ new llvm::vfs::InMemoryFileSystem);
616
+
617
+ #ifdef _WIN32
618
+ const char *TestRoot = " C:\\ " ;
619
+ #define USERCONFIG " C:\\ home\\ user\\ test.cfg"
620
+ #define INCLUDED1 " C:\\ home\\ user\\ file1.cfg"
621
+ #else
622
+ const char *TestRoot = " /" ;
623
+ #define USERCONFIG " /home/user/test.cfg"
624
+ #define INCLUDED1 " /home/user/file1.cfg"
625
+ #endif
626
+ FS->setCurrentWorkingDirectory (TestRoot);
627
+ FS->addFile (" /home/user/test.cfg" , 0 ,
628
+ llvm::MemoryBuffer::getMemBuffer (" @file1.cfg" ));
629
+ FS->addFile (" /home/user/file1.cfg" , 0 ,
630
+ llvm::MemoryBuffer::getMemBuffer (" @file2.cfg" ));
631
+ FS->addFile (" /home/user/file2.cfg" , 0 ,
632
+ llvm::MemoryBuffer::getMemBuffer (" @file3.cfg" ));
633
+ FS->addFile (" /home/user/file3.cfg" , 0 ,
634
+ llvm::MemoryBuffer::getMemBuffer (" @file1.cfg" ));
635
+
636
+ {
637
+ Driver TheDriver (" /home/test/bin/clang" , " arm-linux-gnueabi" , Diags,
638
+ " clang LLVM compiler" , FS);
639
+ std::unique_ptr<Compilation> C (TheDriver.BuildCompilation (
640
+ {" /home/test/bin/clang" , " --config" , " test.cfg" ,
641
+ " --config-system-dir=" , " --config-user-dir=/home/user" , " --version" }));
642
+ ASSERT_TRUE (C);
643
+ ASSERT_TRUE (C->containsError ());
644
+ EXPECT_EQ (1U , DiagConsumer->Errors .size ());
645
+ EXPECT_STREQ (" cannot read configuration file '" USERCONFIG
646
+ " ': recursive expansion of: '" INCLUDED1 " '" ,
647
+ DiagConsumer->Errors [0 ].c_str ());
648
+ }
649
+
650
+ #undef USERCONFIG
651
+ #undef INCLUDED1
652
+ }
653
+
453
654
} // end anonymous namespace.
0 commit comments