From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id B88FB3858C2F; Thu, 15 Jun 2023 12:17:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B88FB3858C2F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686831420; bh=yvnA5Xudx1UhLrQ/o1iIWXlyT9NH7vFKXNC8B8Yf7YQ=; h=From:To:Subject:Date:From; b=tA6h09iO4SpvBViCiDxHJ/bFDnPikN4n3jEeBy5Kz9Ku+PCFWzhMhfu4Fn7t8QKkc d1QKPSC01JubfWEra7X7Tdwu2yvLt0cYFuDDR7W+64vamQJpHsUev8WuCPBa+j/P61 pav+EuO4ayYIVq7q9kQPADS3xlA4WOI2dqzdS3B0= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jakub Jelinek To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-1870] libcpp: Diagnose #include after failed __has_include [PR80753] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/master X-Git-Oldrev: 73a0d3bf895b5c322676178a51ac0d68cf603953 X-Git-Newrev: 37f373e974ac0a272b0e2b24e27c08833ad43470 Message-Id: <20230615121700.B88FB3858C2F@sourceware.org> Date: Thu, 15 Jun 2023 12:17:00 +0000 (GMT) List-Id: https://gcc.gnu.org/g:37f373e974ac0a272b0e2b24e27c08833ad43470 commit r14-1870-g37f373e974ac0a272b0e2b24e27c08833ad43470 Author: Jakub Jelinek Date: Thu Jun 15 14:16:17 2023 +0200 libcpp: Diagnose #include after failed __has_include [PR80753] As can be seen in the testcase, we don't diagnose #include/#include_next of a non-existent header if __has_include/__has_include_next is done for that header first. The problem is that we normally error the first time some header is not found, but in the _cpp_FFK_HAS_INCLUDE case obviously don't want to diagnose it, just expand it to 0. And libcpp caches both successful includes and unsuccessful ones. The following patch fixes that by remembering that we haven't diagnosed error when using __has_include* on it, and diagnosing it when using the cache entry in normal mode the first time. I think _cpp_FFK_NORMAL is the only mode in which we normally diagnose errors, for _cpp_FFK_PRE_INCLUDE that open_file_failed isn't reached and for _cpp_FFK_FAKE neither. 2023-06-15 Jakub Jelinek PR preprocessor/80753 libcpp/ * files.cc (struct _cpp_file): Add deferred_error bitfield. (_cpp_find_file): When finding a file in cache with deferred_error set in _cpp_FFK_NORMAL mode, call open_file_failed and clear the flag. Set deferred_error in _cpp_FFK_HAS_INCLUDE mode if open_file_failed hasn't been called. gcc/testsuite/ * c-c++-common/missing-header-5.c: New test. Diff: --- gcc/testsuite/c-c++-common/missing-header-5.c | 15 +++++++++++++++ libcpp/files.cc | 15 ++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) 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 00000000000..aa36c686d83 --- /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 3f8a8106ec8..43a8894b7de 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; }