From patchwork Thu Nov 2 20:51:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 833540 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-465791-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="wuIdnVsR"; dkim-atps=neutral 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 3yScft33KYz9sNc for ; Fri, 3 Nov 2017 07:50:29 +1100 (AEDT) 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=qHnBJQxMmXat PKQPAoMooYQz+sJTbG9negPMvLmGumVJjqKIlvRq/MOyKMDKcol+UFtOiwrdtJTC n7hPdVOm54Of8OPUUBlGsyh2z18mIyhSdWxfhflH6yaFHcyTIK4SgKXgcu6NAo0p VA0eDiz8uP4Amp7gI50F+endeW0fU4c= 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=V+v7jC1YuRX2gGxo5q MCRVjDSk0=; b=wuIdnVsRVtIDqmmWZUHbBkhLLrNWjH6PHjHKGGPLTH6Vibw4oz KJy26Lqx0mezLaRuQEM2qilCNY9Lih2y+dZwhpuwwyknt0e2ZvwI9RoIqKLeuXbL AYuGOK+JD6XaTAerm1Sz7NB792PdhAXtZ7nmoIZ+pONWhhDvFMk73ECnk= Received: (qmail 121648 invoked by alias); 2 Nov 2017 20:50:13 -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 121634 invoked by uid 89); 2 Nov 2017 20:50:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=sei, trademark, 45, Attempt X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 02 Nov 2017 20:50:07 +0000 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A9E3A37E8E for ; Thu, 2 Nov 2017 20:50:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A9E3A37E8E Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=dmalcolm@redhat.com Received: from c64.redhat.com (ovpn-112-33.phx2.redhat.com [10.3.112.33]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1124260BE0; Thu, 2 Nov 2017 20:50:02 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH] RFC: add taxonomy IDs to diagnostics (CERT C, CWE, etc) Date: Thu, 2 Nov 2017 16:51:28 -0400 Message-Id: <1509655888-48129-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes We currently identify our diagnostics via command-line options, and by the text of the option itself. This patch adds a way to supply metadata with a diagnostic, classifying the problem being reported, according to one of the software problem taxonomies e.g. "INT15-C" within the CERT C Secure Coding Standard, or "CWE-681" within the Common Weakness Enumeration (CWE). The patch tags some of our diagnostics with CERT C IDs. For example: t.c: In function 'f1': t.c:9:20: warning: division 'sizeof (int *) / sizeof (int)' does not compute the number of array elements [-Wsizeof-pointer-div] [ARR01-C] i = sizeof array / sizeof *array; /* { dg-warning "does not compute the number of array elements" } */ ^ t.c:6:10: note: first 'sizeof' operand was declared here f1 (int *array) ~~~~~^~~~~ Note the " [ARR01-C]" appended after the "[-Wsizeof-pointer-div]" above. The "ARR01-C" is colorized (assuming colorization is enabled). Such metadata IDs can be useful for categorizing problems, or for searching for helpful recommendations for addressing the diagnostic. For example, if I search for on Google for "-Wsizeof-pointer-div", I get no results (owing to the leading dash having meaning for Google); if I drop the leading dash, I get a number of different pages describing the implementation of the warning. If I search instead for "ARR01-C", the first hit takes me to the article about that issue within the SEI CERT C Coding Standard, giving lots of useful information about the problem and how to fix it. The new output can be suppressed using a new -fno-diagnostics-show-id flag. Implementation-wise, the patch replaces the "int opt" taken by our internal APIs (like warning_at), in place of a "class diag_id" which can be implicitly constructed from an "int opt", so no changes are needed at callsites that emit diagnostics, until ID tags are added, so e.g.: if (warning_at (body_loc, OPT_Wmultistatement_macros, "macro expands to multiple statements")) ... continues to compile, but can be converted to: if (warning_at (body_loc, diag_id (OPT_Wmultistatement_macros, "PRE10-C"), "macro expands to multiple statements")) ... I didn't touch the Fortran error API. Some known unknowns/questions: - is this useful? (I think so) - if we implement this, should we go through the existing diagnostics tagging them? if so, what taxonomy/taxonomies should we use? CERT vs CWE etc - should the ID be tagged with the taxonomy it comes from? (so e.g. "ARR01-C" could be tagged as being from "CERT C", somehow). How would this be presented to the end-user? Maybe: [-Wsizeof-pointer-div] [CERT-C: ARR01-C] - could/should we support multiple taxonomies e.g. CERT vs CWE e.g. "[CERT-C: ARR01C] [CWE: CWE-467]" or somesuch - if so, do we want taxonomies to be "pluggable"? consider the use-case of a plugin that implements, say, the C++ Core Guidelines, and hence could print stuff like: "[c++-core-guidelines: C.128]" or somesuch - are there license/trademark issues here? Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Thoughts? gcc/c-family/ChangeLog: * c-common.c (c_cpp_error): Provide NULL for new id parameter of diagnostic_set_info_translated. * c-warn.c (warn_for_multistatement_macros): Identify the diagnostic as "PRE10-C". gcc/c/ChangeLog: * c-decl.c (warn_defaults_to): Convert param from int to const diag_id &, and pass on taxonomy id to the diagnostic_info. * c-errors.c (pedwarn_c99): Likewise. (pedwarn_c90): Likewise. * c-parser.c (c_parser_binary_expression): Mark OPT_Wsizeof_pointer_div warning as "ARR01-C". * c-tree.h (pedwarn_c90): Convert param from int to const diag_id &. (pedwarn_c99): Likewise. * c-typeck.c (c_expr_sizeof_expr): Mark OPT_Wsizeof_array_argument warning as "ARR01-C". gcc/cp/ChangeLog: * cp-tree.h (pedwarn_cxx98): Convert param from int to const diag_id &. * error.c (pedwarn_cxx98): Likewise; pass on taxonomy id to the diagnostic_info. * typeck.c (cxx_sizeof_expr): Mark OPT_Wsizeof_array_argument warning as "ARR01-C". (cp_build_binary_op): Likewise for OPT_Wsizeof_pointer_div warning. gcc/ChangeLog: * common.opt (fdiagnostics-show-id): New option. * diagnostic-core.h (class diag_id): New class. (warning): Convert param from int to const diag_id &. (warning_n): Likewise. (warning_at): Likewise. (pedwarn): Likewise. (emit_diagnostic): Likewise. (emit_diagnostic_valist): Likewise. * diagnostic.c (diagnostic_initialize): Initialize new "show_id" field. (diagnostic_set_info_translated): Add param "taxonomy_id" and use it to initialize new field of same name. (diagnostic_set_info): Add param "taxonomy_id" and pass through to diagnostic_set_info_translated. (print_taxonomy_information): New function. (diagnostic_report_diagnostic): Call it. (diagnostic_append_note): Pass NULL for new taxonomy_id param. (diagnostic_impl): Convert param from int to const diag_id &; pass id through to diagnostic_set_info. (diagnostic_n_impl): Likewise. (emit_diagnostic): Convert param from int to const diag_id &. (emit_diagnostic_valist): Likewise. (warning): Likewise. (warning_at): Likewise. (warning_n): Likewise. (pedwarn): Likewise. (selftest::assert_print_taxonomy_information): New function. (selftest::test_print_taxonomy_information): New function. (selftest::diagnostic_c_tests): Call it. * diagnostic.h (struct diagnostic_info): New field "taxonomy_id". (struct diagnostic_context): New field "show_id". (diagnostic_set_info): Add new "const char *" param. (diagnostic_set_info_translated): Likewise. * doc/invoke.texi (Diagnostic Message Formatting Options): Add -fno-diagnostics-show-id. (-fno-diagnostics-show-id): New option. * gimple-ssa-sprintf.c (get_format_string): Update fmtwarn for change of format_warning_at_substring signature. * opts.c (common_handle_option): Handle OPT_fdiagnostics_show_id. * rtl-error.c (diagnostic_for_asm): Add NULL for new "taxonomy_id" param of diagnostic_set_info. * substring-locations.c (format_warning_va): Convert param from int to const diag_id &. Use it for taxonomy_id param in call to diagnostic_set_info. (format_warning_at_substring): Convert param from int to const diag_id &. * substring-locations.h (format_warning_va): Likewise. (format_warning_at_substring): Likewise. * toplev.c (general_init): Initialize global_dc->show_id. gcc/fortran/ChangeLog: * cpp.c (cb_cpp_error): Add NULL for new "taxonomy_id" param of diagnostic_set_info_translated. * error.c (gfc_warning): Likewise for new param of diagnostic_set_info. (gfc_warning_now_at): Likewise. (gfc_warning_now): Likewise. (gfc_warning_internal): Likewise. (gfc_error_now): Likewise. (gfc_fatal_error): Likewise. (gfc_error_opt): Likewise. (gfc_internal_error): Likewise. --- gcc/c-family/c-common.c | 2 +- gcc/c-family/c-warn.c | 3 +- gcc/c/c-decl.c | 10 ++-- gcc/c/c-errors.c | 27 +++++----- gcc/c/c-parser.c | 3 +- gcc/c/c-tree.h | 4 +- gcc/c/c-typeck.c | 2 +- gcc/common.opt | 4 ++ gcc/cp/cp-tree.h | 2 +- gcc/cp/error.c | 7 +-- gcc/cp/typeck.c | 6 ++- gcc/diagnostic-core.h | 53 +++++++++++++++----- gcc/diagnostic.c | 122 +++++++++++++++++++++++++++++++++------------- gcc/diagnostic.h | 13 ++++- gcc/doc/invoke.texi | 15 +++++- gcc/fortran/cpp.c | 2 +- gcc/fortran/error.c | 18 ++++--- gcc/gimple-ssa-sprintf.c | 2 +- gcc/opts.c | 4 ++ gcc/rtl-error.c | 2 +- gcc/substring-locations.c | 13 ++--- gcc/substring-locations.h | 8 ++- gcc/toplev.c | 2 + 23 files changed, 229 insertions(+), 95 deletions(-) diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 24077c7..bae124d 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -6069,7 +6069,7 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason, if (done_lexing) richloc->set_range (line_table, 0, input_location, true); diagnostic_set_info_translated (&diagnostic, msg, ap, - richloc, dlevel); + richloc, dlevel, NULL); diagnostic_override_option_index (&diagnostic, c_option_controlling_cpp_error (reason)); ret = diagnostic_report_diagnostic (global_dc, &diagnostic); diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 09ef685..f28f294 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -2562,7 +2562,8 @@ warn_for_multistatement_macros (location_t body_loc, location_t next_loc, return; } - if (warning_at (body_loc, OPT_Wmultistatement_macros, + if (warning_at (body_loc, + diag_id (OPT_Wmultistatement_macros, "PRE10-C"), "macro expands to multiple statements")) inform (guard_loc, "some parts of macro expansion are not guarded by " "this %qs clause", guard_tinfo_to_string (keyword)); diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index d95a2b6..ea35990 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -599,7 +599,7 @@ static tree grokdeclarator (const struct c_declarator *, bool *, enum deprecated_states); static tree grokparms (struct c_arg_info *, bool); static void layout_array_type (tree); -static void warn_defaults_to (location_t, int, const char *, ...) +static void warn_defaults_to (location_t, const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); /* T is a statement. Add it to the statement-tree. This is the @@ -5473,7 +5473,8 @@ warn_variable_length_array (tree name, tree size) /* Print warning about defaulting to int if necessary. */ static void -warn_defaults_to (location_t location, int opt, const char *gmsgid, ...) +warn_defaults_to (location_t location, const diag_id &di, const char *gmsgid, + ...) { diagnostic_info diagnostic; va_list ap; @@ -5481,8 +5482,9 @@ warn_defaults_to (location_t location, int opt, const char *gmsgid, ...) va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, - flag_isoc99 ? DK_PEDWARN : DK_WARNING); - diagnostic.option_index = opt; + flag_isoc99 ? DK_PEDWARN : DK_WARNING, + di.get_id ()); + diagnostic.option_index = di.get_option (); diagnostic_report_diagnostic (global_dc, &diagnostic); va_end (ap); } diff --git a/gcc/c/c-errors.c b/gcc/c/c-errors.c index aa9ce42..6b9c425 100644 --- a/gcc/c/c-errors.c +++ b/gcc/c/c-errors.c @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see when C11 is specified. */ bool -pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...) +pedwarn_c99 (location_t location, const diag_id &di, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; @@ -46,7 +46,7 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...) { diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, (pedantic && !flag_isoc11) - ? DK_PEDWARN : DK_WARNING); + ? DK_PEDWARN : DK_WARNING, di.get_id ()); diagnostic.option_index = OPT_Wc99_c11_compat; warned = diagnostic_report_diagnostic (global_dc, &diagnostic); } @@ -56,8 +56,9 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...) /* For -pedantic outside C11, issue a pedwarn. */ else if (pedantic && !flag_isoc11) { - diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN); - diagnostic.option_index = opt; + diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN, + di.get_id ()); + diagnostic.option_index = di.get_option (); warned = diagnostic_report_diagnostic (global_dc, &diagnostic); } va_end (ap); @@ -72,7 +73,7 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...) when C99 is specified. (There is no flag_c90.) */ bool -pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...) +pedwarn_c90 (location_t location, const diag_id &di, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; @@ -81,17 +82,18 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...) va_start (ap, gmsgid); /* Warnings such as -Wvla are the most specific ones. */ - if (opt != OPT_Wpedantic) + if (di.get_option () != OPT_Wpedantic) { - int opt_var = *(int *) option_flag_var (opt, &global_options); + int opt_var = *(int *) option_flag_var (di.get_option (), + &global_options); if (opt_var == 0) goto out; else if (opt_var > 0) { diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, (pedantic && !flag_isoc99) - ? DK_PEDWARN : DK_WARNING); - diagnostic.option_index = opt; + ? DK_PEDWARN : DK_WARNING, di.get_id ()); + diagnostic.option_index = di.get_option (); diagnostic_report_diagnostic (global_dc, &diagnostic); warned = true; goto out; @@ -103,7 +105,7 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...) { diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, (pedantic && !flag_isoc99) - ? DK_PEDWARN : DK_WARNING); + ? DK_PEDWARN : DK_WARNING, di.get_id ()); diagnostic.option_index = OPT_Wc90_c99_compat; diagnostic_report_diagnostic (global_dc, &diagnostic); } @@ -113,8 +115,9 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...) /* For -pedantic outside C99, issue a pedwarn. */ else if (pedantic && !flag_isoc99) { - diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN); - diagnostic.option_index = opt; + diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN, + di.get_id ()); + diagnostic.option_index = di.get_option (); diagnostic_report_diagnostic (global_dc, &diagnostic); warned = true; } diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 7bca5f1..0405a4a 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -6989,7 +6989,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after, && !(TREE_CODE (first_arg) == PARM_DECL \ && C_ARRAY_PARAMETER (first_arg) \ && warn_sizeof_array_argument)) \ - if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \ + if (warning_at (stack[sp].loc, \ + diag_id (OPT_Wsizeof_pointer_div, "ARR01-C"), \ "division % does " \ "not compute the number of array elements", \ type0, type1)) \ diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 1135647..c4d7921 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -756,9 +756,9 @@ extern void c_bind (location_t, tree, bool); extern bool tag_exists_p (enum tree_code, tree); /* In c-errors.c */ -extern bool pedwarn_c90 (location_t, int opt, const char *, ...) +extern bool pedwarn_c90 (location_t, const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); -extern bool pedwarn_c99 (location_t, int opt, const char *, ...) +extern bool pedwarn_c99 (location_t, const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern void diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 4bdc48a..394b556 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -2905,7 +2905,7 @@ c_expr_sizeof_expr (location_t loc, struct c_expr expr) if (TREE_CODE (expr.value) == PARM_DECL && C_ARRAY_PARAMETER (expr.value)) { - if (warning_at (loc, OPT_Wsizeof_array_argument, + if (warning_at (loc, diag_id (OPT_Wsizeof_array_argument, "ARR01-C"), "% on array function parameter %qE will " "return size of %qT", expr.value, TREE_TYPE (expr.value))) diff --git a/gcc/common.opt b/gcc/common.opt index f8f2ed3..4c13205 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1268,6 +1268,10 @@ fdiagnostics-show-option Common Var(flag_diagnostics_show_option) Init(1) Amend appropriate diagnostic messages with the command line option that controls them. +fdiagnostics-show-id +Common Var(flag_diagnostics_show_id) Init(1) +Amend appropriate diagnostic messages with an identifier within a problem taxonomy. + fdisable- Common Joined RejectNegative Var(common_deferred_options) Defer -fdisable-[tree|rtl|ipa]-=range1+range2 disables an optimization pass. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 257c877..3ff2703 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6222,7 +6222,7 @@ extern const char *language_to_string (enum languages); extern const char *class_key_or_enum_as_string (tree); extern void maybe_warn_variadic_templates (void); extern void maybe_warn_cpp0x (cpp0x_warn_str str); -extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); +extern bool pedwarn_cxx98 (location_t, const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern location_t location_of (tree); extern void qualified_name_lookup_error (tree, tree, tree, location_t); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 2537713..80e45bf 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -4181,7 +4181,7 @@ maybe_warn_variadic_templates (void) diagnostics for constructs that are invalid C++98, but valid C++0x. */ bool -pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...) +pedwarn_cxx98 (location_t location, const diag_id &di, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; @@ -4190,8 +4190,9 @@ pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...) va_start (ap, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, - (cxx_dialect == cxx98) ? DK_PEDWARN : DK_WARNING); - diagnostic.option_index = opt; + (cxx_dialect == cxx98) ? DK_PEDWARN : DK_WARNING, + di.get_id ()); + diagnostic.option_index = di.get_option (); ret = diagnostic_report_diagnostic (global_dc, &diagnostic); va_end (ap); return ret; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 285d8d2..5b279df 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1637,7 +1637,8 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain) && DECL_ARRAY_PARAMETER_P (e) && (complain & tf_warning)) { - if (warning (OPT_Wsizeof_array_argument, "% on array function " + if (warning (diag_id (OPT_Wsizeof_array_argument, "ARR01-C"), + "% on array function " "parameter %qE will return size of %qT", e, TREE_TYPE (e))) inform (DECL_SOURCE_LOCATION (e), "declared here"); } @@ -4374,7 +4375,8 @@ cp_build_binary_op (location_t location, && DECL_ARRAY_PARAMETER_P (first_arg) && warn_sizeof_array_argument) && (complain & tf_warning)) - if (warning_at (location, OPT_Wsizeof_pointer_div, + if (warning_at (location, + diag_id (OPT_Wsizeof_pointer_div, "ARR01-C"), "division % does " "not compute the number of array elements", type0, type1)) diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h index 24025f1..7b23cf6 100644 --- a/gcc/diagnostic-core.h +++ b/gcc/diagnostic-core.h @@ -36,6 +36,36 @@ typedef enum DK_POP } diagnostic_t; +/* A class for describing a diagnostic. + + It wraps: + + (a) one of the OPT_W* from options.h, describing the command-line + option controlling it (if any), and, + + (b) optionally, an ID from a problem taxonomy (such as "PRE10-C" from the + CERT C Secure Coding Standard, or "CWE-681" from the Common Weakness + Enumeration). + + It is in this header so that users of the simple diagnostic API (e.g. + warning_at) can pass in OPT_W* flags and have them be implicitly + converted to diag_id. */ + +class diag_id +{ + public: + /* Pass one of the OPT_W* from options.h as the first parameter. */ + diag_id (int opt) : m_opt (opt), m_id (NULL) {} + diag_id (int opt, const char *id) : m_opt (opt), m_id (id) {} + + int get_option () const { return m_opt; } + const char *get_id () const { return m_id; } + + private: + int m_opt; + const char *m_id; +}; + extern const char *progname; extern const char *trim_filename (const char *); @@ -57,16 +87,15 @@ extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2) ATTRIBUTE_NORETURN; extern void internal_error_no_backtrace (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2) ATTRIBUTE_NORETURN; -/* Pass one of the OPT_W* from options.h as the first parameter. */ -extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); -extern bool warning_n (location_t, int, int, const char *, const char *, ...) +extern bool warning (const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); +extern bool warning_n (location_t, const diag_id &, int, const char *, const char *, ...) ATTRIBUTE_GCC_DIAG(4,6) ATTRIBUTE_GCC_DIAG(5,6); -extern bool warning_n (rich_location *, int, int, const char *, +extern bool warning_n (rich_location *, const diag_id &, int, const char *, const char *, ...) ATTRIBUTE_GCC_DIAG(4, 6) ATTRIBUTE_GCC_DIAG(5, 6); -extern bool warning_at (location_t, int, const char *, ...) +extern bool warning_at (location_t, const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); -extern bool warning_at (rich_location *, int, const char *, ...) +extern bool warning_at (rich_location *, const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); extern void error_n (location_t, int, const char *, const char *, ...) @@ -76,10 +105,9 @@ extern void error_at (rich_location *, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); extern void fatal_error (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3) ATTRIBUTE_NORETURN; -/* Pass one of the OPT_W* from options.h as the second parameter. */ -extern bool pedwarn (location_t, int, const char *, ...) +extern bool pedwarn (location_t, const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); -extern bool pedwarn (rich_location *, int, const char *, ...) +extern bool pedwarn (rich_location *, const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern bool permerror (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); extern bool permerror (rich_location *, const char *, @@ -90,10 +118,11 @@ extern void inform (rich_location *, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); extern void inform_n (location_t, int, const char *, const char *, ...) ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5); extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); -extern bool emit_diagnostic (diagnostic_t, location_t, int, +extern bool emit_diagnostic (diagnostic_t, location_t, const diag_id &, const char *, ...) ATTRIBUTE_GCC_DIAG(4,5); -extern bool emit_diagnostic_valist (diagnostic_t, location_t, int, const char *, - va_list *) ATTRIBUTE_GCC_DIAG (4,0); +extern bool emit_diagnostic_valist (diagnostic_t, location_t, const diag_id &, + const char *, va_list *) + ATTRIBUTE_GCC_DIAG (4,0); extern bool seen_error (void); #ifdef BUFSIZ diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 813bca6..a687b5e 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -49,10 +49,10 @@ along with GCC; see the file COPYING3. If not see #define permissive_error_option(DC) ((DC)->opt_permissive) /* Prototypes. */ -static bool diagnostic_impl (rich_location *, int, const char *, +static bool diagnostic_impl (rich_location *, const diag_id &, const char *, va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(3,0); -static bool diagnostic_n_impl (rich_location *, int, int, const char *, - const char *, va_list *, +static bool diagnostic_n_impl (rich_location *, const diag_id &, int, + const char *, const char *, va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0); static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; @@ -153,6 +153,7 @@ diagnostic_initialize (diagnostic_context *context, int n_opts) for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++) context->caret_chars[i] = '^'; context->show_option_requested = false; + context->show_id = false; context->abort_on_error = false; context->show_column = false; context->pedantic_errors = false; @@ -252,7 +253,7 @@ diagnostic_finish (diagnostic_context *context) void diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, va_list *args, rich_location *richloc, - diagnostic_t kind) + diagnostic_t kind, const char *taxonomy_id) { gcc_assert (richloc); diagnostic->message.err_no = errno; @@ -262,6 +263,7 @@ diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, diagnostic->richloc = richloc; diagnostic->kind = kind; diagnostic->option_index = 0; + diagnostic->taxonomy_id = taxonomy_id; } /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been @@ -269,10 +271,11 @@ diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, void diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid, va_list *args, rich_location *richloc, - diagnostic_t kind) + diagnostic_t kind, const char *taxonomy_id) { gcc_assert (richloc); - diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind); + diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind, + taxonomy_id); } static const char *const diagnostic_kind_color[] = { @@ -859,6 +862,26 @@ print_option_information (diagnostic_context *context, } } +/* Print any metadata identifying DIAGNOSTIC within a problem taxonomy + (such as CWE) to CONTEXT's printer, e.g. " [CWE-681]". + Subroutine of diagnostic_report_diagnostic. */ + +static void +print_taxonomy_information (diagnostic_context *context, + const diagnostic_info *diagnostic) +{ + if (diagnostic->taxonomy_id == NULL) + return; + + pretty_printer *pp = context->printer; + pp_string (pp, " ["); + pp_string (pp, colorize_start (pp_show_color (pp), + diagnostic_kind_color[diagnostic->kind])); + pp_string (pp, diagnostic->taxonomy_id); + pp_string (pp, colorize_stop (pp_show_color (pp))); + pp_character (pp, ']'); +} + /* Report a diagnostic message (an error or a warning) as specified by DC. This function is *the* subroutine in terms of which front-ends should implement their specific diagnostic handling modules. The @@ -974,6 +997,8 @@ diagnostic_report_diagnostic (diagnostic_context *context, pp_output_formatted_text (context->printer); if (context->show_option_requested) print_option_information (context, diagnostic, orig_diag_kind); + if (context->show_id) + print_taxonomy_information (context, diagnostic); (*diagnostic_finalizer (context)) (context, diagnostic); if (context->parseable_fixits_p) { @@ -1055,7 +1080,7 @@ diagnostic_append_note (diagnostic_context *context, rich_location richloc (line_table, location); va_start (ap, gmsgid); - diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE); + diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE, NULL); if (context->inhibit_notes_p) { va_end (ap); @@ -1076,7 +1101,7 @@ diagnostic_append_note (diagnostic_context *context, permerror, error, error_at, error_at, sorry, fatal_error, internal_error, and internal_error_no_backtrace, as documented and defined below. */ static bool -diagnostic_impl (rich_location *richloc, int opt, +diagnostic_impl (rich_location *richloc, const diag_id &di, const char *gmsgid, va_list *ap, diagnostic_t kind) { @@ -1084,14 +1109,16 @@ diagnostic_impl (rich_location *richloc, int opt, if (kind == DK_PERMERROR) { diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, - permissive_error_kind (global_dc)); + permissive_error_kind (global_dc), + di.get_id ()); diagnostic.option_index = permissive_error_option (global_dc); } else { - diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind); + diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind, + di.get_id ()); if (kind == DK_WARNING || kind == DK_PEDWARN) - diagnostic.option_index = opt; + diagnostic.option_index = di.get_option (); } return diagnostic_report_diagnostic (global_dc, &diagnostic); } @@ -1099,7 +1126,7 @@ diagnostic_impl (rich_location *richloc, int opt, /* Implement inform_n, warning_n, and error_n, as documented and defined below. */ static bool -diagnostic_n_impl (rich_location *richloc, int opt, int n, +diagnostic_n_impl (rich_location *richloc, const diag_id &di, int n, const char *singular_gmsgid, const char *plural_gmsgid, va_list *ap, diagnostic_t kind) @@ -1107,22 +1134,22 @@ diagnostic_n_impl (rich_location *richloc, int opt, int n, diagnostic_info diagnostic; diagnostic_set_info_translated (&diagnostic, ngettext (singular_gmsgid, plural_gmsgid, n), - ap, richloc, kind); + ap, richloc, kind, di.get_id ()); if (kind == DK_WARNING) - diagnostic.option_index = opt; + diagnostic.option_index = di.get_option (); return diagnostic_report_diagnostic (global_dc, &diagnostic); } /* Wrapper around diagnostic_impl taking a variable argument list. */ bool -emit_diagnostic (diagnostic_t kind, location_t location, int opt, +emit_diagnostic (diagnostic_t kind, location_t location, const diag_id &di, const char *gmsgid, ...) { va_list ap; va_start (ap, gmsgid); rich_location richloc (line_table, location); - bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, kind); + bool ret = diagnostic_impl (&richloc, di, gmsgid, &ap, kind); va_end (ap); return ret; } @@ -1130,11 +1157,12 @@ emit_diagnostic (diagnostic_t kind, location_t location, int opt, /* Wrapper around diagnostic_impl taking a va_list parameter. */ bool -emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt, +emit_diagnostic_valist (diagnostic_t kind, location_t location, + const diag_id &di, const char *gmsgid, va_list *ap) { rich_location richloc (line_table, location); - return diagnostic_impl (&richloc, opt, gmsgid, ap, kind); + return diagnostic_impl (&richloc, di, gmsgid, ap, kind); } /* An informative note at LOCATION. Use this for additional details on an error @@ -1179,12 +1207,12 @@ inform_n (location_t location, int n, const char *singular_gmsgid, to the relevant language specification but is likely to be buggy anyway. Returns true if the warning was printed, false if it was inhibited. */ bool -warning (int opt, const char *gmsgid, ...) +warning (const diag_id &di, const char *gmsgid, ...) { va_list ap; va_start (ap, gmsgid); rich_location richloc (line_table, input_location); - bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_WARNING); + bool ret = diagnostic_impl (&richloc, di, gmsgid, &ap, DK_WARNING); va_end (ap); return ret; } @@ -1194,12 +1222,12 @@ warning (int opt, const char *gmsgid, ...) Returns true if the warning was printed, false if it was inhibited. */ bool -warning_at (location_t location, int opt, const char *gmsgid, ...) +warning_at (location_t location, const diag_id &di, const char *gmsgid, ...) { va_list ap; va_start (ap, gmsgid); rich_location richloc (line_table, location); - bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_WARNING); + bool ret = diagnostic_impl (&richloc, di, gmsgid, &ap, DK_WARNING); va_end (ap); return ret; } @@ -1207,13 +1235,14 @@ warning_at (location_t location, int opt, const char *gmsgid, ...) /* Same as "warning at" above, but using RICHLOC. */ bool -warning_at (rich_location *richloc, int opt, const char *gmsgid, ...) +warning_at (rich_location *richloc, const diag_id &di, + const char *gmsgid, ...) { gcc_assert (richloc); va_list ap; va_start (ap, gmsgid); - bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, DK_WARNING); + bool ret = diagnostic_impl (richloc, di, gmsgid, &ap, DK_WARNING); va_end (ap); return ret; } @@ -1221,14 +1250,14 @@ warning_at (rich_location *richloc, int opt, const char *gmsgid, ...) /* Same as warning_n plural variant below, but using RICHLOC. */ bool -warning_n (rich_location *richloc, int opt, int n, +warning_n (rich_location *richloc, const diag_id &di, int n, const char *singular_gmsgid, const char *plural_gmsgid, ...) { gcc_assert (richloc); va_list ap; va_start (ap, plural_gmsgid); - bool ret = diagnostic_n_impl (richloc, opt, n, + bool ret = diagnostic_n_impl (richloc, di, n, singular_gmsgid, plural_gmsgid, &ap, DK_WARNING); va_end (ap); @@ -1240,13 +1269,13 @@ warning_n (rich_location *richloc, int opt, int n, Returns true if the warning was printed, false if it was inhibited. */ bool -warning_n (location_t location, int opt, int n, const char *singular_gmsgid, - const char *plural_gmsgid, ...) +warning_n (location_t location, const diag_id &di, int n, + const char *singular_gmsgid, const char *plural_gmsgid, ...) { va_list ap; va_start (ap, plural_gmsgid); rich_location richloc (line_table, location); - bool ret = diagnostic_n_impl (&richloc, opt, n, + bool ret = diagnostic_n_impl (&richloc, di, n, singular_gmsgid, plural_gmsgid, &ap, DK_WARNING); va_end (ap); @@ -1267,12 +1296,12 @@ warning_n (location_t location, int opt, int n, const char *singular_gmsgid, Returns true if the warning was printed, false if it was inhibited. */ bool -pedwarn (location_t location, int opt, const char *gmsgid, ...) +pedwarn (location_t location, const diag_id &di, const char *gmsgid, ...) { va_list ap; va_start (ap, gmsgid); rich_location richloc (line_table, location); - bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_PEDWARN); + bool ret = diagnostic_impl (&richloc, di, gmsgid, &ap, DK_PEDWARN); va_end (ap); return ret; } @@ -1280,13 +1309,13 @@ pedwarn (location_t location, int opt, const char *gmsgid, ...) /* Same as pedwarn above, but using RICHLOC. */ bool -pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...) +pedwarn (rich_location *richloc, const diag_id &di, const char *gmsgid, ...) { gcc_assert (richloc); va_list ap; va_start (ap, gmsgid); - bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, DK_PEDWARN); + bool ret = diagnostic_impl (richloc, di, gmsgid, &ap, DK_PEDWARN); va_end (ap); return ret; } @@ -1667,6 +1696,32 @@ test_diagnostic_get_location_text () progname = old_progname; } +/* Verify that print_taxonomy_information prints EXPECTED, given ID. */ + +static void +assert_print_taxonomy_information (const char *expected, const char *id) +{ + test_diagnostic_context dc; + diagnostic_info diagnostic; + + diagnostic.kind = DK_WARNING; + + pretty_printer *pp = dc.printer; + + diagnostic.taxonomy_id = id; + print_taxonomy_information (&dc, &diagnostic); + ASSERT_STREQ (expected, pp_formatted_text (pp)); +} + +/* Verify that print_taxonomy_information works as expected. */ + +static void +test_print_taxonomy_information () +{ + assert_print_taxonomy_information ("", NULL); + assert_print_taxonomy_information (" [CWE-681]", "CWE-681"); +} + /* Run all of the selftests within this file. */ void @@ -1678,6 +1733,7 @@ diagnostic_c_tests () test_print_parseable_fixits_remove (); test_print_parseable_fixits_replace (); test_diagnostic_get_location_text (); + test_print_taxonomy_information (); } } // namespace selftest diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index dbd1703..70fbc4c 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -41,6 +41,10 @@ struct diagnostic_info diagnostic_t kind; /* Which OPT_* directly controls this diagnostic. */ int option_index; + /* An optional ID from a problem taxonomy (such as "PRE10-C" from the + CERT C Secure Coding Standard, or "CWE-681" from the Common Weakness + Enumeration). */ + const char *taxonomy_id; }; /* Each time a diagnostic's classification is changed with a pragma, @@ -117,6 +121,10 @@ struct diagnostic_context each diagnostic, if known. */ bool show_option_requested; + /* True if we should print any identifier within a problem taxonomy + for each diagnostic, if known. */ + bool show_id; + /* True if we should raise a SIGABRT on errors. */ bool abort_on_error; @@ -297,10 +305,11 @@ extern bool diagnostic_report_diagnostic (diagnostic_context *, diagnostic_info *); #ifdef ATTRIBUTE_GCC_DIAG extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *, - rich_location *, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0); + rich_location *, diagnostic_t, const char *) + ATTRIBUTE_GCC_DIAG(2,0); extern void diagnostic_set_info_translated (diagnostic_info *, const char *, va_list *, rich_location *, - diagnostic_t) + diagnostic_t, const char *) ATTRIBUTE_GCC_DIAG(2,0); extern void diagnostic_append_note (diagnostic_context *, location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 43acbcb..9562898 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -250,7 +250,8 @@ Objective-C and Objective-C++ Dialects}. @gccoptlist{-fmessage-length=@var{n} @gol -fdiagnostics-show-location=@r{[}once@r{|}every-line@r{]} @gol -fdiagnostics-color=@r{[}auto@r{|}never@r{|}always@r{]} @gol --fno-diagnostics-show-option -fno-diagnostics-show-caret @gol +-fno-diagnostics-show-option -fno-diagnostics-show-id @gol +-fno-diagnostics-show-caret @gol -fdiagnostics-parseable-fixits -fdiagnostics-generate-patch @gol -fdiagnostics-show-template-tree -fno-elide-type @gol -fno-show-column} @@ -3575,6 +3576,18 @@ command-line option that directly controls the diagnostic (if such an option is known to the diagnostic machinery). Specifying the @option{-fno-diagnostics-show-option} flag suppresses that behavior. +@item -fno-diagnostics-show-id +@opindex fno-diagnostics-show-id +@opindex fdiagnostics-show-id +By default, each diagnostic emitted can include text indicating an +ID within a problem taxonomy, such as `INT15-C` within the +CERT C Secure Coding Standard, or `CWE-681` within the +Common Weakness Enumeration (CWE). +Such IDs can be useful for categorizing problems, or for searching for +helpful recommendations for addressing the diagnostic. +Specifying the @option{-fno-diagnostics-show-id} flag suppresses that +behavior. + @item -fno-diagnostics-show-caret @opindex fno-diagnostics-show-caret @opindex fdiagnostics-show-caret diff --git a/gcc/fortran/cpp.c b/gcc/fortran/cpp.c index af8a69c..b657583 100644 --- a/gcc/fortran/cpp.c +++ b/gcc/fortran/cpp.c @@ -1059,7 +1059,7 @@ cb_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason, gcc_unreachable (); } diagnostic_set_info_translated (&diagnostic, msg, ap, - richloc, dlevel); + richloc, dlevel, NULL); if (reason == CPP_W_WARNING_DIRECTIVE) diagnostic_override_option_index (&diagnostic, OPT_Wcpp); ret = diagnostic_report_diagnostic (global_dc, &diagnostic); diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c index 3ad1cf9..6bc9fef 100644 --- a/gcc/fortran/error.c +++ b/gcc/fortran/error.c @@ -787,7 +787,7 @@ gfc_warning (int opt, const char *gmsgid, va_list ap) } diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, - DK_WARNING); + DK_WARNING, NULL); diagnostic.option_index = opt; bool ret = diagnostic_report_diagnostic (global_dc, &diagnostic); @@ -1137,7 +1137,8 @@ gfc_warning_now_at (location_t loc, int opt, const char *gmsgid, ...) bool ret; va_start (argp, gmsgid); - diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_WARNING); + diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_WARNING, + NULL); diagnostic.option_index = opt; ret = diagnostic_report_diagnostic (global_dc, &diagnostic); va_end (argp); @@ -1156,7 +1157,7 @@ gfc_warning_now (int opt, const char *gmsgid, ...) va_start (argp, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, - DK_WARNING); + DK_WARNING, NULL); diagnostic.option_index = opt; ret = diagnostic_report_diagnostic (global_dc, &diagnostic); va_end (argp); @@ -1175,7 +1176,7 @@ gfc_warning_internal (int opt, const char *gmsgid, ...) va_start (argp, gmsgid); diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, - DK_WARNING); + DK_WARNING, NULL); diagnostic.option_index = opt; ret = diagnostic_report_diagnostic (global_dc, &diagnostic); va_end (argp); @@ -1194,7 +1195,8 @@ gfc_error_now (const char *gmsgid, ...) error_buffer.flag = true; va_start (argp, gmsgid); - diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ERROR); + diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ERROR, + NULL); diagnostic_report_diagnostic (global_dc, &diagnostic); va_end (argp); } @@ -1210,7 +1212,7 @@ gfc_fatal_error (const char *gmsgid, ...) rich_location rich_loc (line_table, UNKNOWN_LOCATION); va_start (argp, gmsgid); - diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_FATAL); + diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_FATAL, NULL); diagnostic_report_diagnostic (global_dc, &diagnostic); va_end (argp); @@ -1295,7 +1297,7 @@ gfc_error_opt (int opt, const char *gmsgid, va_list ap) --errorcount; } - diagnostic_set_info (&diagnostic, gmsgid, &argp, &richloc, DK_ERROR); + diagnostic_set_info (&diagnostic, gmsgid, &argp, &richloc, DK_ERROR, NULL); diagnostic_report_diagnostic (global_dc, &diagnostic); if (buffered_p) @@ -1345,7 +1347,7 @@ gfc_internal_error (const char *gmsgid, ...) exit(EXIT_FAILURE); va_start (argp, gmsgid); - diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ICE); + diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ICE, NULL); diagnostic_report_diagnostic (global_dc, &diagnostic); va_end (argp); diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 7415413..1ca62c6 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -594,7 +594,7 @@ get_format_string (tree format, location_t *ploc) static bool (* const fmtwarn) (const substring_loc &, location_t, - const char *, int, const char *, ...) + const char *, const diag_id &, const char *, ...) = format_warning_at_substring; /* Format length modifiers. */ diff --git a/gcc/opts.c b/gcc/opts.c index ac383d4..9bcfa75 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -2098,6 +2098,10 @@ common_handle_option (struct gcc_options *opts, dc->show_option_requested = value; break; + case OPT_fdiagnostics_show_id: + dc->show_id = value; + break; + case OPT_fdump_: /* Deferred. */ break; diff --git a/gcc/rtl-error.c b/gcc/rtl-error.c index e04bd7e..eab90ac 100644 --- a/gcc/rtl-error.c +++ b/gcc/rtl-error.c @@ -70,7 +70,7 @@ diagnostic_for_asm (const rtx_insn *insn, const char *msg, va_list *args_ptr, rich_location richloc (line_table, location_for_asm (insn)); diagnostic_set_info (&diagnostic, msg, args_ptr, - &richloc, kind); + &richloc, kind, NULL); diagnostic_report_diagnostic (global_dc, &diagnostic); } diff --git a/gcc/substring-locations.c b/gcc/substring-locations.c index 7de435b..092d81f 100644 --- a/gcc/substring-locations.c +++ b/gcc/substring-locations.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "substring-locations.h" -/* Emit a warning governed by option OPT, using GMSGID as the format +/* Emit a warning governed by option DI, using GMSGID as the format string and AP as its arguments. Attempt to obtain precise location information within a string @@ -102,7 +102,7 @@ bool format_warning_va (const substring_loc &fmt_loc, location_t param_loc, const char *corrected_substring, - int opt, const char *gmsgid, va_list *ap) + const diag_id &di, const char *gmsgid, va_list *ap) { bool substring_within_range = false; location_t primary_loc; @@ -143,8 +143,9 @@ format_warning_va (const substring_loc &fmt_loc, richloc.add_fixit_replace (fmt_substring_range, corrected_substring); diagnostic_info diagnostic; - diagnostic_set_info (&diagnostic, gmsgid, ap, &richloc, DK_WARNING); - diagnostic.option_index = opt; + diagnostic_set_info (&diagnostic, gmsgid, ap, &richloc, DK_WARNING, + di.get_id ()); + diagnostic.option_index = di.get_option (); bool warned = diagnostic_report_diagnostic (global_dc, &diagnostic); if (!err && fmt_substring_loc && !substring_within_range) @@ -168,12 +169,12 @@ bool format_warning_at_substring (const substring_loc &fmt_loc, location_t param_loc, const char *corrected_substring, - int opt, const char *gmsgid, ...) + const diag_id &di, const char *gmsgid, ...) { va_list ap; va_start (ap, gmsgid); bool warned = format_warning_va (fmt_loc, param_loc, corrected_substring, - opt, gmsgid, &ap); + di, gmsgid, &ap); va_end (ap); return warned; diff --git a/gcc/substring-locations.h b/gcc/substring-locations.h index 3d7796d..13df498 100644 --- a/gcc/substring-locations.h +++ b/gcc/substring-locations.h @@ -79,13 +79,17 @@ class substring_loc extern bool format_warning_va (const substring_loc &fmt_loc, location_t param_loc, const char *corrected_substring, - int opt, const char *gmsgid, va_list *ap) + const diag_id &di, + const char *gmsgid, + va_list *ap) ATTRIBUTE_GCC_DIAG (5,0); extern bool format_warning_at_substring (const substring_loc &fmt_loc, location_t param_loc, const char *corrected_substring, - int opt, const char *gmsgid, ...) + const diag_id &di, + const char *gmsgid, + ...) ATTRIBUTE_GCC_DIAG (5,0); /* Implementation detail, for use when implementing diff --git a/gcc/toplev.c b/gcc/toplev.c index eff1690..590ab58 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1102,6 +1102,8 @@ general_init (const char *argv0, bool init_signals) = global_options_init.x_flag_diagnostics_show_caret; global_dc->show_option_requested = global_options_init.x_flag_diagnostics_show_option; + global_dc->show_id + = global_options_init.x_flag_diagnostics_show_id; global_dc->show_column = global_options_init.x_flag_show_column; global_dc->internal_error = internal_error_function;