From fb2675cb4683a430fb63af44713cd9d2fcd77b97 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 23 Nov 2016 10:06:07 +0000 Subject: [PATCH] system.h (HAVE_DESIGNATED_INITIALIZERS, [...]): Do not use "defined" in macros. gcc: 2016-11-23 Paolo Bonzini * system.h (HAVE_DESIGNATED_INITIALIZERS, HAVE_DESIGNATED_UNION_INITIALIZERS): Do not use "defined" in macros. * doc/cpp.texi (Defined): Mention -Wexpansion-to-defined. * doc/cppopts.texi (Invocation): Document -Wexpansion-to-defined. * doc/invoke.texi (Warning Options): Document -Wexpansion-to-defined. gcc/c-family: 2016-11-23 Paolo Bonzini * c.opt (Wexpansion-to-defined): New. gcc/testsuite: 2016-11-23 Paolo Bonzini * gcc.dg/cpp/defined.c: Mark newly introduced warnings and adjust for warning->pedwarn change. * gcc.dg/cpp/defined-syshdr.c, gcc.dg/cpp/defined-Wexpansion-to-defined.c, gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c, gcc.dg/cpp/defined-Wextra.c, gcc.dg/cpp/defined-Wno-expansion-to-defined.c: New testcases. libcpp: 2016-11-23 Paolo Bonzini * include/cpplib.h (struct cpp_options): Add new member warn_expansion_to_defined. (CPP_W_EXPANSION_TO_DEFINED): New enum member. * expr.c (parse_defined): Warn for all uses of "defined" in macros, and tie warning to CPP_W_EXPANSION_TO_DEFINED. Make it a pedwarning instead of a warning. * system.h (HAVE_DESIGNATED_INITIALIZERS): Do not use "defined" in macros. From-SVN: r242743 --- gcc/ChangeLog | 9 ++++++ gcc/c-family/ChangeLog | 4 +++ gcc/c-family/c.opt | 4 +++ gcc/doc/cpp.texi | 4 ++- gcc/doc/cppopts.texi | 6 ++++ gcc/doc/invoke.texi | 5 ++++ gcc/system.h | 14 ++++++--- gcc/testsuite/ChangeLog | 10 +++++++ .../cpp/defined-Wexpansion-to-defined.c | 30 +++++++++++++++++++ .../defined-Wextra-Wno-expansion-to-defined.c | 30 +++++++++++++++++++ gcc/testsuite/gcc.dg/cpp/defined-Wextra.c | 30 +++++++++++++++++++ .../cpp/defined-Wno-expansion-to-defined.c | 30 +++++++++++++++++++ gcc/testsuite/gcc.dg/cpp/defined-syshdr.c | 27 +++++++++++++++++ gcc/testsuite/gcc.dg/cpp/defined.c | 14 ++++----- libcpp/ChangeLog | 11 +++++++ libcpp/expr.c | 8 +++-- libcpp/include/cpplib.h | 7 ++++- libcpp/system.h | 7 +++-- 18 files changed, 232 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/defined-Wexpansion-to-defined.c create mode 100644 gcc/testsuite/gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c create mode 100644 gcc/testsuite/gcc.dg/cpp/defined-Wextra.c create mode 100644 gcc/testsuite/gcc.dg/cpp/defined-Wno-expansion-to-defined.c create mode 100644 gcc/testsuite/gcc.dg/cpp/defined-syshdr.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 92abe520728..b4e5acff78b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-11-23 Paolo Bonzini + + * system.h (HAVE_DESIGNATED_INITIALIZERS, + HAVE_DESIGNATED_UNION_INITIALIZERS): Do not use + "defined" in macros. + * doc/cpp.texi (Defined): Mention -Wexpansion-to-defined. + * doc/cppopts.texi (Invocation): Document -Wexpansion-to-defined. + * doc/invoke.texi (Warning Options): Document -Wexpansion-to-defined. + 2016-11-23 Georg-Johann Lay PR target/60300 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 3b412825c36..6b86dd2355f 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2016-11-23 Paolo Bonzini + + * c.opt (Wexpansion-to-defined): New. + 2016-11-23 Jakub Jelinek PR target/78451 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index c61fab8d2bc..2d47d54563a 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -573,6 +573,10 @@ Wdouble-promotion C ObjC C++ ObjC++ Var(warn_double_promotion) Warning Warn about implicit conversions from \"float\" to \"double\". +Wexpansion-to-defined +C ObjC C++ ObjC++ CPP(warn_expansion_to_defined) CppReason(CPP_W_EXPANSION_TO_DEFINED) Var(cpp_warn_expansion_to_defined) Init(0) Warning EnabledBy(Wextra || Wpedantic) +Warn if \"defined\" is used outside #if. + Wimplicit-function-declaration C ObjC Var(warn_implicit_function_declaration) Init(-1) Warning LangEnabledBy(C ObjC,Wimplicit) Warn about implicit function declarations. diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index ed91767bc96..49aa95369a0 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -3369,7 +3369,9 @@ If the @code{defined} operator appears as a result of a macro expansion, the C standard says the behavior is undefined. GNU cpp treats it as a genuine @code{defined} operator and evaluates it normally. It will warn wherever your code uses this feature if you use the command-line option -@option{-pedantic}, since other compilers may handle it differently. +@option{-Wpedantic}, since other compilers may handle it differently. The +warning is also enabled by @option{-Wextra}, and can also be enabled +individually with @option{-Wexpansion-to-defined}. @node Else @subsection Else diff --git a/gcc/doc/cppopts.texi b/gcc/doc/cppopts.texi index c5f919a5cf2..e349555909c 100644 --- a/gcc/doc/cppopts.texi +++ b/gcc/doc/cppopts.texi @@ -120,6 +120,12 @@ Warn whenever an identifier which is not a macro is encountered in an @samp{#if} directive, outside of @samp{defined}. Such identifiers are replaced with zero. +@item -Wexpansion-to-defined +@opindex Wexpansion-to-defined +Warn whenever @samp{defined} is encountered in the expansion of a macro +(including the case where the macro is expanded by an @samp{#if} directive). +Such usage is not portable. + @item -Wunused-macros @opindex Wunused-macros Warn about macros defined in the main file that are unused. A macro diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e02665318b1..32c7a083be0 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -5320,6 +5320,11 @@ Warn when a declaration is found after a statement in a block. This construct, known from C++, was introduced with ISO C99 and is by default allowed in GCC@. It is not supported by ISO C90. @xref{Mixed Declarations}. +@item -Wexpansion-to-defined +@opindex Wexpansion-to-defined +Warn whenever @samp{defined} is encountered in the expansion of a macro. +This warning is also enabled by @option{-Wpedantic} and @option{-Wextra}. + @item -Wundef @opindex Wundef @opindex Wno-undef diff --git a/gcc/system.h b/gcc/system.h index 8c6127c97a9..3e120176c2b 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -577,15 +577,21 @@ extern int vsnprintf (char *, size_t, const char *, va_list); /* 1 if we have C99 designated initializers. */ #if !defined(HAVE_DESIGNATED_INITIALIZERS) +#ifdef __cplusplus +#define HAVE_DESIGNATED_INITIALIZERS 0 +#else #define HAVE_DESIGNATED_INITIALIZERS \ - (((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) \ - && !defined(__cplusplus)) + (((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) +#endif #endif #if !defined(HAVE_DESIGNATED_UNION_INITIALIZERS) +#ifdef __cplusplus +#define HAVE_DESIGNATED_UNION_INITIALIZERS (GCC_VERSION >= 4007) +#else #define HAVE_DESIGNATED_UNION_INITIALIZERS \ - (((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) \ - && (!defined(__cplusplus) || (GCC_VERSION >= 4007))) + (((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) +#endif #endif #if HAVE_SYS_STAT_H diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 55644cdbac2..b9ccccc3d51 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2016-11-23 Paolo Bonzini + + * gcc.dg/cpp/defined.c: Mark newly introduced warnings and + adjust for warning->pedwarn change. + * gcc.dg/cpp/defined-syshdr.c, + gcc.dg/cpp/defined-Wexpansion-to-defined.c, + gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c, + gcc.dg/cpp/defined-Wextra.c, + gcc.dg/cpp/defined-Wno-expansion-to-defined.c: New testcases. + 2016-11-23 Senthil Kumar Selvaraj * gcc.dg/uninit-19.c: Add -finline-small-functions for avr. diff --git a/gcc/testsuite/gcc.dg/cpp/defined-Wexpansion-to-defined.c b/gcc/testsuite/gcc.dg/cpp/defined-Wexpansion-to-defined.c new file mode 100644 index 00000000000..9823c764df0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/defined-Wexpansion-to-defined.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. */ + +/* { dg-do preprocess } */ +/* { dg-options "-Wexpansion-to-defined" } */ + +/* Use of defined in different contexts. */ + +/* Source: Neil Booth, 29 Oct 2000, Zack Weinberg 11 Dec 2000. */ + +#define Z + +#define bad0 defined Z +#if !bad0 /* { dg-warning "may not be portable" } */ +#error Z is defined +#endif + +#define bad1 defined +#if !bad1 Z /* { dg-warning "may not be portable" } */ +#error Z is defined +#endif + +#if !bad1 (Z) /* { dg-warning "may not be portable" } */ +#error Z is defined +#endif + +#define bad2 defined (Z +#if !bad2) /* { dg-warning "may not be portable" } */ +#error Z is defined +#endif + diff --git a/gcc/testsuite/gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c b/gcc/testsuite/gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c new file mode 100644 index 00000000000..16a641db001 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. */ + +/* { dg-do preprocess } */ +/* { dg-options "-Wextra -Wno-expansion-to-defined" } */ + +/* Use of defined in different contexts. */ + +/* Source: Neil Booth, 29 Oct 2000, Zack Weinberg 11 Dec 2000. */ + +#define Z + +#define bad0 defined Z +#if !bad0 /* { dg-bogus "may not be portable" } */ +#error Z is defined +#endif + +#define bad1 defined +#if !bad1 Z /* { dg-bogus "may not be portable" } */ +#error Z is defined +#endif + +#if !bad1 (Z) /* { dg-bogus "may not be portable" } */ +#error Z is defined +#endif + +#define bad2 defined (Z +#if !bad2) /* { dg-bogus "may not be portable" } */ +#error Z is defined +#endif + diff --git a/gcc/testsuite/gcc.dg/cpp/defined-Wextra.c b/gcc/testsuite/gcc.dg/cpp/defined-Wextra.c new file mode 100644 index 00000000000..460a1cb43b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/defined-Wextra.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. */ + +/* { dg-do preprocess } */ +/* { dg-options "-Wextra" } */ + +/* Use of defined in different contexts. */ + +/* Source: Neil Booth, 29 Oct 2000, Zack Weinberg 11 Dec 2000. */ + +#define Z + +#define bad0 defined Z +#if !bad0 /* { dg-warning "may not be portable" } */ +#error Z is defined +#endif + +#define bad1 defined +#if !bad1 Z /* { dg-warning "may not be portable" } */ +#error Z is defined +#endif + +#if !bad1 (Z) /* { dg-warning "may not be portable" } */ +#error Z is defined +#endif + +#define bad2 defined (Z +#if !bad2) /* { dg-warning "may not be portable" } */ +#error Z is defined +#endif + diff --git a/gcc/testsuite/gcc.dg/cpp/defined-Wno-expansion-to-defined.c b/gcc/testsuite/gcc.dg/cpp/defined-Wno-expansion-to-defined.c new file mode 100644 index 00000000000..ddd015b75ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/defined-Wno-expansion-to-defined.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. */ + +/* { dg-do preprocess } */ +/* { dg-options "-ansi -pedantic-errors -Wno-expansion-to-defined" } */ + +/* Use of defined in different contexts. */ + +/* Source: Neil Booth, 29 Oct 2000, Zack Weinberg 11 Dec 2000. */ + +#define Z + +#define bad0 defined Z +#if !bad0 /* { dg-bogus "may not be portable" } */ +#error Z is defined +#endif + +#define bad1 defined +#if !bad1 Z /* { dg-bogus "may not be portable" } */ +#error Z is defined +#endif + +#if !bad1 (Z) /* { dg-bogus "may not be portable" } */ +#error Z is defined +#endif + +#define bad2 defined (Z +#if !bad2) /* { dg-bogus "may not be portable" } */ +#error Z is defined +#endif + diff --git a/gcc/testsuite/gcc.dg/cpp/defined-syshdr.c b/gcc/testsuite/gcc.dg/cpp/defined-syshdr.c new file mode 100644 index 00000000000..9c3846cddf1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/defined-syshdr.c @@ -0,0 +1,27 @@ +# 1 "defined-syshdr.c" 1 +/* { dg-do preprocess } */ +/* { dg-options "-Wexpansion-to-defined" } */ + +#define defined_outside_sys_hdr defined FOO + +# 36 "some-system-header.h" 1 3 + +#define defined_inside_sys_hdr defined FOO + +/* In a system header, it's acceptable. */ +#if defined_outside_sys_hdr /* { dg-bogus "may not be portable" } */ +#endif + +# 16 "defined-syshdr.c" 2 + +/* Back to _not_ in a system header */ + +#if defined_outside_sys_hdr /* { dg-message "may not be portable" } */ +#endif + +/* Currently we warn about this, but it is probably a good idea not to. */ + +#if defined_inside_sys_hdr /* { dg-bogus "may not be portable" "" { xfail *-*-* } } */ +#endif + +int x; diff --git a/gcc/testsuite/gcc.dg/cpp/defined.c b/gcc/testsuite/gcc.dg/cpp/defined.c index 9a60bdd5d10..44567e4b8e0 100644 --- a/gcc/testsuite/gcc.dg/cpp/defined.c +++ b/gcc/testsuite/gcc.dg/cpp/defined.c @@ -21,7 +21,7 @@ /* The behavior of "defined" when it comes from a macro expansion is now documented. */ -#if is_Z_defined +#if is_Z_defined /* { dg-error "may not be portable" } */ #error Macro expanding into defined operator test 1 #endif @@ -31,7 +31,7 @@ #error Z is defined #endif -#if !is_Z_defined +#if !is_Z_defined /* { dg-error "may not be portable" } */ #error Macro expanding into defined operator test 2 #endif @@ -53,7 +53,7 @@ /* The behavior of "defined" when it comes from a macro expansion is now documented. */ -#if is_Z_defined +#if is_Z_defined /* { dg-error "may not be portable" } */ #error Macro expanding into defined operator test 1 #endif @@ -63,23 +63,23 @@ #error Z is defined #endif -#if !is_Z_defined +#if !is_Z_defined /* { dg-error "may not be portable" } */ #error Macro expanding into defined operator test 2 #endif /* Use of defined in different contexts. */ #define bad1 defined -#if !bad1 Z /* { dg-warning "may not be portable" } */ +#if !bad1 Z /* { dg-error "may not be portable" } */ #error Z is defined #endif -#if !bad1 (Z) /* { dg-warning "may not be portable" } */ +#if !bad1 (Z) /* { dg-error "may not be portable" } */ #error Z is defined #endif #define bad2 defined (Z -#if !bad2) /* { dg-warning "may not be portable" } */ +#if !bad2) /* { dg-error "may not be portable" } */ #error Z is defined #endif diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 6b928078636..1a7e737cd95 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,14 @@ +2016-11-23 Paolo Bonzini + + * include/cpplib.h (struct cpp_options): Add new member + warn_expansion_to_defined. + (CPP_W_EXPANSION_TO_DEFINED): New enum member. + * expr.c (parse_defined): Warn for all uses of "defined" + in macros, and tie warning to CPP_W_EXPANSION_TO_DEFINED. + Make it a pedwarning instead of a warning. + * system.h (HAVE_DESIGNATED_INITIALIZERS): Do not use + "defined" in macros. + 2016-11-17 David Malcolm * charset.c (cpp_interpret_string_1): Skip locations from diff --git a/libcpp/expr.c b/libcpp/expr.c index 61bc1b21af1..a4cf7505958 100644 --- a/libcpp/expr.c +++ b/libcpp/expr.c @@ -1031,9 +1031,11 @@ parse_defined (cpp_reader *pfile) if (node) { - if (pfile->context != initial_context && CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_WARNING, - "this use of \"defined\" may not be portable"); + if ((pfile->context != initial_context + || initial_context != &pfile->base_context) + && CPP_OPTION (pfile, warn_expansion_to_defined)) + cpp_pedwarning (pfile, CPP_W_EXPANSION_TO_DEFINED, + "this use of \"defined\" may not be portable"); _cpp_mark_macro_used (node); if (!(node->flags & NODE_USED)) diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 0781c095156..56c2491d2ee 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -415,6 +415,10 @@ struct cpp_options /* Nonzero means warn if undefined identifiers are evaluated in an #if. */ unsigned char warn_undef; + /* Nonzero means warn if "defined" is encountered in a place other than + an #if. */ + unsigned char warn_expansion_to_defined; + /* Nonzero means warn of unused macros from the main file. */ unsigned char warn_unused_macros; @@ -1040,7 +1044,8 @@ enum { CPP_W_DATE_TIME, CPP_W_PEDANTIC, CPP_W_C90_C99_COMPAT, - CPP_W_CXX11_COMPAT + CPP_W_CXX11_COMPAT, + CPP_W_EXPANSION_TO_DEFINED }; /* Output a diagnostic of some kind. */ diff --git a/libcpp/system.h b/libcpp/system.h index e89131e900e..67b02bb4578 100644 --- a/libcpp/system.h +++ b/libcpp/system.h @@ -375,9 +375,12 @@ extern void abort (void); ??? C99 designated initializers are not supported by most C++ compilers, including G++. -- gdr, 2005-05-18 */ #if !defined(HAVE_DESIGNATED_INITIALIZERS) +#ifdef __cplusplus +#define HAVE_DESIGNATED_INITIALIZERS 0 +#else #define HAVE_DESIGNATED_INITIALIZERS \ - (!defined(__cplusplus) \ - && ((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L))) + ((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) +#endif #endif #ifndef offsetof -- 2.30.2