diff --git a/include/boost/wave/util/cpp_macromap.hpp b/include/boost/wave/util/cpp_macromap.hpp index fad958a3..c7b93bc4 100644 --- a/include/boost/wave/util/cpp_macromap.hpp +++ b/include/boost/wave/util/cpp_macromap.hpp @@ -224,7 +224,6 @@ class macromap { void rescan_replacement_list(token_type const &curr_token, macro_definition_type ¯odef, ContainerT &replacement_list, ContainerT &expanded, bool expand_operator_defined, - bool expand_operator_has_include, IteratorT &nfirst, IteratorT const &nlast); // Resolves the operator defined() and replaces the token with "0" or "1" @@ -1363,7 +1362,6 @@ macromap::rescan_replacement_list(token_type const &curr_token, macro_definition_type ¯o_def, ContainerT &replacement_list, ContainerT &expanded, bool expand_operator_defined, - bool expand_operator_has_include, IteratorT &nfirst, IteratorT const &nlast) { if (!replacement_list.empty()) { @@ -1394,9 +1392,11 @@ macromap::rescan_replacement_list(token_type const &curr_token, typename ContainerT::iterator begin_it = replacement_list.begin(); typename ContainerT::iterator end_it = replacement_list.end(); + // The replacement list does not contain tokens following the macro invocation. + // Defer __has_include resolution until the expanded tokens are rescanned with those tokens available. expand_whole_tokensequence( expanded, begin_it, end_it, - expand_operator_defined, expand_operator_has_include); + expand_operator_defined, false); // trim replacement list, leave placeholder tokens untouched impl::trim_replacement_list(expanded); @@ -1643,7 +1643,7 @@ macromap::expand_macro(ContainerT &expanded, rescan_replacement_list( curr_token, macro_def, replacement_list, expanded_list, expand_operator_defined, - expand_operator_has_include, first, last); + first, last); ctx.get_hooks().rescanned_macro(ctx.derived(), expanded_list); diff --git a/test/testwave/testfiles/t_2_033.cpp b/test/testwave/testfiles/t_2_033.cpp new file mode 100644 index 00000000..9bab81eb --- /dev/null +++ b/test/testwave/testfiles/t_2_033.cpp @@ -0,0 +1,32 @@ +/*============================================================================= + Boost.Wave: A Standard compliant C++ preprocessor library + http://www.boost.org/ + + Copyright (c) 2026 Martin Medler. Distributed under the Boost + Software License, Version 1.0. (See accompanying file + LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +//O --c++17 +//O -Werror +//O -S. + +// An object-like macro alias for __has_include must be expanded once before +// resolving the operator. +#define HAS_INCLUDE __has_include +#if HAS_INCLUDE() +#define FOUND_SELF_VIA_ALIAS +#else +#warning has_include could not find this file through an alias +#endif + +//H 10: t_2_033.cpp(16): #define +//H 08: t_2_033.cpp(16): HAS_INCLUDE=__has_include +//H 10: t_2_033.cpp(17): #if +//H 01: t_2_033.cpp(16): HAS_INCLUDE +//H 02: __has_include +//H 03: __has_include +//H 11: t_2_033.cpp(17): #if HAS_INCLUDE(): 1 +//H 10: t_2_033.cpp(18): #define +//H 08: t_2_033.cpp(18): FOUND_SELF_VIA_ALIAS= +//H 10: t_2_033.cpp(19): #else diff --git a/test/testwave/testfiles/test.cfg b/test/testwave/testfiles/test.cfg index 10d51b91..872f04a5 100644 --- a/test/testwave/testfiles/test.cfg +++ b/test/testwave/testfiles/test.cfg @@ -85,6 +85,7 @@ t_2_029.cpp t_2_030.cpp t_2_031.cpp t_2_032.cpp +t_2_033.cpp # # t_3: Predefined macros