diff --git a/gcc/testsuite/c-c++-common/missing-header-5.c b/gcc/testsuite/c-c++-common/missing-header-5.c new file mode 100644 index 0000000000000000000000000000000000000000..aa36c686d83458a47c58cc9219b2c973f8de90cf --- /dev/null +++ b/gcc/testsuite/c-c++-common/missing-header-5.c @@ -0,0 +1,15 @@ +/* PR preprocessor/80753 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +#if __has_include("nonexistent.h") +# error +#endif + +#include "nonexistent.h" + +/* { dg-message "nonexistent.h" "nonexistent.h" { target *-*-* } 0 } */ +/* { dg-message "terminated" "terminated" { target *-*-* } 0 } */ + +/* This declaration should not receive any diagnostic. */ +foo bar; diff --git a/libcpp/files.cc b/libcpp/files.cc index 3f8a8106ec8b566d054e0b5352dbe383dc6d51e3..43a8894b7deca1bcc3bee277714319512617881a 100644 --- a/libcpp/files.cc +++ b/libcpp/files.cc @@ -109,6 +109,10 @@ struct _cpp_file /* If this file is implicitly preincluded. */ bool implicit_preinclude : 1; + /* Set if a header wasn't found with __has_include or __has_include_next + and error should be emitted if it is included normally. */ + bool deferred_error : 1; + /* > 0: Known C++ Module header unit, <0: known not. ==0, unknown */ int header_unit : 2; }; @@ -523,7 +527,14 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, cpp_file_hash_entry *entry = search_cache ((struct cpp_file_hash_entry *) *hash_slot, start_dir); if (entry) - return entry->u.file; + { + if (entry->u.file->deferred_error && kind == _cpp_FFK_NORMAL) + { + open_file_failed (pfile, entry->u.file, angle_brackets, loc); + entry->u.file->deferred_error = false; + } + return entry->u.file; + } _cpp_file *file = make_cpp_file (start_dir, fname); file->implicit_preinclude @@ -589,6 +600,8 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, if (kind != _cpp_FFK_HAS_INCLUDE) open_file_failed (pfile, file, angle_brackets, loc); + else + file->deferred_error = true; break; }