From patchwork Fri Apr 19 16:34:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 238050 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 91B112C01E4 for ; Sat, 20 Apr 2013 02:37:57 +1000 (EST) 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:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=a/3f61w0onid68gO C+YR/iJrCjZqj7/CXEZEokCLk+2EiuzaCsuMHfK+Naif3ZpUwsONcwlNL5dsF5qh NwTydm9xu7q2Qs8kJbsbw3VxurYiN1aFvMYtCaDfMIwsemK1bvtwo6+Nl5yc2WSu hHkzVwbZ28FO1Ab0sTs9RTUFb2k= 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:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=5i3oTJrNY0iihgkiE4Ojo4 /791c=; b=RnNiLAvYFHC9GP5olJyfXRa8QB6f7/U9FgBGm5KOAh9SBo4rKfFHcs HeESOgDnEOx+AGiHYb+btxmGYJ0xKnbEdXTmUQZfxroW5VDgUW2Vev5AzUaqkwp8 R9ChrLaW7CN3ysqu28ZhEyNY+fgaLNf8wlC1bsZ6vFkkL5+LXR8cc= Received: (qmail 22658 invoked by alias); 19 Apr 2013 16:37:50 -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 22648 invoked by uid 89); 19 Apr 2013 16:37:50 -0000 X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL, BAYES_00, TW_TM autolearn=ham version=3.3.1 Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 19 Apr 2013 16:37:49 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id AF17329019A for ; Fri, 19 Apr 2013 18:37:45 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zlk3PEtI9tga for ; Fri, 19 Apr 2013 18:37:45 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id 6F379290011 for ; Fri, 19 Apr 2013 18:37:45 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Introduce #pragma GCC diagnostic off Date: Fri, 19 Apr 2013 18:34:09 +0200 Message-ID: <9905781.8p9cTLN4od@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.19-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 X-Virus-Found: No Hi, this patch implements the new "#pragma GCC diagnostic off" for the C family of compilers as well as for the Ada compiler. In fact the subject is slightly misleading as the main goal of the patch is to wire the diagnostic circuitry of the Ada front-end to that of the middle-end, thus enabling the former to drive the latter; but the former has the equivalent of "diagnostic off" so it needs middle-end support for it, which in turn could be reused by the C family of compilers. The implementation in diagnostic.c is a bit kludgy in that it overloads the option index 0. But this index has been disabled since day #1 and I couldn't figure out a more elegant approach... Of course I'm ready to implement what the maintainers would suggest as alternative implementation. Tested on x86_64-suse-linux, OK for the mainline? 2013-04-19 Eric Botcazou * doc/extend.texi (Diagnostic Pragmas): Document diagnostic off. * diagnostic.c (diagnostic_classify_diagnostic): Accept zero index and document its semantics. (diagnostic_report_diagnostic): Adjust accordingly. c-family/ * c-pragma.c (ALL_KINDS_STRING): Define. (handle_pragma_diagnostic): Use it and accept diagnostic off. ada/ * gcc-interface/trans.c: Include diagnostic.h and opts.h. (Pragma_to_gnu) : New case. * gcc-interface/Make-lang.in (ada/trans.o): Adjust. 2013-04-19 Eric Botcazou * gcc.dg/pragma-diag-3.c: New test. Index: doc/extend.texi =================================================================== --- doc/extend.texi (revision 198047) +++ doc/extend.texi (working copy) @@ -14807,6 +14807,10 @@ track of the location of each pragma, an to the state as of that point in the source file. Thus, pragmas occurring after a line do not affect diagnostics caused by that line. +@item #pragma GCC diagnostic off +Causes GCC to ignore all the diagnostics. This is equivalent to specifying +@samp{ignored} for all the diagnostics with the previous form of the pragma. + @item #pragma GCC diagnostic push @itemx #pragma GCC diagnostic pop Index: c-family/c-pragma.c =================================================================== --- c-family/c-pragma.c (revision 198047) +++ c-family/c-pragma.c (working copy) @@ -684,19 +684,22 @@ handle_pragma_visibility (cpp_reader *du warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>"); } +#define ALL_KINDS_STRING "[error|warning|ignored|off|push|pop]" + static void handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) { - const char *kind_string, *option_string; + const char *kind_string; unsigned int option_index; enum cpp_ttype token; diagnostic_t kind; tree x; struct cl_option_handlers handlers; + bool no_option = false; token = pragma_lex (&x); if (token != CPP_NAME) - GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>"); + GCC_BAD ("missing "ALL_KINDS_STRING" after %<#pragma GCC diagnostic%>"); kind_string = IDENTIFIER_POINTER (x); if (strcmp (kind_string, "error") == 0) kind = DK_ERROR; @@ -704,6 +707,11 @@ handle_pragma_diagnostic(cpp_reader *ARG kind = DK_WARNING; else if (strcmp (kind_string, "ignored") == 0) kind = DK_IGNORED; + else if (strcmp (kind_string, "off") == 0) + { + kind = DK_IGNORED; + no_option = true; + } else if (strcmp (kind_string, "push") == 0) { diagnostic_push_diagnostics (global_dc, input_location); @@ -715,23 +723,27 @@ handle_pragma_diagnostic(cpp_reader *ARG return; } else - GCC_BAD ("expected [error|warning|ignored|push|pop] after %<#pragma GCC diagnostic%>"); + GCC_BAD ("expected "ALL_KINDS_STRING" after %<#pragma GCC diagnostic%>"); + + if (no_option) + option_index = 0; + else + { + token = pragma_lex (&x); + if (token != CPP_STRING) + GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind"); + const char *option_string = TREE_STRING_POINTER (x); + for (option_index = 0; option_index < cl_options_count; option_index++) + if (strcmp (cl_options[option_index].opt_text, option_string) == 0) + break; + if (option_index == cl_options_count) + GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind"); + } - token = pragma_lex (&x); - if (token != CPP_STRING) - GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind"); - option_string = TREE_STRING_POINTER (x); set_default_handlers (&handlers); - for (option_index = 0; option_index < cl_options_count; option_index++) - if (strcmp (cl_options[option_index].opt_text, option_string) == 0) - { - control_warning_option (option_index, (int) kind, kind != DK_IGNORED, - input_location, c_family_lang_mask, &handlers, - &global_options, &global_options_set, - global_dc); - return; - } - GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind"); + control_warning_option (option_index, (int) kind, kind != DK_IGNORED, + input_location, c_family_lang_mask, &handlers, + &global_options, &global_options_set, global_dc); } /* Parse #pragma GCC target (xxx) to set target specific options. */ Index: diagnostic.c =================================================================== --- diagnostic.c (revision 198047) +++ diagnostic.c (working copy) @@ -551,7 +551,8 @@ default_diagnostic_finalizer (diagnostic /* Interface to specify diagnostic kind overrides. Returns the previous setting, or DK_UNSPECIFIED if the parameters are out of - range. */ + range. If OPTION_INDEX is zero, the new setting is for all the + diagnostics. */ diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *context, int option_index, @@ -560,7 +561,7 @@ diagnostic_classify_diagnostic (diagnost { diagnostic_t old_kind; - if (option_index <= 0 + if (option_index < 0 || option_index >= context->n_opts || new_kind >= DK_LAST_DIAGNOSTIC_KIND) return DK_UNSPECIFIED; @@ -692,9 +693,8 @@ diagnostic_report_diagnostic (diagnostic /* This tests for #pragma diagnostic changes. */ if (context->n_classification_history > 0) { - int i; /* FIXME: Stupid search. Optimize later. */ - for (i = context->n_classification_history - 1; i >= 0; i --) + for (int i = context->n_classification_history - 1; i >= 0; i --) { if (linemap_location_before_p (line_table, @@ -706,7 +706,9 @@ diagnostic_report_diagnostic (diagnostic i = context->classification_history[i].option; continue; } - if (context->classification_history[i].option == diagnostic->option_index) + int option = context->classification_history[i].option; + /* The option 0 is for all the diagnostics. */ + if (option == 0 || option == diagnostic->option_index) { diag_class = context->classification_history[i].kind; if (diag_class != DK_UNSPECIFIED) Index: testsuite/gcc.dg/pragma-diag-3.c =================================================================== --- testsuite/gcc.dg/pragma-diag-3.c (revision 0) +++ testsuite/gcc.dg/pragma-diag-3.c (revision 0) @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized" } */ + +#pragma GCC diagnostic push + +int foo1 (void) +{ + int i; +#pragma GCC diagnostic off + return i; /* { dg-bogus "is used uninitialized" } */ +} + +#pragma GCC diagnostic pop + +int foo2 (void) +{ + int i; + return i; /* { dg-warning "is used uninitialized" } */ +} Index: ada/gcc-interface/trans.c =================================================================== --- ada/gcc-interface/trans.c (revision 198047) +++ ada/gcc-interface/trans.c (working copy) @@ -36,6 +36,8 @@ #include "gimple.h" #include "bitmap.h" #include "cgraph.h" +#include "diagnostic.h" +#include "opts.h" #include "target.h" #include "common/common-target.h" @@ -1184,8 +1186,8 @@ Identifier_to_gnu (Node_Id gnat_node, tr static tree Pragma_to_gnu (Node_Id gnat_node) { - Node_Id gnat_temp; tree gnu_result = alloc_stmt_list (); + Node_Id gnat_temp; /* Check for (and ignore) unrecognized pragma and do nothing if we are just annotating types. */ @@ -1278,6 +1280,89 @@ Pragma_to_gnu (Node_Id gnat_node) if (write_symbols == NO_DEBUG) post_error ("must specify -g?", gnat_node); break; + + case Pragma_Warnings: + { + Node_Id gnat_expr; + /* Preserve the location of the pragma. */ + const location_t location = input_location; + struct cl_option_handlers handlers; + unsigned int option_index; + diagnostic_t kind; + bool imply; + + gnat_temp = First (Pragma_Argument_Associations (gnat_node)); + + /* This is the String form: pragma Warnings (String). */ + if (Nkind (Expression (gnat_temp)) == N_String_Literal) + { + kind = DK_WARNING; + gnat_expr = Expression (gnat_temp); + imply = true; + } + + /* This is the On/Off form: pragma Warnings (On | Off [,String]). */ + else if (Nkind (Expression (gnat_temp)) == N_Identifier) + { + switch (Chars (Expression (gnat_temp))) + { + case Name_Off: + kind = DK_IGNORED; + break; + + case Name_On: + kind = DK_WARNING; + break; + + default: + gcc_unreachable (); + } + + if (Present (Next (gnat_temp))) + { + /* pragma Warnings (On | Off, Name) is handled differently. */ + if (Nkind (Expression (Next (gnat_temp))) != N_String_Literal) + break; + + gnat_expr = Expression (Next (gnat_temp)); + } + else + gnat_expr = Empty; + + imply = false; + } + + else + gcc_unreachable (); + + /* This is the same implementation as in the C family of compilers. */ + if (Present (gnat_expr)) + { + tree gnu_expr = gnat_to_gnu (gnat_expr); + const char *opt_string = TREE_STRING_POINTER (gnu_expr); + const int len = TREE_STRING_LENGTH (gnu_expr); + if (len < 3 || opt_string[0] != '-' || opt_string[1] != 'W') + break; + for (option_index = 0; + option_index < cl_options_count; + option_index++) + if (strcmp (cl_options[option_index].opt_text, opt_string) == 0) + break; + if (option_index == cl_options_count) + { + post_error ("unknown -W switch", gnat_node); + break; + } + } + else + option_index = 0; + + set_default_handlers (&handlers); + control_warning_option (option_index, (int) kind, imply, location, + CL_Ada, &handlers, &global_options, + &global_options_set, global_dc); + } + break; } return gnu_result;