Skip to content

Commit 2e87463

Browse files
authored
[Clang] Fix PPChainedCallbacks::EmbedFileNotFound() (#170293)
We've had internal test failures since #166188 landed. The root cause is that `PPChainedCallbacks::EmbedFileNotFound()` incorrectly calls `PPCallbacks::FileNotFound()` not `PPCallbacks::EmbedFileNotFound()`.
1 parent 09efb48 commit 2e87463

File tree

3 files changed

+60
-11
lines changed

3 files changed

+60
-11
lines changed

clang/include/clang/Lex/PPCallbacks.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,10 +499,10 @@ class PPChainedCallbacks : public PPCallbacks {
499499
}
500500

501501
bool EmbedFileNotFound(StringRef FileName) override {
502-
bool Skip = First->FileNotFound(FileName);
502+
bool Skip = First->EmbedFileNotFound(FileName);
503503
// Make sure to invoke the second callback, no matter if the first already
504504
// returned true to skip the file.
505-
Skip |= Second->FileNotFound(FileName);
505+
Skip |= Second->EmbedFileNotFound(FileName);
506506
return Skip;
507507
}
508508

clang/lib/Lex/PPDirectives.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,11 +1397,12 @@ void Preprocessor::HandleDirective(Token &Result) {
13971397
return HandleIdentSCCSDirective(Result);
13981398
case tok::pp_sccs:
13991399
return HandleIdentSCCSDirective(Result);
1400-
case tok::pp_embed:
1401-
return HandleEmbedDirective(SavedHash.getLocation(), Result,
1402-
getCurrentFileLexer()
1403-
? *getCurrentFileLexer()->getFileEntry()
1404-
: static_cast<FileEntry *>(nullptr));
1400+
case tok::pp_embed: {
1401+
if (PreprocessorLexer *CurrentFileLexer = getCurrentFileLexer())
1402+
if (OptionalFileEntryRef FERef = CurrentFileLexer->getFileEntry())
1403+
return HandleEmbedDirective(SavedHash.getLocation(), Result, *FERef);
1404+
return HandleEmbedDirective(SavedHash.getLocation(), Result, nullptr);
1405+
}
14051406
case tok::pp_assert:
14061407
//isExtension = true; // FIXME: implement #assert
14071408
break;

clang/unittests/Lex/PPCallbacksTest.cpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ TEST_F(PPCallbacksTest, FileNotFoundSkipped) {
437437
PreprocessorOptions PPOpts;
438438
HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts, Target.get());
439439

440+
unsigned int NumCalls = 0;
440441
DiagnosticConsumer *DiagConsumer = new DiagnosticConsumer;
441442
DiagnosticsEngine FileNotFoundDiags(DiagID, DiagOpts, DiagConsumer);
442443
Preprocessor PP(PPOpts, FileNotFoundDiags, LangOpts, SourceMgr, HeaderInfo,
@@ -445,21 +446,68 @@ TEST_F(PPCallbacksTest, FileNotFoundSkipped) {
445446

446447
class FileNotFoundCallbacks : public PPCallbacks {
447448
public:
448-
unsigned int NumCalls = 0;
449+
unsigned int &NumCalls;
450+
451+
FileNotFoundCallbacks(unsigned int &NumCalls) : NumCalls(NumCalls) {}
452+
449453
bool FileNotFound(StringRef FileName) override {
450454
NumCalls++;
451455
return FileName == "skipped.h";
452456
}
453457
};
454458

455-
auto *Callbacks = new FileNotFoundCallbacks;
456-
PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
459+
PP.addPPCallbacks(std::make_unique<FileNotFoundCallbacks>(NumCalls));
460+
461+
// Lex source text.
462+
PP.EnterMainSourceFile();
463+
PP.LexTokensUntilEOF();
464+
465+
ASSERT_EQ(1u, NumCalls);
466+
ASSERT_EQ(0u, DiagConsumer->getNumErrors());
467+
}
468+
469+
TEST_F(PPCallbacksTest, EmbedFileNotFoundChained) {
470+
const char *SourceText = "#embed \"notfound.h\"\n";
471+
472+
std::unique_ptr<llvm::MemoryBuffer> SourceBuf =
473+
llvm::MemoryBuffer::getMemBuffer(SourceText);
474+
SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf)));
475+
476+
unsigned int NumCalls = 0;
477+
HeaderSearchOptions HSOpts;
478+
TrivialModuleLoader ModLoader;
479+
PreprocessorOptions PPOpts;
480+
HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts, Target.get());
481+
482+
DiagnosticConsumer *DiagConsumer = new DiagnosticConsumer;
483+
DiagnosticsEngine EmbedFileNotFoundDiags(DiagID, DiagOpts, DiagConsumer);
484+
Preprocessor PP(PPOpts, EmbedFileNotFoundDiags, LangOpts, SourceMgr,
485+
HeaderInfo, ModLoader, /*IILookup=*/nullptr,
486+
/*OwnsHeaderSearch=*/false);
487+
PP.Initialize(*Target);
488+
489+
class EmbedFileNotFoundCallbacks : public PPCallbacks {
490+
public:
491+
unsigned int &NumCalls;
492+
493+
EmbedFileNotFoundCallbacks(unsigned int &NumCalls) : NumCalls(NumCalls) {}
494+
495+
bool EmbedFileNotFound(StringRef FileName) override {
496+
NumCalls++;
497+
return true;
498+
}
499+
};
500+
501+
// Add two instances of `EmbedFileNotFoundCallbacks` to ensure the
502+
// preprocessor is using an instance of `PPChainedCallbaks`.
503+
PP.addPPCallbacks(std::make_unique<EmbedFileNotFoundCallbacks>(NumCalls));
504+
PP.addPPCallbacks(std::make_unique<EmbedFileNotFoundCallbacks>(NumCalls));
457505

458506
// Lex source text.
459507
PP.EnterMainSourceFile();
460508
PP.LexTokensUntilEOF();
461509

462-
ASSERT_EQ(1u, Callbacks->NumCalls);
510+
ASSERT_EQ(2u, NumCalls);
463511
ASSERT_EQ(0u, DiagConsumer->getNumErrors());
464512
}
465513

0 commit comments

Comments
 (0)