https://github.com/vsapsai created https://github.com/llvm/llvm-project/pull/146976
Otherwise we are continuing in an invalid state and can easily crash. It is a follow-up to cde90e68f8123e7abef3f9e18d79980aa19f460a but an important difference is when a failure happens in a submodule. In this case in `Preprocessor::HandleEndOfFile` `tok::eof` is replaced by `tok::annot_module_end`. And after exiting a file with bad `#include/#import` we work with a new buffer, so `BufferPtr < BufferEnd`. As there are no signs to stop lexing we just keep doing it. The fix is the same as in dc9fdaf2171cc480300d5572606a8ede1678d18b in `Lexer::LexTokenInternal` but this time in `Lexer::LexDependencyDirectiveToken` as well. rdar://152499276 >From 6731f2079e69b7565875aa97f11829c1d758bf82 Mon Sep 17 00:00:00 2001 From: Volodymyr Sapsai <vsap...@apple.com> Date: Thu, 3 Jul 2025 16:40:26 -0700 Subject: [PATCH] [clang][deps] Stop lexing if hit a failure while loading a PCH/module in a submodule. Otherwise we are continuing in an invalid state and can easily crash. It is a follow-up to cde90e68f8123e7abef3f9e18d79980aa19f460a but an important difference is when a failure happens in a submodule. In this case in `Preprocessor::HandleEndOfFile` `tok::eof` is replaced by `tok::annot_module_end`. And after exiting a file with bad `#include/#import` we work with a new buffer, so `BufferPtr < BufferEnd`. As there are no signs to stop lexing we just keep doing it. The fix is the same as in `dc9fdaf2171cc480300d5572606a8ede1678d18b` in `Lexer::LexTokenInternal` but this time in `Lexer::LexDependencyDirectiveToken` as well. rdar://152499276 --- clang/lib/Lex/Lexer.cpp | 3 ++ .../ClangScanDeps/fatal-module-loader-error.m | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 clang/test/ClangScanDeps/fatal-module-loader-error.m diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 30ac48b8010b8..8a0560615bf97 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -4589,6 +4589,9 @@ bool Lexer::LexDependencyDirectiveToken(Token &Result) { if (Result.is(tok::hash) && Result.isAtStartOfLine()) { PP->HandleDirective(Result); + if (PP->hadModuleLoaderFatalFailure()) + // With a fatal failure in the module loader, we abort parsing. + return true; return false; } if (Result.is(tok::raw_identifier)) { diff --git a/clang/test/ClangScanDeps/fatal-module-loader-error.m b/clang/test/ClangScanDeps/fatal-module-loader-error.m new file mode 100644 index 0000000000000..ed4d8628a6471 --- /dev/null +++ b/clang/test/ClangScanDeps/fatal-module-loader-error.m @@ -0,0 +1,42 @@ +// This tests that after a fatal module loader error, we do not continue parsing. + +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: mkdir %t/ModulesCache +// RUN: touch %t/ModulesCache/Unusable.pcm + +// RUN: not clang-scan-deps -format experimental-full -mode preprocess-dependency-directives -- \ +// RUN: %clang -fmodules -fimplicit-modules -Xclang -fdisable-module-hash -fmodules-cache-path=%t/ModulesCache \ +// RUN: -F %t/Frameworks -c %t/test.m -o %t/test.o +// RUN: ls %t/ModulesCache | not grep AfterUnusable + +//--- Frameworks/Unusable.framework/Headers/Unusable.h +// empty +//--- Frameworks/Unusable.framework/Modules/module.modulemap +framework module Unusable { header "Unusable.h" } + +//--- Frameworks/AfterUnusable.framework/Headers/AfterUnusable.h +// empty +//--- Frameworks/AfterUnusable.framework/Modules/module.modulemap +framework module AfterUnusable { header "AfterUnusable.h" } + +//--- Frameworks/Importer.framework/Headers/Importer.h +#import <Importer/ImportUnusable.h> +// Parsing should have stopped and we should not handle AfterUnusable. +#import <AfterUnusable/AfterUnusable.h> + +//--- Frameworks/Importer.framework/Headers/ImportUnusable.h +// It is important that this header is a submodule. +#import <Unusable/Unusable.h> +// Parsing should have stopped and we should not handle AfterUnusable. +#import <AfterUnusable/AfterUnusable.h> + +//--- Frameworks/Importer.framework/Modules/module.modulemap +framework module Importer { + umbrella header "Importer.h" + module * { export * } + export * +} + +//--- test.m +#import <Importer/Importer.h> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits