From patchwork Wed Aug 10 13:53:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 657696 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3s8Xgr3Wxzz9sBr for ; Wed, 10 Aug 2016 23:54:15 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=NJqh3oJ6; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=l/haTvKqQsMV RIG+Ovgvy9ycHceSGUo/pvzqWs7MSGcuynMMkG1HU6adfsoo7UCYDvu79iEDDzq9 b+Wh094UsFVP55IlX37TvlQEr5pKG1ynILUWVzArNFZvgT9SOYPnGF+Jscaaf119 /aIjIPn43z0SJ7yR301MTAidVLbUFLo= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=kH7/tGZnB71Ufm1KBn nT7HWceOA=; b=NJqh3oJ64Bb9TlWaOVhf9ARlGuceccjYsslQymyDL/wN/5Jha9 dNnmrIIMqVzYbddrt8f1COJAVZ/TEr7fnyLIg+sXpMa/OGkjdQvuQv95jO/b5MU+ vLOI0+23Gq2jesvcPGoZvZJFse0YwGSOGkLF7fJVNWuG+a8nuDuWV5KlU= Received: (qmail 74314 invoked by alias); 10 Aug 2016 13:54:04 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 74304 invoked by uid 89); 10 Aug 2016 13:54:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.9 required=5.0 tests=BAYES_50, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 spammy=booth, dec, TYPE, Dec X-HELO: mail-wm0-f43.google.com Received: from mail-wm0-f43.google.com (HELO mail-wm0-f43.google.com) (74.125.82.43) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 10 Aug 2016 13:53:53 +0000 Received: by mail-wm0-f43.google.com with SMTP id f65so92229018wmi.0 for ; Wed, 10 Aug 2016 06:53:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=wOp6s0/LldTjBkajBKfZnp6qHO4KQYFOONa24x+a/wY=; b=Jv9tdtrMWuwS/BR2ugZVFUbQ5jIvu9F/t959o4gB0n6/Ed+MtgOQxPF680q/eobTlm ab2yliY6hJ3XP6oQW8EOMly8XkI8qErzyriIffJqi3Jqst2eDiq1DxKiJBQxai4f8ECP lu/tvd06SzPDCJDA+e8y+oHgHH7rB9rmDLg01fgsfa1GoCc7GlJsqcBHzqDIMxU3Bs/O Eo9LCUMZLuOL05cYEb7Tty+zgs0DL8mOSHUOdBwyVpte7o34+yoQ2gasWvvZyyCHltfe S47w5Yt8mKTnpVaNpO5YPkcNr3DccRk2bMsQSLyljAA+2z6byndM4yVyiebeVHiBJUy8 UEew== X-Gm-Message-State: AEkoouvVy5p4Axs9sjN4p1pzv05vP7dNvNxn9AhIWxMcKdLwOck2E3jQjNaLfYWhEaZGaw== X-Received: by 10.194.140.35 with SMTP id rd3mr4077648wjb.88.1470837228039; Wed, 10 Aug 2016 06:53:48 -0700 (PDT) Received: from 640k.lan (94-39-152-88.adsl-ull.clienti.tiscali.it. [94.39.152.88]) by smtp.gmail.com with ESMTPSA id k3sm43178268wjf.7.2016.08.10.06.53.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Aug 2016 06:53:46 -0700 (PDT) From: Paolo Bonzini To: gcc-patches@gcc.gnu.org Cc: Joseph Myers , =?UTF-8?q?Manuel=20L=C3=B3pez-Ib=C3=A1=C3=B1ez?= , Paolo Bonzini Subject: [PATCH v3] cpp/c: Add -Wexpansion-to-defined Date: Wed, 10 Aug 2016 15:53:44 +0200 Message-Id: <1470837224-14510-1-git-send-email-pbonzini@redhat.com> From: Paolo Bonzini clang recently added a new warning -Wexpansion-to-defined, which warns when `defined' is used outside a #if expression (including the case of a macro that is then used in a #if expression). While I disagree with their inclusion of the warning to -Wall, I think it is a good addition overall. First, it is a logical extension of the existing warning for breaking defined across a macro and its caller. Second, it is good to make these warnings for `defined' available with a command-line option other than -pedantic. This patch adds -Wexpansion-to-defined, and enables it automatically for both -pedantic (as before) and -Wextra. It also changes the warning from a warning to a pedwarn; this is mostly for documentation sake since the EnabledBy machinery would turn -pedantic-errors into -Werror=expansion-to-defined anyway. Bootstrapped and regression tested x86_64-pc-linux-gnu, ok? Paolo libcpp: 2016-08-09 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. gcc: 2016-08-09 Paolo Bonzini * system.h (HAVE_DESIGNATED_INITIALIZERS, HAVE_DESIGNATED_UNION_INITIALIZERS): Do not use "defined" in macros. gcc/c-family: 2016-08-09 Paolo Bonzini * c.opt (Wexpansion-to-defined): New. gcc/doc: 2016-08-09 Paolo Bonzini * cpp.texi (Defined): Mention -Wexpansion-to-defined. * cppopts.texi (Invocation): Document -Wexpansion-to-defined. * invoke.texi (Warning Options): Document -Wexpansion-to-defined. gcc/testsuite: 2016-08-09 Paolo Bonzini * gcc.dg/cpp/defined.c: Mark newly introduced warnings and adjust for warning->pedwarn change. * 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. Index: gcc/c-family/c.opt =================================================================== --- gcc/c-family/c.opt (revision 239276) +++ gcc/c-family/c.opt (working copy) @@ -506,6 +506,10 @@ 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. Index: gcc/doc/cpp.texi =================================================================== --- gcc/doc/cpp.texi (revision 239276) +++ gcc/doc/cpp.texi (working copy) @@ -3342,7 +3342,9 @@ 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 Index: gcc/doc/cppopts.texi =================================================================== --- gcc/doc/cppopts.texi (revision 239276) +++ gcc/doc/cppopts.texi (working copy) @@ -120,6 +120,12 @@ @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 Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 239276) +++ gcc/doc/invoke.texi (working copy) @@ -4914,6 +4914,11 @@ 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 Index: gcc/system.h =================================================================== --- gcc/system.h (revision 239276) +++ gcc/system.h (working copy) @@ -577,16 +577,22 @@ /* 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 # include Index: gcc/testsuite/gcc.dg/cpp/defined-Wno-expansion-to-defined.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/defined-Wno-expansion-to-defined.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/defined-Wno-expansion-to-defined.c (working copy) @@ -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 + Index: gcc/testsuite/gcc.dg/cpp/defined-Wexpansion-to-defined.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/defined-Wexpansion-to-defined.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/defined-Wexpansion-to-defined.c (working copy) @@ -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 + Index: gcc/testsuite/gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/defined-Wextra-Wno-expansion-to-defined.c (working copy) @@ -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 + Index: gcc/testsuite/gcc.dg/cpp/defined-Wextra.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/defined-Wextra.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/defined-Wextra.c (working copy) @@ -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 + Index: gcc/testsuite/gcc.dg/cpp/defined.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/defined.c (revision 239276) +++ gcc/testsuite/gcc.dg/cpp/defined.c (working copy) @@ -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 Index: libcpp/expr.c =================================================================== --- libcpp/expr.c (revision 239276) +++ libcpp/expr.c (working copy) @@ -947,9 +947,11 @@ 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)) Index: libcpp/include/cpplib.h =================================================================== --- libcpp/include/cpplib.h (revision 239276) +++ libcpp/include/cpplib.h (working copy) @@ -410,6 +410,10 @@ /* 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; @@ -1025,7 +1029,8 @@ 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. */ Index: libcpp/system.h =================================================================== --- libcpp/system.h (revision 239276) +++ libcpp/system.h (working copy) @@ -375,10 +375,13 @@ ??? 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 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)