c++: Warn on #undef/#define of remaining cpp.predefined macros [PR120778]

We already warn on #undef or pedwarn on #define (but not on #define
after #undef) of some builtin macros mentioned in cpp.predefined.

The C++26 P2843R3 paper changes it from (compile time) undefined behavior
to ill-formed.  The following patch arranges for warning (for #undef)
and pedwarn (on #define) for the remaining cpp.predefined macros.
__cpp_* feature test macros only for C++20 which added some of them
to cpp.predefined, in earlier C++ versions it was just an extension and
for pedantic diagnostic I think we don't need to diagnose anything,
__STDCPP_* and __cplusplus macros for all C++ versions where they appeared.

Like the earlier posted -Wkeyword-macro diagnostics (which is done
regardless whether the identifier is defined as a macro or not, obviously
most likely none of the keywords are defined as macros initially), this
one also warns on #undef when a macro isn't defined or later #define
after #undef.

2025-08-15  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/120778
	PR target/121520
gcc/c-family/
	* c-cppbuiltin.cc (c_cpp_builtins): Implement C++26 DR 2581.  Add
	cpp_define_warn lambda and use it as well as cpp_warn where needed.
	In the if (c_dialect_cxx ()) block with __cpp_* predefinitions add
	cpp_define lambda.  Formatting fixes.
gcc/c/
	* c-decl.cc (c_init_decl_processing): Use cpp_warn instead of
	cpp_lookup and NODE_WARN bit setting.
gcc/cp/
	* lex.cc (cxx_init): Remove warn_on lambda.  Use cpp_warn instead of
	cpp_lookup and NODE_WARN bit setting or warn_on.
gcc/testsuite/
	* g++.dg/DRs/dr2581-1.C: New test.
	* g++.dg/DRs/dr2581-2.C: New test.
	* c-c++-common/cpp/pr92296-2.c: Expect warnings also on defining
	special macros after undefining them.
libcpp/
	* include/cpplib.h (struct cpp_options): Add
	suppress_builtin_macro_warnings member.
	(cpp_warn): New inline functions.
	* init.cc (cpp_create_reader): Clear suppress_builtin_macro_warnings.
	(cpp_init_builtins): Call cpp_warn on __cplusplus, __STDC__,
	__STDC_VERSION__, __STDC_MB_MIGHT_NEQ_WC__ and
	__STDCPP_STRICT_POINTER_SAFETY__ when appropriate.
	* directives.cc (do_undef): Warn on undefining NODE_WARN macros if
	not cpp_keyword_p.  Don't emit any NODE_WARN related diagnostics
	if CPP_OPTION (pfile, suppress_builtin_macro_warnings).
	(cpp_define, _cpp_define_builtin, cpp_undef): Temporarily set
	CPP_OPTION (pfile, suppress_builtin_macro_warnings) around
	run_directive calls.
	* macro.cc (_cpp_create_definition): Warn on defining NODE_WARN
	macros if they weren't previously defined and not cpp_keyword_p.
	Ignore NODE_WARN for diagnostics if
	CPP_OPTION (pfile, suppress_builtin_macro_warnings).
This commit is contained in:
Jakub Jelinek 2025-08-15 22:31:27 +02:00 committed by Jakub Jelinek
parent 87f354ca75
commit cdd015c4dd
10 changed files with 357 additions and 47 deletions

View File

@ -913,23 +913,42 @@ c_cpp_builtins (cpp_reader *pfile)
/* encoding definitions used by users and libraries */
builtin_define_with_value ("__GNUC_EXECUTION_CHARSET_NAME",
cpp_get_narrow_charset_name (pfile), 1);
cpp_get_narrow_charset_name (pfile), 1);
builtin_define_with_value ("__GNUC_WIDE_EXECUTION_CHARSET_NAME",
cpp_get_wide_charset_name (pfile), 1);
cpp_get_wide_charset_name (pfile), 1);
if (c_dialect_cxx ())
{
int major;
parse_basever (&major, NULL, NULL);
cpp_define_formatted (pfile, "__GNUG__=%d", major);
}
{
int major;
parse_basever (&major, NULL, NULL);
cpp_define_formatted (pfile, "__GNUG__=%d", major);
}
/* For stddef.h. They require macros defined in c-common.cc. */
c_stddef_cpp_builtins ();
/* Variant of cpp_define which arranges for diagnostics on user #define
or #undef of the macros. */
auto cpp_define_warn = [] (cpp_reader *pfile, const char *def)
{
const char *end = strchr (def, '=');
cpp_define (pfile, def);
cpp_warn (pfile, def, end ? end - def : strlen (def));
};
if (c_dialect_cxx ())
{
/* Treat all cpp_define calls in this block for macros starting
with __cpp_ (for C++20 and later) or __STDCPP_ as cpp_define_warn. */
auto cpp_define = [=] (cpp_reader *pfile, const char *def)
{
if ((cxx_dialect >= cxx20 && startswith (def, "__cpp_"))
|| startswith (def, "__STDCPP_"))
cpp_define_warn (pfile, def);
else
::cpp_define (pfile, def);
};
if (flag_weak && SUPPORTS_ONE_ONLY)
cpp_define (pfile, "__GXX_WEAK__=1");
else
@ -1101,42 +1120,65 @@ c_cpp_builtins (cpp_reader *pfile)
}
if (flag_concepts && cxx_dialect > cxx14)
cpp_define (pfile, "__cpp_concepts=202002L");
else if (cxx_dialect >= cxx20)
cpp_warn (pfile, "__cpp_concepts");
if (flag_contracts)
{
cpp_define (pfile, "__cpp_contracts=201906L");
cpp_define (pfile, "__cpp_contracts_literal_semantics=201906L");
cpp_define (pfile, "__cpp_contracts_roles=201906L");
}
else if (cxx_dialect >= cxx26)
cpp_warn (pfile, "__cpp_contracts");
if (flag_modules)
/* The std-defined value is 201907L, but I don't think we can
claim victory yet. 201810 is the p1103 date. */
cpp_define (pfile, "__cpp_modules=201810L");
else if (cxx_dialect >= cxx20)
cpp_warn (pfile, "__cpp_modules");
if (flag_coroutines)
cpp_define (pfile, "__cpp_impl_coroutine=201902L"); /* n4861, DIS */
else if (cxx_dialect >= cxx20)
cpp_warn (pfile, "__cpp_impl_coroutine");
if (flag_tm)
/* Use a value smaller than the 201505 specified in
the TS, since we don't yet support atomic_cancel. */
cpp_define (pfile, "__cpp_transactional_memory=201500L");
if (flag_sized_deallocation)
cpp_define (pfile, "__cpp_sized_deallocation=201309L");
else if (cxx_dialect >= cxx20)
cpp_warn (pfile, "__cpp_sized_deallocation");
if (aligned_new_threshold)
{
cpp_define (pfile, "__cpp_aligned_new=201606L");
cpp_define_formatted (pfile, "__STDCPP_DEFAULT_NEW_ALIGNMENT__=%d",
aligned_new_threshold);
}
else if (cxx_dialect >= cxx20)
cpp_warn (pfile, "__cpp_aligned_new");
if (cxx_dialect >= cxx17)
cpp_warn (pfile, "__STDCPP_DEFAULT_NEW_ALIGNMENT__");
if (flag_new_ttp)
cpp_define (pfile, "__cpp_template_template_args=201611L");
else if (cxx_dialect >= cxx20)
cpp_warn (pfile, "__cpp_template_template_args");
if (flag_threadsafe_statics)
cpp_define (pfile, "__cpp_threadsafe_static_init=200806L");
else if (cxx_dialect >= cxx20)
cpp_warn (pfile, "__cpp_threadsafe_static_init");
if (flag_char8_t)
cpp_define (pfile, "__cpp_char8_t=202207L");
else if (cxx_dialect >= cxx20)
cpp_warn (pfile, "__cpp_char8_t");
#ifndef THREAD_MODEL_SPEC
/* Targets that define THREAD_MODEL_SPEC need to define
__STDCPP_THREADS__ in their config/XXX/XXX-c.c themselves. */
if (cxx_dialect >= cxx11 && strcmp (thread_model, "single") != 0)
cpp_define (pfile, "__STDCPP_THREADS__=1");
else
#endif
if (cxx_dialect >= cxx11)
cpp_warn (pfile, "__STDCPP_THREADS__");
if (flag_implicit_constexpr)
cpp_define (pfile, "__cpp_implicit_constexpr=20211111L");
}
@ -1293,7 +1335,13 @@ c_cpp_builtins (cpp_reader *pfile)
{
char name[sizeof ("__STDCPP_FLOAT128_T__=1")];
sprintf (name, "__STDCPP_FLOAT%d_T__=1", floatn_nx_types[i].n);
cpp_define (pfile, name);
cpp_define_warn (pfile, name);
}
else if (cxx_dialect >= cxx23)
{
char name[sizeof ("__STDCPP_FLOAT128_T__")];
sprintf (name, "__STDCPP_FLOAT%d_T__", floatn_nx_types[i].n);
cpp_warn (pfile, name);
}
char prefix[20], csuffix[20];
sprintf (prefix, "FLT%d%s", floatn_nx_types[i].n,
@ -1306,10 +1354,12 @@ c_cpp_builtins (cpp_reader *pfile)
if (bfloat16_type_node)
{
if (c_dialect_cxx () && cxx_dialect > cxx20)
cpp_define (pfile, "__STDCPP_BFLOAT16_T__=1");
cpp_define_warn (pfile, "__STDCPP_BFLOAT16_T__=1");
builtin_define_float_constants ("BFLT16", "BF16", "%s",
"BF16", bfloat16_type_node);
}
else if (cxx_dialect >= cxx23)
cpp_warn (pfile, "__STDCPP_BFLOAT16_T__");
/* For float.h. */
if (targetm.decimal_float_supported_p ())

View File

@ -4843,9 +4843,8 @@ c_init_decl_processing (void)
tree id = get_identifier (c_common_reswords[i].word);
if (C_IS_RESERVED_WORD (id)
&& C_RID_CODE (id) != RID_CXX_COMPAT_WARN)
cpp_lookup (parse_in,
(const unsigned char *) IDENTIFIER_POINTER (id),
IDENTIFIER_LENGTH (id))->flags |= NODE_WARN;
cpp_warn (parse_in, IDENTIFIER_POINTER (id),
IDENTIFIER_LENGTH (id));
}
}
}

View File

@ -384,47 +384,42 @@ cxx_init (void)
if (IDENTIFIER_KEYWORD_P (id)
/* Don't register keywords with spaces. */
&& IDENTIFIER_POINTER (id)[IDENTIFIER_LENGTH (id) - 1] != ' ')
cpp_lookup (parse_in,
(const unsigned char *) IDENTIFIER_POINTER (id),
IDENTIFIER_LENGTH (id))->flags |= NODE_WARN;
cpp_warn (parse_in, IDENTIFIER_POINTER (id),
IDENTIFIER_LENGTH (id));
}
auto warn_on = [] (const char *name) {
cpp_lookup (parse_in, (const unsigned char *) name,
strlen (name))->flags |= NODE_WARN;
};
if (cxx_dialect >= cxx11)
{
warn_on ("final");
warn_on ("override");
warn_on ("noreturn");
cpp_warn (parse_in, "final");
cpp_warn (parse_in, "override");
cpp_warn (parse_in, "noreturn");
if (cxx_dialect < cxx26)
warn_on ("carries_dependency");
cpp_warn (parse_in, "carries_dependency");
}
if (cxx_dialect >= cxx14)
warn_on ("deprecated");
cpp_warn (parse_in, "deprecated");
if (cxx_dialect >= cxx17)
{
warn_on ("fallthrough");
warn_on ("maybe_unused");
warn_on ("nodiscard");
cpp_warn (parse_in, "fallthrough");
cpp_warn (parse_in, "maybe_unused");
cpp_warn (parse_in, "nodiscard");
}
if (cxx_dialect >= cxx20)
{
warn_on ("likely");
warn_on ("unlikely");
warn_on ("no_unique_address");
cpp_warn (parse_in, "likely");
cpp_warn (parse_in, "unlikely");
cpp_warn (parse_in, "no_unique_address");
}
if (flag_modules)
{
warn_on ("import");
warn_on ("module");
cpp_warn (parse_in, "import");
cpp_warn (parse_in, "module");
}
if (cxx_dialect >= cxx23)
warn_on ("assume");
cpp_warn (parse_in, "assume");
if (cxx_dialect >= cxx26)
{
warn_on ("replaceable_if_eligible");
warn_on ("trivially_relocatable_if_eligible");
cpp_warn (parse_in, "replaceable_if_eligible");
cpp_warn (parse_in, "trivially_relocatable_if_eligible");
}
}

View File

@ -39,42 +39,42 @@ filebase2 = __BASE_FILE__ /* { dg-final { scan-file-not pr92296-2.i "filebase2 =
#pragma push_macro("__LINE__")
#undef __LINE__ /* { dg-warning "undefining" } */
#define __LINE__ 142
#define __LINE__ 142 /* { dg-warning "defined" } */
line1 = __LINE__ /* { dg-final { scan-file pr92296-2.i "line1 = 142" } } */
#pragma pop_macro("__LINE__")
line2 = __LINE__ /* { dg-final { scan-file pr92296-2.i "line2 = 45" } } */
#pragma push_macro("__INCLUDE_LEVEL__")
#undef __INCLUDE_LEVEL__ /* { dg-warning "undefining" } */
#define __INCLUDE_LEVEL__ 42
#define __INCLUDE_LEVEL__ 42 /* { dg-warning "defined" } */
includelevel1 = __INCLUDE_LEVEL__ /* { dg-final { scan-file pr92296-2.i "includelevel1 = 42" } } */
#pragma pop_macro("__INCLUDE_LEVEL__")
includelevel2 = __INCLUDE_LEVEL__ /* { dg-final { scan-file pr92296-2.i "includelevel2 = 0" } } */
#pragma push_macro("__COUNTER__")
#undef __COUNTER__ /* { dg-warning "undefining" } */
#define __COUNTER__ 172
#define __COUNTER__ 172 /* { dg-warning "defined" } */
counter1 = __COUNTER__ /* { dg-final { scan-file pr92296-2.i "counter1 = 172" } } */
#pragma pop_macro("__COUNTER__")
counter2 = __COUNTER__ /* { dg-final { scan-file-not pr92296-2.i "counter2 = 172" } } */
#pragma push_macro("__has_attribute")
#undef __has_attribute /* { dg-warning "undefining" } */
#define __has_attribute(x) 0
#define __has_attribute(x) 0 /* { dg-warning "defined" } */
hasattr1 = __has_attribute(noreturn) /* { dg-final { scan-file pr92296-2.i "hasattr1 = 0" } } */
#pragma pop_macro("__has_attribute")
hasattr2 = __has_attribute(noreturn) /* { dg-final { scan-file-not pr92296-2.i "hasattr2 = 0" } } */
#pragma push_macro("__has_cpp_attribute")
#undef __has_cpp_attribute /* { dg-warning "undefining" } */
#define __has_cpp_attribute(x) 0
#define __has_cpp_attribute(x) 0 /* { dg-warning "defined" } */
hasattrcpp1 = __has_cpp_attribute(noreturn) /* { dg-final { scan-file pr92296-2.i "hasattrcpp1 = 0" } } */
#pragma pop_macro("__has_cpp_attribute")
hasattrcpp2 = __has_cpp_attribute(noreturn) /* { dg-final { scan-file-not pr92296-2.i "hasattrcpp2 = 0" } } */
#pragma push_macro("__has_builtin")
#undef __has_builtin /* { dg-warning "undefining" } */
#define __has_builtin(x) 0
#define __has_builtin(x) 0 /* { dg-warning "defined" } */
hasbuiltin1 = __has_builtin(__builtin_expect) /* { dg-final { scan-file pr92296-2.i "hasbuiltin1 = 0" } } */
#pragma pop_macro("__has_builtin")
hasbuiltin2 = __has_builtin(__builtin_expect) /* { dg-final { scan-file pr92296-2.i "hasbuiltin2 = 1" } } */

View File

@ -0,0 +1,106 @@
// DR 2581 - Undefined behavior for predefined macros
// { dg-do preprocess }
// { dg-additional-options "-fcontracts" { target c++26 } }
// { dg-additional-options "-fmodules -fcoroutines" { target c++20 } }
#undef defined // { dg-error "'defined' cannot be used as a macro name" }
#undef __cplusplus // { dg-warning "undefining '__cplusplus'" }
#undef __DATE__ // { dg-warning "undefining '__DATE__'" }
#undef __FILE__ // { dg-warning "undefining '__FILE__'" }
#undef __LINE__ // { dg-warning "undefining '__LINE__'" }
#undef __STDC_EMBED_NOT_FOUND__ // { dg-warning "undefining '__STDC_EMBED_NOT_FOUND__'" }
#undef __STDC_EMBED_FOUND__ // { dg-warning "undefining '__STDC_EMBED_FOUND__'" }
#undef __STDC_EMBED_EMPTY__ // { dg-warning "undefining '__STDC_EMBED_EMPTY__'" }
#undef __STDC_HOSTED__ // { dg-warning "undefining '__STDC_HOSTED__'" }
#undef __STDCPP_DEFAULT_NEW_ALIGNMENT__ // { dg-warning "undefining '__STDCPP_DEFAULT_NEW_ALIGNMENT__'" "" { target c++17 } }
#undef __STDCPP_FLOAT16_T__ // { dg-warning "undefining '__STDCPP_FLOAT16_T__'" "" { target c++23 } }
#undef __STDCPP_FLOAT32_T__ // { dg-warning "undefining '__STDCPP_FLOAT32_T__'" "" { target c++23 } }
#undef __STDCPP_FLOAT64_T__ // { dg-warning "undefining '__STDCPP_FLOAT64_T__'" "" { target c++23 } }
#undef __STDCPP_FLOAT128_T__ // { dg-warning "undefining '__STDCPP_FLOAT128_T__'" "" { target c++23 } }
#undef __STDCPP_BFLOAT16_T__ // { dg-warning "undefining '__STDCPP_BFLOAT16_T__'" "" { target c++23 } }
#undef __TIME__ // { dg-warning "undefining '__TIME__'" }
#undef __STDC__ // { dg-warning "undefining '__STDC__'" }
#undef __STDC_MB_MIGHT_NEQ_WC__ // { dg-warning "undefining '__STDC_MB_MIGHT_NEQ_WC__'" "" { target c++11 } }
#undef __STDC_VERSION__ // { dg-warning "undefining '__STDC_VERSION__'" "" { target c++11 } }
#undef __STDC_ISO_10646__ // { dg-warning "undefining '__STDC_ISO_10646__'" }
#undef __STDCPP_THREADS__ // { dg-warning "undefining '__STDCPP_THREADS__'" "" { target c++11 } }
#undef __STDCPP_STRICT_POINTER_SAFETY__ // { dg-warning "undefining '__STDCPP_STRICT_POINTER_SAFETY__'" "" { target { c++11 && c++20_down } } }
#undef __cpp_aggregate_bases // { dg-warning "undefining '__cpp_aggregate_bases'" "" { target c++20 } }
#undef __cpp_aggregate_nsdmi // { dg-warning "undefining '__cpp_aggregate_nsdmi'" "" { target c++20 } }
#undef __cpp_aggregate_paren_init // { dg-warning "undefining '__cpp_aggregate_paren_init'" "" { target c++20 } }
#undef __cpp_alias_templates // { dg-warning "undefining '__cpp_alias_templates'" "" { target c++20 } }
#undef __cpp_aligned_new // { dg-warning "undefining '__cpp_aligned_new'" "" { target c++20 } }
#undef __cpp_attributes // { dg-warning "undefining '__cpp_attributes'" "" { target c++20 } }
#undef __cpp_auto_cast // { dg-warning "undefining '__cpp_auto_cast'" "" { target c++23 } }
#undef __cpp_binary_literals // { dg-warning "undefining '__cpp_binary_literals'" "" { target c++20 } }
#undef __cpp_capture_star_this // { dg-warning "undefining '__cpp_capture_star_this'" "" { target c++20 } }
#undef __cpp_char8_t // { dg-warning "undefining '__cpp_char8_t'" "" { target c++20 } }
#undef __cpp_concepts // { dg-warning "undefining '__cpp_concepts'" "" { target c++20 } }
#undef __cpp_conditional_explicit // { dg-warning "undefining '__cpp_conditional_explicit'" "" { target c++20 } }
#undef __cpp_constexpr // { dg-warning "undefining '__cpp_constexpr'" "" { target c++20 } }
#undef __cpp_constexpr_dynamic_alloc // { dg-warning "undefining '__cpp_constexpr_dynamic_alloc'" "" { target c++20 } }
#undef __cpp_constexpr_exceptions // { dg-warning "undefining '__cpp_constexpr_exceptions'" "" { target c++26 } }
#undef __cpp_constexpr_in_decltype // { dg-warning "undefining '__cpp_constexpr_in_decltype'" "" { target c++20 } }
#undef __cpp_constexpr_virtual_inheritance // { dg-warning "undefining '__cpp_constexpr_virtual_inheritance'" "" { target c++26 } }
#undef __cpp_consteval // { dg-warning "undefining '__cpp_consteval'" "" { target c++20 } }
#undef __cpp_constinit // { dg-warning "undefining '__cpp_constinit'" "" { target c++20 } }
#undef __cpp_contracts // { dg-warning "undefining '__cpp_contracts'" "" { target c++26 } }
#undef __cpp_decltype // { dg-warning "undefining '__cpp_decltype'" "" { target c++20 } }
#undef __cpp_decltype_auto // { dg-warning "undefining '__cpp_decltype_auto'" "" { target c++20 } }
#undef __cpp_deduction_guides // { dg-warning "undefining '__cpp_deduction_guides'" "" { target c++20 } }
#undef __cpp_delegating_constructors // { dg-warning "undefining '__cpp_delegating_constructors'" "" { target c++20 } }
#undef __cpp_deleted_function // { dg-warning "undefining '__cpp_deleted_function'" "" { target c++26 } }
#undef __cpp_designated_initializers // { dg-warning "undefining '__cpp_designated_initializers'" "" { target c++20 } }
#undef __cpp_enumerator_attributes // { dg-warning "undefining '__cpp_enumerator_attributes'" "" { target c++20 } }
#undef __cpp_expansion_statements // { dg-warning "undefining '__cpp_expansion_statements'" "" { target c++26 } }
#undef __cpp_explicit_this_parameter // { dg-warning "undefining '__cpp_explicit_this_parameter'" "" { target c++23 } }
#undef __cpp_fold_expressions // { dg-warning "undefining '__cpp_fold_expressions'" "" { target c++20 } }
#undef __cpp_generic_lambdas // { dg-warning "undefining '__cpp_generic_lambdas'" "" { target c++20 } }
#undef __cpp_guaranteed_copy_elision // { dg-warning "undefining '__cpp_guaranteed_copy_elision'" "" { target c++20 } }
#undef __cpp_hex_float // { dg-warning "undefining '__cpp_hex_float'" "" { target c++20 } }
#undef __cpp_if_consteval // { dg-warning "undefining '__cpp_if_consteval'" "" { target c++23 } }
#undef __cpp_if_constexpr // { dg-warning "undefining '__cpp_if_constexpr'" "" { target c++20 } }
#undef __cpp_impl_coroutine // { dg-warning "undefining '__cpp_impl_coroutine'" "" { target c++20 } }
#undef __cpp_impl_destroying_delete // { dg-warning "undefining '__cpp_impl_destroying_delete'" "" { target c++20 } }
#undef __cpp_impl_three_way_comparison // { dg-warning "undefining '__cpp_impl_three_way_comparison'" "" { target c++20 } }
#undef __cpp_impl_reflection
#undef __cpp_implicit_move // { dg-warning "undefining '__cpp_implicit_move'" "" { target c++23 } }
#undef __cpp_inheriting_constructors // { dg-warning "undefining '__cpp_inheriting_constructors'" "" { target c++20 } }
#undef __cpp_init_captures // { dg-warning "undefining '__cpp_init_captures'" "" { target c++20 } }
#undef __cpp_initializer_lists // { dg-warning "undefining '__cpp_initializer_lists'" "" { target c++20 } }
#undef __cpp_inline_variables // { dg-warning "undefining '__cpp_inline_variables'" "" { target c++20 } }
#undef __cpp_lambdas // { dg-warning "undefining '__cpp_lambdas'" "" { target c++20 } }
#undef __cpp_modules // { dg-warning "undefining '__cpp_modules'" "" { target c++20 } }
#undef __cpp_multidimensional_subscript // { dg-warning "undefining '__cpp_multidimensional_subscript'" "" { target c++23 } }
#undef __cpp_named_character_escapes // { dg-warning "undefining '__cpp_named_character_escapes'" "" { target c++23 } }
#undef __cpp_namespace_attributes // { dg-warning "undefining '__cpp_namespace_attributes'" "" { target c++20 } }
#undef __cpp_noexcept_function_type // { dg-warning "undefining '__cpp_noexcept_function_type'" "" { target c++20 } }
#undef __cpp_nontype_template_args // { dg-warning "undefining '__cpp_nontype_template_args'" "" { target c++20 } }
#undef __cpp_nontype_template_parameter_auto // { dg-warning "undefining '__cpp_nontype_template_parameter_auto'" "" { target c++20 } }
#undef __cpp_nsdmi // { dg-warning "undefining '__cpp_nsdmi'" "" { target c++20 } }
#undef __cpp_pack_indexing // { dg-warning "undefining '__cpp_pack_indexing'" "" { target c++26 } }
#undef __cpp_placeholder_variables // { dg-warning "undefining '__cpp_placeholder_variables'" "" { target c++26 } }
#undef __cpp_pp_embed // { dg-warning "undefining '__cpp_pp_embed'" "" { target c++26 } }
#undef __cpp_range_based_for // { dg-warning "undefining '__cpp_range_based_for'" "" { target c++20 } }
#undef __cpp_raw_strings // { dg-warning "undefining '__cpp_raw_strings'" "" { target c++20 } }
#undef __cpp_ref_qualifiers // { dg-warning "undefining '__cpp_ref_qualifiers'" "" { target c++20 } }
#undef __cpp_return_type_deduction // { dg-warning "undefining '__cpp_return_type_deduction'" "" { target c++20 } }
#undef __cpp_rvalue_references // { dg-warning "undefining '__cpp_rvalue_references'" "" { target c++20 } }
#undef __cpp_size_t_suffix // { dg-warning "undefining '__cpp_size_t_suffix'" "" { target c++23 } }
#undef __cpp_sized_deallocation // { dg-warning "undefining '__cpp_sized_deallocation'" "" { target c++20 } }
#undef __cpp_static_assert // { dg-warning "undefining '__cpp_static_assert'" "" { target c++20 } }
#undef __cpp_static_call_operator // { dg-warning "undefining '__cpp_static_call_operator'" "" { target c++23 } }
#undef __cpp_structured_bindings // { dg-warning "undefining '__cpp_structured_bindings'" "" { target c++20 } }
#undef __cpp_template_parameters
#undef __cpp_template_template_args // { dg-warning "undefining '__cpp_template_template_args'" "" { target c++20 } }
#undef __cpp_threadsafe_static_init // { dg-warning "undefining '__cpp_threadsafe_static_init'" "" { target c++20 } }
#undef __cpp_trivial_relocatability // { dg-warning "undefining '__cpp_trivial_relocatability'" "" { target c++26 } }
#undef __cpp_trivial_union
#undef __cpp_unicode_characters // { dg-warning "undefining '__cpp_unicode_characters'" "" { target c++20 } }
#undef __cpp_unicode_literals // { dg-warning "undefining '__cpp_unicode_literals'" "" { target c++20 } }
#undef __cpp_user_defined_literals // { dg-warning "undefining '__cpp_user_defined_literals'" "" { target c++20 } }
#undef __cpp_using_enum // { dg-warning "undefining '__cpp_using_enum'" "" { target c++20 } }
#undef __cpp_variable_templates // { dg-warning "undefining '__cpp_variable_templates'" "" { target c++20 } }
#undef __cpp_variadic_friend // { dg-warning "undefining '__cpp_variadic_friend'" "" { target c++26 } }
#undef __cpp_variadic_templates // { dg-warning "undefining '__cpp_variadic_templates'" "" { target c++20 } }
#undef __cpp_variadic_using // { dg-warning "undefining '__cpp_variadic_using'" "" { target c++20 } }

View File

@ -0,0 +1,106 @@
// DR 2581 - Undefined behavior for predefined macros
// { dg-do preprocess }
// { dg-additional-options "-fcontracts" { target c++26 } }
// { dg-additional-options "-fmodules -fcoroutines" { target c++20 } }
#define defined defined // { dg-error "'defined' cannot be used as a macro name" }
#define __cplusplus 202400L // { dg-error "'__cplusplus' redefined" }
#define __DATE__ // { dg-error "'__DATE__' redefined" }
#define __FILE__ // { dg-error "'__FILE__' redefined" }
#define __LINE__ // { dg-error "'__LINE__' redefined" }
#define __STDC_EMBED_NOT_FOUND__ 0 // { dg-error "'__STDC_EMBED_NOT_FOUND__' redefined" }
#define __STDC_EMBED_FOUND__ 1 // { dg-error "'__STDC_EMBED_FOUND__' redefined" }
#define __STDC_EMBED_EMPTY__ 2 // { dg-error "'__STDC_EMBED_EMPTY__' redefined" }
#define __STDC_HOSTED__ 1 // { dg-error "'__STDC_HOSTED__' redefined" }
#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 1 // { dg-error "'__STDCPP_DEFAULT_NEW_ALIGNMENT__' redefined" "" { target c++17 } }
#define __STDCPP_FLOAT16_T__ 1 // { dg-message "'__STDCPP_FLOAT16_T__' (?:re)?defined" "" { target c++23 } }
#define __STDCPP_FLOAT32_T__ 1 // { dg-message "'__STDCPP_FLOAT32_T__' (?:re)?defined" "" { target c++23 } }
#define __STDCPP_FLOAT64_T__ 1 // { dg-message "'__STDCPP_FLOAT64_T__' (?:re)?defined" "" { target c++23 } }
#define __STDCPP_FLOAT128_T__ 1 // { dg-message "'__STDCPP_FLOAT128_T__' (?:re)?defined" "" { target c++23 } }
#define __STDCPP_BFLOAT16_T__ 1 // { dg-message "'__STDCPP_BFLOAT16_T__' (?:re)?defined" "" { target c++23 } }
#define __TIME__ // { dg-error "'__TIME__' redefined" }
#define __STDC__ // { dg-error "'__STDC__' redefined" }
#define __STDC_MB_MIGHT_NEQ_WC__ // { dg-warning "'__STDC_MB_MIGHT_NEQ_WC__' defined" "" { target c++11 } }
#define __STDC_VERSION__ // { dg-warning "'__STDC_VERSION__' defined" "" { target c++11 } }
#define __STDC_ISO_10646__ // { dg-error "'__STDC_ISO_10646__' redefined" }
#define __STDCPP_THREADS__ // { dg-message "'__STDCPP_THREADS__' (?:re)?defined" "" { target c++11 } }
#define __STDCPP_STRICT_POINTER_SAFETY__ // { dg-warning "'__STDCPP_STRICT_POINTER_SAFETY__' defined" "" { target { c++11 && c++20_down } } }
#define __cpp_aggregate_bases 201603L // { dg-error "'__cpp_aggregate_bases' redefined" "" { target c++20 } }
#define __cpp_aggregate_nsdmi 201304L // { dg-error "'__cpp_aggregate_nsdmi' redefined" "" { target c++20 } }
#define __cpp_aggregate_paren_init 201902L // { dg-error "'__cpp_aggregate_paren_init' redefined" "" { target c++20 } }
#define __cpp_alias_templates 200704L // { dg-error "'__cpp_alias_templates' redefined" "" { target c++20 } }
#define __cpp_aligned_new 201606L // { dg-error "'__cpp_aligned_new' redefined" "" { target c++20 } }
#define __cpp_attributes 200809L // { dg-error "'__cpp_attributes' redefined" "" { target c++20 } }
#define __cpp_auto_cast 202110L // { dg-error "'__cpp_auto_cast' redefined" "" { target c++23 } }
#define __cpp_binary_literals 201304L // { dg-error "'__cpp_binary_literals' redefined" "" { target c++20 } }
#define __cpp_capture_star_this 201603L // { dg-error "'__cpp_capture_star_this' redefined" "" { target c++20 } }
#define __cpp_char8_t 202207L // { dg-error "'__cpp_char8_t' redefined" "" { target c++20 } }
#define __cpp_concepts 202002L // { dg-error "'__cpp_concepts' redefined" "" { target c++20 } }
#define __cpp_conditional_explicit 201806L // { dg-error "'__cpp_conditional_explicit' redefined" "" { target c++20 } }
#define __cpp_constexpr 202406L // { dg-error "'__cpp_constexpr' redefined" "" { target c++11 } }
#define __cpp_constexpr_dynamic_alloc 201907L // { dg-error "'__cpp_constexpr_dynamic_alloc' redefined" "" { target c++20 } }
#define __cpp_constexpr_exceptions 202411L // { dg-error "'__cpp_constexpr_exceptions' redefined" "" { target c++26 } }
#define __cpp_constexpr_in_decltype 201711L // { dg-error "'__cpp_constexpr_in_decltype' redefined" "" { target c++20 } }
#define __cpp_constexpr_virtual_inheritance 202506L // { dg-error "'__cpp_constexpr_virtual_inheritance' redefined" "" { target c++26 } }
#define __cpp_consteval 202211L // { dg-error "'__cpp_consteval' redefined" "" { target c++20 } }
#define __cpp_constinit 201907L // { dg-error "'__cpp_constinit' redefined" "" { target c++20 } }
#define __cpp_contracts 202502L // { dg-error "'__cpp_contracts' redefined" "" { target c++26 } }
#define __cpp_decltype 200707L // { dg-error "'__cpp_decltype' redefined" "" { target c++20 } }
#define __cpp_decltype_auto 201304L // { dg-error "'__cpp_decltype_auto' redefined" "" { target c++20 } }
#define __cpp_deduction_guides 201907L // { dg-error "'__cpp_deduction_guides' redefined" "" { target c++17 } }
#define __cpp_delegating_constructors 200604L // { dg-error "'__cpp_delegating_constructors' redefined" "" { target c++20 } }
#define __cpp_deleted_function 202403L // { dg-error "'__cpp_deleted_function' redefined" "" { target c++26 } }
#define __cpp_designated_initializers 201707L // { dg-error "'__cpp_designated_initializers' redefined" "" { target c++20 } }
#define __cpp_enumerator_attributes 201411L // { dg-error "'__cpp_enumerator_attributes' redefined" "" { target c++20 } }
#define __cpp_expansion_statements 202506L // { dg-error "'__cpp_expansion_statements' redefined" "" { target c++26 } }
#define __cpp_explicit_this_parameter 202110L // { dg-error "'__cpp_explicit_this_parameter' redefined" "" { target c++23 } }
#define __cpp_fold_expressions 201603L // { dg-error "'__cpp_fold_expressions' redefined" "" { target c++20 } }
#define __cpp_generic_lambdas 201707L // { dg-error "'__cpp_generic_lambdas' redefined" "" { target c++14 } }
#define __cpp_guaranteed_copy_elision 201606L // { dg-error "'__cpp_guaranteed_copy_elision' redefined" "" { target c++20 } }
#define __cpp_hex_float 201603L // { dg-error "'__cpp_hex_float' redefined" "" { target c++20 } }
#define __cpp_if_consteval 202106L // { dg-error "'__cpp_if_consteval' redefined" "" { target c++23 } }
#define __cpp_if_constexpr 201606L // { dg-error "'__cpp_if_constexpr' redefined" "" { target c++20 } }
#define __cpp_impl_coroutine 201902L // { dg-error "'__cpp_impl_coroutine' redefined" "" { target c++20 } }
#define __cpp_impl_destroying_delete 201806L // { dg-error "'__cpp_impl_destroying_delete' redefined" "" { target c++20 } }
#define __cpp_impl_three_way_comparison 201907L // { dg-error "'__cpp_impl_three_way_comparison' redefined" "" { target c++20 } }
#define __cpp_impl_reflection 202506L
#define __cpp_implicit_move 202207L // { dg-error "'__cpp_implicit_move' redefined" "" { target c++23 } }
#define __cpp_inheriting_constructors 201511L // { dg-error "'__cpp_inheriting_constructors' redefined" "" { target c++20 } }
#define __cpp_init_captures 201803L // { dg-error "'__cpp_init_captures' redefined" "" { target c++14 } }
#define __cpp_initializer_lists 200806L // { dg-error "'__cpp_initializer_lists' redefined" "" { target c++20 } }
#define __cpp_inline_variables 201606L // { dg-error "'__cpp_inline_variables' redefined" "" { target c++20 } }
#define __cpp_lambdas 200907L // { dg-error "'__cpp_lambdas' redefined" "" { target c++20 } }
#define __cpp_modules 201907L // { dg-error "'__cpp_modules' redefined" "" { target c++20 } }
#define __cpp_multidimensional_subscript 202211L // { dg-error "'__cpp_multidimensional_subscript' redefined" "" { target c++23 } }
#define __cpp_named_character_escapes 202207L // { dg-error "'__cpp_named_character_escapes' redefined" "" { target c++23 } }
#define __cpp_namespace_attributes 201411L // { dg-error "'__cpp_namespace_attributes' redefined" "" { target c++20 } }
#define __cpp_noexcept_function_type 201510L // { dg-error "'__cpp_noexcept_function_type' redefined" "" { target c++20 } }
#define __cpp_nontype_template_args 201911L // { dg-error "'__cpp_nontype_template_args' redefined" "" { target c++17 } }
#define __cpp_nontype_template_parameter_auto 201606L // { dg-error "'__cpp_nontype_template_parameter_auto' redefined" "" { target c++20 } }
#define __cpp_nsdmi 200809L // { dg-error "'__cpp_nsdmi' redefined" "" { target c++20 } }
#define __cpp_pack_indexing 202311L // { dg-error "'__cpp_pack_indexing' redefined" "" { target c++26 } }
#define __cpp_placeholder_variables 202306L // { dg-error "'__cpp_placeholder_variables' redefined" "" { target c++26 } }
#define __cpp_pp_embed 202502L // { dg-error "'__cpp_pp_embed' redefined" "" { target c++26 } }
#define __cpp_range_based_for 202211L // { dg-error "'__cpp_range_based_for' redefined" "" { target c++11 } }
#define __cpp_raw_strings 200710L // { dg-error "'__cpp_raw_strings' redefined" "" { target c++20 } }
#define __cpp_ref_qualifiers 200710L // { dg-error "'__cpp_ref_qualifiers' redefined" "" { target c++20 } }
#define __cpp_return_type_deduction 201304L // { dg-error "'__cpp_return_type_deduction' redefined" "" { target c++20 } }
#define __cpp_rvalue_references 200610L // { dg-error "'__cpp_rvalue_references' redefined" "" { target c++20 } }
#define __cpp_size_t_suffix 202011L // { dg-error "'__cpp_size_t_suffix' redefined" "" { target c++23 } }
#define __cpp_sized_deallocation 201309L // { dg-error "'__cpp_sized_deallocation' redefined" "" { target c++20 } }
#define __cpp_static_assert 202306L // { dg-error "'__cpp_static_assert' redefined" "" { target c++11 } }
#define __cpp_static_call_operator 202207L // { dg-error "'__cpp_static_call_operator' redefined" "" { target c++23 } }
#define __cpp_structured_bindings 202411L // { dg-error "'__cpp_structured_bindings' redefined" "" { target c++17 } }
#define __cpp_template_parameters 202502L
#define __cpp_template_template_args 201611L // { dg-error "'__cpp_template_template_args' redefined" "" { target c++20 } }
#define __cpp_threadsafe_static_init 200806L // { dg-error "'__cpp_threadsafe_static_init' redefined" "" { target c++20 } }
#define __cpp_trivial_relocatability 202502L // { dg-error "'__cpp_trivial_relocatability' redefined" "" { target c++26 } }
#define __cpp_trivial_union 202502L
#define __cpp_unicode_characters 200704L // { dg-error "'__cpp_unicode_characters' redefined" "" { target c++17 } }
#define __cpp_unicode_literals 200710L // { dg-error "'__cpp_unicode_literals' redefined" "" { target c++20 } }
#define __cpp_user_defined_literals 200809L // { dg-error "'__cpp_user_defined_literals' redefined" "" { target c++20 } }
#define __cpp_using_enum 201907L // { dg-error "'__cpp_using_enum' redefined" "" { target c++20 } }
#define __cpp_variable_templates 201304L // { dg-error "'__cpp_variable_templates' redefined" "" { target c++20 } }
#define __cpp_variadic_friend 202403L // { dg-error "'__cpp_variadic_friend' redefined" "" { target c++26 } }
#define __cpp_variadic_templates 200704L // { dg-error "'__cpp_variadic_templates' redefined" "" { target c++20 } }
#define __cpp_variadic_using 201611L // { dg-error "'__cpp_variadic_using' redefined" "" { target c++20 } }

View File

@ -736,7 +736,9 @@ do_undef (cpp_reader *pfile)
/* Handle -Wkeyword-macro registered identifiers. */
bool diagnosed = false;
if (CPP_OPTION (pfile, cpp_warn_keyword_macro) && cpp_keyword_p (node))
if (CPP_OPTION (pfile, cpp_warn_keyword_macro)
&& !CPP_OPTION (pfile, suppress_builtin_macro_warnings)
&& cpp_keyword_p (node))
{
if (CPP_OPTION (pfile, cpp_pedantic)
&& CPP_OPTION (pfile, cplusplus)
@ -752,7 +754,8 @@ do_undef (cpp_reader *pfile)
identifier is not currently defined as a macro name. */
if (cpp_macro_p (node))
{
if (node->flags & NODE_WARN)
if ((node->flags & NODE_WARN)
&& !CPP_OPTION (pfile, suppress_builtin_macro_warnings))
{
if (!diagnosed)
cpp_error (pfile, CPP_DL_WARNING,
@ -769,6 +772,11 @@ do_undef (cpp_reader *pfile)
_cpp_free_definition (node);
}
else if ((node->flags & NODE_WARN)
&& !CPP_OPTION (pfile, suppress_builtin_macro_warnings)
&& !diagnosed
&& !cpp_keyword_p (node))
cpp_error (pfile, CPP_DL_WARNING, "undefining %qs", NODE_NAME (node));
}
check_eol (pfile, false);
@ -3087,7 +3095,9 @@ cpp_define (cpp_reader *pfile, const char *str)
}
buf[count] = '\n';
CPP_OPTION (pfile, suppress_builtin_macro_warnings) = 1;
run_directive (pfile, T_DEFINE, buf, count);
CPP_OPTION (pfile, suppress_builtin_macro_warnings) = 0;
}
/* Like cpp_define, but does not warn about unused macro. */
@ -3141,7 +3151,9 @@ _cpp_define_builtin (cpp_reader *pfile, const char *str)
char *buf = (char *) alloca (len + 1);
memcpy (buf, str, len);
buf[len] = '\n';
CPP_OPTION (pfile, suppress_builtin_macro_warnings) = 1;
run_directive (pfile, T_DEFINE, buf, len);
CPP_OPTION (pfile, suppress_builtin_macro_warnings) = 0;
}
/* Process MACRO as if it appeared as the body of an #undef. */
@ -3152,7 +3164,9 @@ cpp_undef (cpp_reader *pfile, const char *macro)
char *buf = (char *) alloca (len + 1);
memcpy (buf, macro, len);
buf[len] = '\n';
CPP_OPTION (pfile, suppress_builtin_macro_warnings) = 1;
run_directive (pfile, T_UNDEF, buf, len);
CPP_OPTION (pfile, suppress_builtin_macro_warnings) = 0;
}
/* Replace a previous definition DEF of the macro STR. If DEF is NULL,

View File

@ -435,6 +435,10 @@ struct cpp_options
Presumably the usage is protected by the appropriate #ifdef. */
unsigned char warn_variadic_macros;
/* Non-zero means suppress diagnostics for NODE_WARN #define or #undef.
Used for cpp_define/cpp_undef. */
unsigned char suppress_builtin_macro_warnings;
/* Nonzero means warn about builtin macros that are redefined or
explicitly undefined. */
unsigned char warn_builtin_macro_redefined;
@ -1526,6 +1530,21 @@ extern cpp_comment_table *cpp_get_comments (cpp_reader *);
extern cpp_hashnode *cpp_lookup (cpp_reader *, const unsigned char *,
unsigned int);
/* Set NODE_WARN flag for NAME, such that there will be diagnostics
for #define or #undef of NAME. */
inline void
cpp_warn (cpp_reader *pfile, const char *name, unsigned int len)
{
cpp_lookup (pfile, (const unsigned char *) name, len)->flags |= NODE_WARN;
}
inline void
cpp_warn (cpp_reader *pfile, const char *name)
{
cpp_warn (pfile, name, strlen (name));
}
typedef int (*cpp_cb) (cpp_reader *, cpp_hashnode *, void *);
extern void cpp_forall_identifiers (cpp_reader *, cpp_cb, void *);

View File

@ -246,6 +246,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
CPP_OPTION (pfile, dollars_in_ident) = 1;
CPP_OPTION (pfile, warn_dollars) = 1;
CPP_OPTION (pfile, warn_variadic_macros) = 1;
CPP_OPTION (pfile, suppress_builtin_macro_warnings) = 0;
CPP_OPTION (pfile, warn_builtin_macro_redefined) = 1;
CPP_OPTION (pfile, cpp_warn_implicit_fallthrough) = 0;
CPP_OPTION (pfile, warn_header_guard) = 0;
@ -593,6 +594,8 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
&& (! CPP_OPTION (pfile, stdc_0_in_system_headers)
|| CPP_OPTION (pfile, std)))
_cpp_define_builtin (pfile, "__STDC__ 1");
else if (CPP_OPTION (pfile, cplusplus))
cpp_warn (pfile, "__STDC__");
if (CPP_OPTION (pfile, cplusplus))
{
@ -618,6 +621,14 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
_cpp_define_builtin (pfile, "__cplusplus 201103L");
else
_cpp_define_builtin (pfile, "__cplusplus 199711L");
cpp_warn (pfile, "__cplusplus");
if (CPP_OPTION (pfile, lang) >= CLK_GNUCXX11)
{
cpp_warn (pfile, "__STDC_VERSION__");
cpp_warn (pfile, "__STDC_MB_MIGHT_NEQ_WC__");
if (CPP_OPTION (pfile, lang) < CLK_GNUCXX23)
cpp_warn (pfile, "__STDCPP_STRICT_POINTER_SAFETY__");
}
}
else if (CPP_OPTION (pfile, lang) == CLK_ASM)
_cpp_define_builtin (pfile, "__ASSEMBLER__ 1");

View File

@ -3412,8 +3412,11 @@ warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
/* Some redefinitions need to be warned about regardless. */
if (node->flags & NODE_WARN)
{
/* Ignore NODE_WARN on -Wkeyword-macro registered identifiers though. */
if (!CPP_OPTION (pfile, cpp_warn_keyword_macro) || !cpp_keyword_p (node))
/* Ignore NODE_WARN on -Wkeyword-macro registered identifiers though
or during cpp_define. */
if (!CPP_OPTION (pfile, suppress_builtin_macro_warnings)
&& (!CPP_OPTION (pfile, cpp_warn_keyword_macro)
|| !cpp_keyword_p (node)))
return true;
}
@ -3954,7 +3957,9 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node,
macro->line = name_loc;
/* Handle -Wkeyword-macro registered identifiers. */
if (CPP_OPTION (pfile, cpp_warn_keyword_macro) && cpp_keyword_p (node))
if (CPP_OPTION (pfile, cpp_warn_keyword_macro)
&& !CPP_OPTION (pfile, suppress_builtin_macro_warnings)
&& cpp_keyword_p (node))
{
if (macro->fun_like
&& CPP_OPTION (pfile, cplusplus)
@ -3994,6 +3999,11 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node,
}
_cpp_free_definition (node);
}
else if ((node->flags & NODE_WARN)
&& !CPP_OPTION (pfile, suppress_builtin_macro_warnings)
&& !cpp_keyword_p (node))
cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0,
"%qs defined", NODE_NAME (node));
/* Enter definition in hash table. */
node->type = NT_USER_MACRO;