From patchwork Wed Jul 24 22:18:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964556 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=jQo+wQ2n; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpMn4vNlz1ydm for ; Thu, 25 Jul 2024 08:19:17 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C67D1385DDE3 for ; Wed, 24 Jul 2024 22:19:15 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 90E91385AC29 for ; Wed, 24 Jul 2024 22:18:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 90E91385AC29 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 90E91385AC29 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859524; cv=none; b=RzMPkwm4oyxPBs7QC7rAZxFoOXtHibfqEVf3RmDQTy8jHxBfJOi8x1dXCtwjUJYJu8o3q4xqy8kwUwRSW29zdFl8jfaabS0+maNJAjLRswbzyznUDqk2df88iGVnD4ZK3b/QAEt6BAonv6ZAmqoPFToRHlqW7gOhMFP1ntI2RgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859524; c=relaxed/simple; bh=doFunrOO/Bp9gVuLyDZMYQIxU3utyAgl2PwOFmm3H2s=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=bqa/xLU9zTLOp3rPCud3unuNnhX9GHdLI6KdYd1k43ERWZAULQ2JCAo4W5ZYGgi7LEQYkiM+iJj8ceh74iw0+SsYhiMGLxC7nhQ2QoAJ7oWEEraC/nbdH7fIpXqUG6PUBuWodWLDgPCm6JmPtY+r1i00jrhTh2haDct5UuYzLxw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859522; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3hbDnd4ctHpjtniIgLnLJeqEiq8LyNW2ecKsY+0neUM=; b=jQo+wQ2nrCKirj60RRLqCFffFT9ih17sXoGINfvdfWUZuZGNjmrC2InRxTQzMENyNLV0QP LI5f4qJLzZjdC9XP/0Uwisz4SXHtSy1QYz98p4ZtMPkPwzKrC1mArS4uCviKTDB9G0t/Q2 fayLFuUkFOZrvguop0uEYqBrGUrUSy8= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-358-ETcpS8GUNz-qehoCkZVPAQ-1; Wed, 24 Jul 2024 18:18:38 -0400 X-MC-Unique: ETcpS8GUNz-qehoCkZVPAQ-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 748BC1955D44 for ; Wed, 24 Jul 2024 22:18:36 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 846821955E80; Wed, 24 Jul 2024 22:18:35 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 01/16] json: add dump overload for easier debugging Date: Wed, 24 Jul 2024 18:18:09 -0400 Message-Id: <20240724221824.585054-2-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org This has saved me a lot of typing in the debugger. gcc/ChangeLog: * json.cc (value::dump): New overload, taking no params. * json.h (value::dump): New decl. Signed-off-by: David Malcolm --- gcc/json.cc | 10 ++++++++++ gcc/json.h | 1 + 2 files changed, 11 insertions(+) diff --git a/gcc/json.cc b/gcc/json.cc index b3106f39cedf..53edca520556 100644 --- a/gcc/json.cc +++ b/gcc/json.cc @@ -90,6 +90,16 @@ value::dump (FILE *outf, bool formatted) const pp_flush (&pp); } +/* A convenience function for debugging. + Dump to stderr with formatting, and a trailing newline. */ + +void +value::dump () const +{ + dump (stderr, true); + fprintf (stderr, "\n"); +} + /* class json::object, a subclass of json::value, representing an ordered collection of key/value pairs. */ diff --git a/gcc/json.h b/gcc/json.h index 97c68116b329..ad4f8c448f8c 100644 --- a/gcc/json.h +++ b/gcc/json.h @@ -83,6 +83,7 @@ class value virtual void print (pretty_printer *pp, bool formatted) const = 0; void dump (FILE *, bool formatted) const; + void DEBUG_FUNCTION dump () const; }; /* Subclass of value for objects: a collection of key/value pairs From patchwork Wed Jul 24 22:18:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964555 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ASsww34m; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpMn4sLTz1ybY for ; Thu, 25 Jul 2024 08:19:17 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E5A15385C6CC for ; Wed, 24 Jul 2024 22:19:15 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 7D116385B50B for ; Wed, 24 Jul 2024 22:18:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7D116385B50B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7D116385B50B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859524; cv=none; b=V3uFJjH+oj4GfE1dr6XVQxG3Yaad7jO5BPctY/4aMLDFt9oRjbRDMiSQT6htk6xaYNvcJ7P2SYBy1Bu1VuJMEp6TiVyT+0oXJc4BroOLwHStvSFBYo1nnZTA5WLrw1rGfjaSgIu10Cb9N+Rw6fEaGlmEhHvFZsSl8jgmnJyr7IY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859524; c=relaxed/simple; bh=+n+9hGRUe38uUItzpdcoU62JLNWv/ZsqI0yM4FNTiyw=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=EJiq/VSbOHbhRxAkze8Ho7V768dSn6MIwazT9C8mtYHhfDzIaGZurst2A8IvDz1sP/V8zZRgoVPpTZwkbvwpdFWAoZ1qiHhk/zKYhToF3xlkmVKrL9NiKpkrxhEX0eMuR6/EeqYzrOsMyqe1cu8tQzSiZCL+ndQoqRr0YfwWK7M= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859521; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YtdIlYR5KQsHCTDu1890MTxIVhyh33TrBDWXX5AHdkc=; b=ASsww34mSSSEUGVyzaCZnxFzpXbs2lDXqZ85LsXgKI0IX8EO9/49K2Fy6i003xCTY99pL6 vfRkdEB2mv69XyNpzL9xcR4QC1WeFgcWN/hz4GnxGVLtx61STJbwvooBr4LhuT8SDY+Yia PAhuWxH858YPusEzSA+an2G88YDoSx0= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-439-H9WEiIqJPSyd47ooI1tSQA-1; Wed, 24 Jul 2024 18:18:38 -0400 X-MC-Unique: H9WEiIqJPSyd47ooI1tSQA-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id F20921955F42 for ; Wed, 24 Jul 2024 22:18:37 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EE8831955F3B; Wed, 24 Jul 2024 22:18:36 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 02/16] json: add array::append_string Date: Wed, 24 Jul 2024 18:18:10 -0400 Message-Id: <20240724221824.585054-3-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org No functional change intended. gcc/analyzer/ChangeLog: * supergraph.cc (supernode::to_json): Avoid naked "new" by using json::array::append_string. (supernode::to_json): Likewise. gcc/ChangeLog: * diagnostic-format-sarif.cc (sarif_artifact::populate_roles): Avoid naked "new" by using json::array::append_string. (sarif_builder::maybe_make_kinds_array): Likewise. * json.cc (json::array::append_string): New. (selftest::test_writing_arrays): Use it. * json.h (json::array::append_string): New decl. * optinfo-emit-json.cc (optrecord_json_writer::pass_to_json): Avoid naked "new" by using json::array::append_string. (optrecord_json_writer::optinfo_to_json): Likewise. Signed-off-by: David Malcolm --- gcc/analyzer/supergraph.cc | 4 ++-- gcc/diagnostic-format-sarif.cc | 8 ++++---- gcc/json.cc | 9 ++++++++- gcc/json.h | 1 + gcc/optinfo-emit-json.cc | 4 ++-- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc index 4dc7942b26aa..20c62856d4b6 100644 --- a/gcc/analyzer/supergraph.cc +++ b/gcc/analyzer/supergraph.cc @@ -747,7 +747,7 @@ supernode::to_json () const pretty_printer pp; pp_format_decoder (&pp) = default_tree_printer; pp_gimple_stmt_1 (&pp, stmt, 0, (dump_flags_t)0); - phi_arr->append (new json::string (pp_formatted_text (&pp))); + phi_arr->append_string (pp_formatted_text (&pp)); } snode_obj->set ("phis", phi_arr); } @@ -762,7 +762,7 @@ supernode::to_json () const pretty_printer pp; pp_format_decoder (&pp) = default_tree_printer; pp_gimple_stmt_1 (&pp, stmt, 0, (dump_flags_t)0); - stmt_arr->append (new json::string (pp_formatted_text (&pp))); + stmt_arr->append_string (pp_formatted_text (&pp)); } snode_obj->set ("stmts", stmt_arr); } diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 225476995d13..7105f7853318 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -435,7 +435,7 @@ sarif_artifact::populate_roles () if (bitmap_bit_p (m_roles, i)) { enum diagnostic_artifact_role role = (enum diagnostic_artifact_role)i; - roles_arr->append (new json::string (get_artifact_role_string (role))); + roles_arr->append_string (get_artifact_role_string (role)); } set ("roles", roles_arr); } @@ -1394,13 +1394,13 @@ sarif_builder::maybe_make_kinds_array (diagnostic_event::meaning m) const json::array *kinds_arr = new json::array (); if (const char *verb_str = diagnostic_event::meaning::maybe_get_verb_str (m.m_verb)) - kinds_arr->append (new json::string (verb_str)); + kinds_arr->append_string (verb_str); if (const char *noun_str = diagnostic_event::meaning::maybe_get_noun_str (m.m_noun)) - kinds_arr->append (new json::string (noun_str)); + kinds_arr->append_string (noun_str); if (const char *property_str = diagnostic_event::meaning::maybe_get_property_str (m.m_property)) - kinds_arr->append (new json::string (property_str)); + kinds_arr->append_string (property_str); return kinds_arr; } diff --git a/gcc/json.cc b/gcc/json.cc index 53edca520556..86490259dabf 100644 --- a/gcc/json.cc +++ b/gcc/json.cc @@ -286,6 +286,13 @@ array::append (value *v) m_elements.safe_push (v); } +void +array::append_string (const char *utf8_value) +{ + gcc_assert (utf8_value); + append (new json::string (utf8_value)); +} + /* class json::float_number, a subclass of json::value, wrapping a double. */ /* Implementation of json::value::print for json::float_number. */ @@ -432,7 +439,7 @@ test_writing_arrays () arr.append (new json::string ("foo")); ASSERT_PRINT_EQ (arr, true, "[\"foo\"]"); - arr.append (new json::string ("bar")); + arr.append_string ("bar"); ASSERT_PRINT_EQ (arr, true, "[\"foo\",\n" " \"bar\"]"); diff --git a/gcc/json.h b/gcc/json.h index ad4f8c448f8c..d3493a72d525 100644 --- a/gcc/json.h +++ b/gcc/json.h @@ -130,6 +130,7 @@ class array : public value void print (pretty_printer *pp, bool formatted) const final override; void append (value *v); + void append_string (const char *utf8_value); private: auto_vec m_elements; diff --git a/gcc/optinfo-emit-json.cc b/gcc/optinfo-emit-json.cc index 1fa82d438db9..faae95fc232a 100644 --- a/gcc/optinfo-emit-json.cc +++ b/gcc/optinfo-emit-json.cc @@ -259,7 +259,7 @@ optrecord_json_writer::pass_to_json (opt_pass *pass) optgroup->name != NULL; optgroup++) if (optgroup->value != OPTGROUP_ALL && (pass->optinfo_flags & optgroup->value)) - optgroups->append (new json::string (optgroup->name)); + optgroups->append_string (optgroup->name); } obj->set_integer ("num", pass->static_pass_number); return obj; @@ -347,7 +347,7 @@ optrecord_json_writer::optinfo_to_json (const optinfo *optinfo) gcc_unreachable (); case OPTINFO_ITEM_KIND_TEXT: { - message->append (new json::string (item->get_text ())); + message->append_string (item->get_text ()); } break; case OPTINFO_ITEM_KIND_TREE: From patchwork Wed Jul 24 22:18:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964559 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=YDL0aHBh; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpPP5nxzz1yY9 for ; Thu, 25 Jul 2024 08:20:41 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 14A85385DDC3 for ; Wed, 24 Jul 2024 22:20:40 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id A6557385B50D for ; Wed, 24 Jul 2024 22:18:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A6557385B50D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A6557385B50D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859525; cv=none; b=j6Rh4pek/FwPz1k1tl1+IMeMr6bHiKzIZ9Pz+7zdTGXG3gCn7ftTaH9tuY8KheEHrUZ/CMvSY/l43bFvSBNNHQG7So1hQPSYzebPWZXp6h7o9YMz3c/Gq8xWzwUzTCu2CpY+uc/2gHMOyHbhD1w+MkEcmsgtbirpDMjThTV+cGc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859525; c=relaxed/simple; bh=ikHv696ISH5HrNXqnssECJhCuSLXsPSNsWGjf+HSl8c=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=NfeFM2zV46ET0Zet2OojopoiJ4JY7XWqkcOYiUdnMqUNztU201JGOMXWkgdWCr2vgD5ocOwa3ea+O5FaMEwvV6e3QkVSTnYp9FDzLn94fS7Hd2GcDL/ubOhCBk0Q74QYgiY/QLWiR4/ErM9M7YV7eAWIJZxybWGKqjbhIR0+9ck= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859522; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/cioFD0uD9iRiV580MN0pMD655lLe0PI4KBHbCeihgI=; b=YDL0aHBhpl7P0pneCIXu0AoeXTr1c91kF2WEsM3oQFtDnatTurxIxaGSacFou+1h0JjAiY vzJ130SnJT39gBD4n8INqGd8Xyb7/St5qFcSg0AYJObmp5UyV+e7cQU+4IQuCdC5E7o77h UYAm1Ix91aGBZHCVwMqFywsohv6mjxI= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-624-1LMxgeZkNryZ8nJ7K8cvDw-1; Wed, 24 Jul 2024 18:18:41 -0400 X-MC-Unique: 1LMxgeZkNryZ8nJ7K8cvDw-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 55B181955F28 for ; Wed, 24 Jul 2024 22:18:40 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0FBB31955F40; Wed, 24 Jul 2024 22:18:38 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 03/16] analyzer: reduce use of naked "new" for json dumps Date: Wed, 24 Jul 2024 18:18:11 -0400 Message-Id: <20240724221824.585054-4-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org No functional change intended. gcc/analyzer/ChangeLog: * call-string.cc (call_string::to_json): Avoid naked "new". * constraint-manager.cc (bounded_range::set_json_attr): Likewise. (equiv_class::to_json): Likewise. (constraint::to_json): Likewise. (bounded_ranges_constraint::to_json): Likewise. * diagnostic-manager.cc (saved_diagnostic::to_json): Likewise. (saved_diagnostic::maybe_add_sarif_properties): Likewise. * engine.cc (exploded_node::to_json): Likewise. (exploded_edge::to_json): Likewise. * program-point.cc (program_point::to_json): Likewise. * program-state.cc (program_state::to_json): Likewise. * sm.cc (state_machine::to_json): Likewise. * store.cc (binding_cluster::to_json): Likewise. (store::to_json): Likewise. * supergraph.cc (supernode::to_json): Likewise. (superedge::to_json): Likewise. Signed-off-by: David Malcolm --- gcc/analyzer/call-string.cc | 9 +++------ gcc/analyzer/constraint-manager.cc | 12 ++++++------ gcc/analyzer/diagnostic-manager.cc | 14 +++++++------- gcc/analyzer/engine.cc | 13 ++++++------- gcc/analyzer/program-point.cc | 11 ++++------- gcc/analyzer/program-state.cc | 2 +- gcc/analyzer/sm.cc | 2 +- gcc/analyzer/store.cc | 6 +++--- gcc/analyzer/supergraph.cc | 17 ++++++++--------- 9 files changed, 39 insertions(+), 47 deletions(-) diff --git a/gcc/analyzer/call-string.cc b/gcc/analyzer/call-string.cc index 23880e3f5419..c404c09ca0df 100644 --- a/gcc/analyzer/call-string.cc +++ b/gcc/analyzer/call-string.cc @@ -111,12 +111,9 @@ call_string::to_json () const for (const call_string::element_t &e : m_elements) { json::object *e_obj = new json::object (); - e_obj->set ("src_snode_idx", - new json::integer_number (e.m_callee->m_index)); - e_obj->set ("dst_snode_idx", - new json::integer_number (e.m_caller->m_index)); - e_obj->set ("funcname", - new json::string (function_name (e.m_caller->m_fun))); + e_obj->set_integer ("src_snode_idx", e.m_callee->m_index); + e_obj->set_integer ("dst_snode_idx", e.m_caller->m_index); + e_obj->set_string ("funcname", function_name (e.m_caller->m_fun)); arr->append (e_obj); } diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc index 29539060ebdd..62d3b84bb745 100644 --- a/gcc/analyzer/constraint-manager.cc +++ b/gcc/analyzer/constraint-manager.cc @@ -479,7 +479,7 @@ bounded_range::set_json_attr (json::object *obj, const char *name, tree value) pretty_printer pp; pp_format_decoder (&pp) = default_tree_printer; pp_printf (&pp, "%E", value); - obj->set (name, new json::string (pp_formatted_text (&pp))); + obj->set_string (name, pp_formatted_text (&pp)); } @@ -1140,7 +1140,7 @@ equiv_class::to_json () const pretty_printer pp; pp_format_decoder (&pp) = default_tree_printer; pp_printf (&pp, "%qE", m_constant); - ec_obj->set ("constant", new json::string (pp_formatted_text (&pp))); + ec_obj->set_string ("constant", pp_formatted_text (&pp)); } return ec_obj; @@ -1397,9 +1397,9 @@ constraint::to_json () const { json::object *con_obj = new json::object (); - con_obj->set ("lhs", new json::integer_number (m_lhs.as_int ())); - con_obj->set ("op", new json::string (constraint_op_code (m_op))); - con_obj->set ("rhs", new json::integer_number (m_rhs.as_int ())); + con_obj->set_integer ("lhs", m_lhs.as_int ()); + con_obj->set_string ("op", constraint_op_code (m_op)); + con_obj->set_integer ("rhs", m_rhs.as_int ()); return con_obj; } @@ -1485,7 +1485,7 @@ bounded_ranges_constraint::to_json () const { json::object *con_obj = new json::object (); - con_obj->set ("ec", new json::integer_number (m_ec_id.as_int ())); + con_obj->set_integer ("ec", m_ec_id.as_int ()); con_obj->set ("ranges", m_ranges->to_json ()); return con_obj; diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index 51304b0795b6..92e30bd049bd 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -746,17 +746,17 @@ saved_diagnostic::to_json () const json::object *sd_obj = new json::object (); if (m_sm) - sd_obj->set ("sm", new json::string (m_sm->get_name ())); - sd_obj->set ("enode", new json::integer_number (m_enode->m_index)); - sd_obj->set ("snode", new json::integer_number (m_snode->m_index)); + sd_obj->set_string ("sm", m_sm->get_name ()); + sd_obj->set_integer ("enode", m_enode->m_index); + sd_obj->set_integer ("snode", m_snode->m_index); if (m_sval) sd_obj->set ("sval", m_sval->to_json ()); if (m_state) sd_obj->set ("state", m_state->to_json ()); if (m_best_epath) - sd_obj->set ("path_length", new json::integer_number (get_epath_length ())); - sd_obj->set ("pending_diagnostic", new json::string (m_d->get_kind ())); - sd_obj->set ("idx", new json::integer_number (m_idx)); + sd_obj->set_integer ("path_length", get_epath_length ()); + sd_obj->set_string ("pending_diagnostic", m_d->get_kind ()); + sd_obj->set_integer ("idx", m_idx); /* We're not yet JSONifying the following fields: const gimple *m_stmt; @@ -1038,7 +1038,7 @@ saved_diagnostic::maybe_add_sarif_properties (sarif_object &result_obj) const if (m_state) props.set (PROPERTY_PREFIX "state", m_state->to_json ()); if (m_best_epath) - props.set (PROPERTY_PREFIX "idx", new json::integer_number (m_idx)); + props.set_integer (PROPERTY_PREFIX "idx", m_idx); #undef PROPERTY_PREFIX /* Potentially add pending_diagnostic-specific properties. */ diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index c9f204b13e70..f4239753c91e 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -1449,10 +1449,9 @@ exploded_node::to_json (const extrinsic_state &ext_state) const enode_obj->set ("point", get_point ().to_json ()); enode_obj->set ("state", get_state ().to_json (ext_state)); - enode_obj->set ("status", new json::string (status_to_str (m_status))); - enode_obj->set ("idx", new json::integer_number (m_index)); - enode_obj->set ("processed_stmts", - new json::integer_number (m_num_processed_stmts)); + enode_obj->set_string ("status", status_to_str (m_status)); + enode_obj->set_integer ("idx", m_index); + enode_obj->set_integer ("processed_stmts", m_num_processed_stmts); return enode_obj; } @@ -2298,8 +2297,8 @@ json::object * exploded_edge::to_json () const { json::object *eedge_obj = new json::object (); - eedge_obj->set ("src_idx", new json::integer_number (m_src->m_index)); - eedge_obj->set ("dst_idx", new json::integer_number (m_dest->m_index)); + eedge_obj->set_integer ("src_idx", m_src->m_index); + eedge_obj->set_integer ("dst_idx", m_dest->m_index); if (m_sedge) eedge_obj->set ("sedge", m_sedge->to_json ()); if (m_custom_info) @@ -2307,7 +2306,7 @@ exploded_edge::to_json () const pretty_printer pp; pp_format_decoder (&pp) = default_tree_printer; m_custom_info->print (&pp); - eedge_obj->set ("custom", new json::string (pp_formatted_text (&pp))); + eedge_obj->set_string ("custom", pp_formatted_text (&pp)); } return eedge_obj; } diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc index ea15ccc91d27..8e0a3a0e3be1 100644 --- a/gcc/analyzer/program-point.cc +++ b/gcc/analyzer/program-point.cc @@ -319,23 +319,20 @@ program_point::to_json () const { json::object *point_obj = new json::object (); - point_obj->set ("kind", - new json::string (point_kind_to_string (get_kind ()))); + point_obj->set_string ("kind", point_kind_to_string (get_kind ())); if (get_supernode ()) - point_obj->set ("snode_idx", - new json::integer_number (get_supernode ()->m_index)); + point_obj->set_integer ("snode_idx", get_supernode ()->m_index); switch (get_kind ()) { default: break; case PK_BEFORE_SUPERNODE: if (const superedge *sedge = get_from_edge ()) - point_obj->set ("from_edge_snode_idx", - new json::integer_number (sedge->m_src->m_index)); + point_obj->set_integer ("from_edge_snode_idx", sedge->m_src->m_index); break; case PK_BEFORE_STMT: - point_obj->set ("stmt_idx", new json::integer_number (get_stmt_idx ())); + point_obj->set_integer ("stmt_idx", get_stmt_idx ()); break; } diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc index c42fc752350a..b975184d33e6 100644 --- a/gcc/analyzer/program-state.cc +++ b/gcc/analyzer/program-state.cc @@ -1223,7 +1223,7 @@ program_state::to_json (const extrinsic_state &ext_state) const state_obj->set ("checkers", checkers_obj); } - state_obj->set ("valid", new json::literal (m_valid)); + state_obj->set_bool ("valid", m_valid); return state_obj; } diff --git a/gcc/analyzer/sm.cc b/gcc/analyzer/sm.cc index f23a94b62438..f8b21b85db03 100644 --- a/gcc/analyzer/sm.cc +++ b/gcc/analyzer/sm.cc @@ -156,7 +156,7 @@ state_machine::to_json () const { json::object *sm_obj = new json::object (); - sm_obj->set ("name", new json::string (m_name)); + sm_obj->set_string ("name", m_name); { json::array *states_arr = new json::array (); unsigned i; diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index 284866c7effc..c6c17b58d5c7 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -1444,8 +1444,8 @@ binding_cluster::to_json () const { json::object *cluster_obj = new json::object (); - cluster_obj->set ("escaped", new json::literal (m_escaped)); - cluster_obj->set ("touched", new json::literal (m_touched)); + cluster_obj->set_bool ("escaped", m_escaped); + cluster_obj->set_bool ("touched", m_touched); cluster_obj->set ("map", m_map.to_json ()); return cluster_obj; @@ -2705,7 +2705,7 @@ store::to_json () const store_obj->set (parent_reg_desc.get (), clusters_in_parent_reg_obj); } - store_obj->set ("called_unknown_fn", new json::literal (m_called_unknown_fn)); + store_obj->set_bool ("called_unknown_fn", m_called_unknown_fn); return store_obj; } diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc index 20c62856d4b6..68d83bb914a7 100644 --- a/gcc/analyzer/supergraph.cc +++ b/gcc/analyzer/supergraph.cc @@ -723,18 +723,17 @@ supernode::to_json () const { json::object *snode_obj = new json::object (); - snode_obj->set ("idx", new json::integer_number (m_index)); - snode_obj->set ("bb_idx", new json::integer_number (m_bb->index)); + snode_obj->set_integer ("idx", m_index); + snode_obj->set_integer ("bb_idx", m_bb->index); if (function *fun = get_function ()) - snode_obj->set ("fun", new json::string (function_name (fun))); + snode_obj->set_string ("fun", function_name (fun)); if (m_returning_call) { pretty_printer pp; pp_format_decoder (&pp) = default_tree_printer; pp_gimple_stmt_1 (&pp, m_returning_call, 0, (dump_flags_t)0); - snode_obj->set ("returning_call", - new json::string (pp_formatted_text (&pp))); + snode_obj->set_string ("returning_call", pp_formatted_text (&pp)); } /* Phi nodes. */ @@ -990,15 +989,15 @@ json::object * superedge::to_json () const { json::object *sedge_obj = new json::object (); - sedge_obj->set ("kind", new json::string (edge_kind_to_string (m_kind))); - sedge_obj->set ("src_idx", new json::integer_number (m_src->m_index)); - sedge_obj->set ("dst_idx", new json::integer_number (m_dest->m_index)); + sedge_obj->set_string ("kind", edge_kind_to_string (m_kind)); + sedge_obj->set_integer ("src_idx", m_src->m_index); + sedge_obj->set_integer ("dst_idx", m_dest->m_index); { pretty_printer pp; pp_format_decoder (&pp) = default_tree_printer; dump_label_to_pp (&pp, false); - sedge_obj->set ("desc", new json::string (pp_formatted_text (&pp))); + sedge_obj->set_string ("desc", pp_formatted_text (&pp)); } return sedge_obj; From patchwork Wed Jul 24 22:18:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964560 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=DKT/X6Zu; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpPS6NHFz1yY9 for ; Thu, 25 Jul 2024 08:20:44 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1EC08385E45B for ; Wed, 24 Jul 2024 22:20:43 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id DC808385C6CF for ; Wed, 24 Jul 2024 22:18:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DC808385C6CF Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DC808385C6CF Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859527; cv=none; b=okMEB6m8iVZwJQ/ySOVC6iImiVIoztaLDA+VT1cgKNbNIDhMtd0tJVQcEbC0/G+DPuSHPSo4NJ9m54bs1h9x+4TF7QTOe04jcSDkGHPS5ANWtxKg+qWaXWXSD7UwnmRDq7risrhxmfEy5G+PYJux/H/3d0uKdW/VTYjwmnRTFOk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859527; c=relaxed/simple; bh=HBHHrDARg8n9BdB3xNJ0s+ZGbU1Ef2B8NLouKJuR8gM=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=q8CVrwbbFGJp3TYPlgK1ErHJw7s9DVEpViCI06QZN6aKWzwTWdb+wYB+jPFqxEXhXv1qyZaCx+XrIu2tNNCKRrQowc/PQ0FvPYwO0TBgl86hIgRDFOeq2VY+d8TThR4AkgZXSuDFqLKxpcUhDkOs1X/Ri17B4DKuUBkjBupqoDc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859524; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TPchOibo337dQlHaAVW5+YnTRAlLavl1aNmD4qJp9A0=; b=DKT/X6Zu7HsrnsgGSZc3JtzlLbDRKqDP2efINgmQ26+Z4CCsMMch8+jH+GHaw+crqTIEaZ iuLG3j0FOmrl4ptQNyIk+jcZ8XYWKsfgspx8b8cPSU9N4aYoQosAvS7s4BUv5Ew55DbTfR foc5eFCdtbLagcWfpBKXU/p80djf7XE= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-618-X_WIatl-NqKPURl2pycHSw-1; Wed, 24 Jul 2024 18:18:43 -0400 X-MC-Unique: X_WIatl-NqKPURl2pycHSw-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C13611955F56 for ; Wed, 24 Jul 2024 22:18:41 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5B27C1955F40; Wed, 24 Jul 2024 22:18:40 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 04/16] gcov: reduce use of naked "new" for json output Date: Wed, 24 Jul 2024 18:18:12 -0400 Message-Id: <20240724221824.585054-5-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org No functional change intended. gcc/ChangeLog: * gcov.cc (output_intermediate_json_line): Use json::object::set_integer to avoid naked "new". Signed-off-by: David Malcolm --- gcc/gcov.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/gcov.cc b/gcc/gcov.cc index e76a314041cd..85fdac4368e8 100644 --- a/gcc/gcov.cc +++ b/gcc/gcov.cc @@ -1285,8 +1285,8 @@ output_intermediate_json_line (json::array *object, const int covered = info.popcount (); json::object *cond = new json::object (); - cond->set ("count", new json::integer_number (count)); - cond->set ("covered", new json::integer_number (covered)); + cond->set_integer ("count", count); + cond->set_integer ("covered", covered); json::array *mtrue = new json::array (); json::array *mfalse = new json::array (); From patchwork Wed Jul 24 22:18:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964558 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=TJapSAT9; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpNG68fkz1ybY for ; Thu, 25 Jul 2024 08:19:42 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1B9E4385DDD4 for ; Wed, 24 Jul 2024 22:19:41 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 83EA8385DDC8 for ; Wed, 24 Jul 2024 22:18:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 83EA8385DDC8 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 83EA8385DDC8 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859537; cv=none; b=vOtiDq1nmOnHPpxnAC8L2lLkTy3Eh6KyvZXLemPpqpWZENin8wI/WTxOtcM/twZ5wxeUuUO1T+3z4oHlQDn7+8iQpuWk3ca20uhF6gEtggMZhFYM2QYAzURkFbozjUvK2swwaejyQYY501WYvRltCaEPaOJyPuMffbgJ9rMN3Tw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859537; c=relaxed/simple; bh=RgImSeuSMSHcGldyqD0oa/KlsodwlWXptBestt0RG74=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=WZ7KwZYnbZgAZdDCHyF5ReHuIH8S/xYN2ZeNeWkXCHUXtk7Yk7Hs8MfJTWW3pfNuKWC+7PJxy59QpHLDsuRMnIPkbV8RiJJszR3RqFrzOXB6WoST0V2EIYBt5NNpUL+ib0bIJlSh7NlJl0WeLaShD9IqTLFGKcCvYGtzDhEoIYg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859527; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JxN0Y6zKLMzTbw+3zcoTM5UVbu926/Tl3dLSDXqnOVI=; b=TJapSAT9isdJEe5FBkaW0c9h6blzdIYjUiku6CvYjm5t0FuTCMjNvGCx57DAnU9Ge2oe1X 00q8hQSuj7npPbA16NDVVqUUF3ri+Rex8Rj25fTtJXdGBAcn0qOb7BTVAImlooKMqg0n6c ND9nNUqg73nrduafj96XVXnBftU/6eY= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-463-rTMh3UWGMEm9GXQui5wdvg-1; Wed, 24 Jul 2024 18:18:45 -0400 X-MC-Unique: rTMh3UWGMEm9GXQui5wdvg-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 62CF41955D58 for ; Wed, 24 Jul 2024 22:18:44 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9CC991955F3B; Wed, 24 Jul 2024 22:18:41 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 05/16] diagnostics: SARIF output: add sarif_object subclasses throughout Date: Wed, 24 Jul 2024 18:18:13 -0400 Message-Id: <20240724221824.585054-6-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_FILL_THIS_FORM_SHORT, URIBL_SBL_A autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org No functional change intended. gcc/ChangeLog: * diagnostic-format-sarif.cc: Introduce subclasses of sarif_object for all aspects of the spec that we're using. Replace almost all usage of json::object with uses of these subclasses, the only remaining use of json::object being for originalUriBaseIds, as per SARIF 2.1.0 §3.14.14. This stronger typing makes it considerably easier to maintain validity against the schema. * diagnostic-format-sarif.h (class sarif_logical_location): New. (make_sarif_logical_location_object): Convert return type from json::object * to sarif_logical_location *. Signed-off-by: David Malcolm --- gcc/diagnostic-format-sarif.cc | 605 +++++++++++++++++++++------------ gcc/diagnostic-format-sarif.h | 9 +- 2 files changed, 399 insertions(+), 215 deletions(-) diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 7105f7853318..c35d8788d6de 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -36,18 +36,87 @@ along with GCC; see the file COPYING3. If not see #include "ordered-hash-map.h" #include "sbitmap.h" +/* Forward decls. */ class sarif_builder; -/* Subclass of json::object for SARIF invocation objects +/* Subclasses of sarif_object. + Keep these in order of their descriptions in the specification. */ +class sarif_artifact_content; // 3.3 +class sarif_artifact_location; // 3.4 +class sarif_message; // 3.11 +class sarif_multiformat_message_string; // 3.12 +class sarif_log; // 3.13 +class sarif_run; // 3.14 +class sarif_tool; // 3.18 +class sarif_tool_component; // 3.19 +class sarif_invocation; // 3.20 +class sarif_artifact; // 3.24 +class sarif_result; // 3.27 +class sarif_location; // 3.28 +class sarif_physical_location; // 3.29 +class sarif_region; // 3.30 +class sarif_logical_location; // 3.33 +class sarif_code_flow; // 3.36 +class sarif_thread_flow; // 3.37 +class sarif_thread_flow_location; // 3.38 +class sarif_reporting_descriptor; // 3.49 +class sarif_reporting_descriptor_reference; // 3.53 +class sarif_tool_component_reference; // 3.54 +class sarif_fix; // 3.55 +class sarif_artifact_change; // 3.56 +class sarif_replacement; // 3.57 +class sarif_ice_notification; // 3.58 + +/* Declarations of subclasses of sarif_object. + Keep these in order of their descriptions in the specification. */ + +/* Subclass of sarif_object for SARIF "artifactContent" objects + (SARIF v2.1.0 section 3.3). */ + +class sarif_artifact_content : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "artifactLocation" objects + (SARIF v2.1.0 section 3.4). */ + +class sarif_artifact_location : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "message" objects + (SARIF v2.1.0 section 3.11). */ + +class sarif_message : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "multiformatMessageString" objects + (SARIF v2.1.0 section 3.12). */ + +class sarif_multiformat_message_string : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "log" objects + (SARIF v2.1.0 section 3.13). */ + +class sarif_log : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "run" objects + (SARIF v2.1.0 section 3.14). */ + +class sarif_run : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "tool" objects + (SARIF v2.1.0 section 3.18). */ + +class sarif_tool : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "toolComponent" objects + (SARIF v2.1.0 section 3.19). */ + +class sarif_tool_component : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "invocation" objects (SARIF v2.1.0 section 3.20). */ class sarif_invocation : public sarif_object { public: - sarif_invocation () - : m_notifications_arr (new json::array ()), - m_success (true) - {} + sarif_invocation (); void add_notification_for_ice (diagnostic_context *context, const diagnostic_info &diagnostic, @@ -104,7 +173,7 @@ private: bool m_embed_contents; }; -/* Subclass of sarif_object for SARIF result objects +/* Subclass of sarif_object for SARIF "result" objects (SARIF v2.1.0 section 3.27). */ class sarif_result : public sarif_object @@ -122,42 +191,95 @@ public: sarif_builder *builder); private: - void add_related_location (json::object *location_obj); + void + add_related_location (sarif_location *location_obj); json::array *m_related_locations_arr; }; -/* Subclass of sarif_object for SARIF notification objects - (SARIF v2.1.0 section 3.58). +/* Subclass of sarif_object for SARIF "location" objects + (SARIF v2.1.0 section 3.28). */ - This subclass is specifically for notifying when an - internal compiler error occurs. */ +class sarif_location : public sarif_object {}; -class sarif_ice_notification : public sarif_object -{ -public: - sarif_ice_notification (diagnostic_context *context, - const diagnostic_info &diagnostic, - sarif_builder *builder); -}; +/* Subclass of sarif_object for SARIF "physicalLocation" objects + (SARIF v2.1.0 section 3.29). */ + +class sarif_physical_location : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "region" objects + (SARIF v2.1.0 section 3.30). */ + +class sarif_region : public sarif_object {}; -/* Subclass of sarif_object for SARIF threadFlow objects - (SARIF v2.1.0 section 3.37) for PATH. */ +/* Subclass of sarif_object for SARIF "codeFlow" objects + (SARIF v2.1.0 section 3.36). */ + +class sarif_code_flow : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "threadFlow" objects + (SARIF v2.1.0 section 3.37). */ class sarif_thread_flow : public sarif_object { public: sarif_thread_flow (const diagnostic_thread &thread); - void add_location (json::object *thread_flow_loc_obj) - { - m_locations_arr->append (thread_flow_loc_obj); - } + void add_location (sarif_thread_flow_location *thread_flow_loc_obj); private: json::array *m_locations_arr; }; +/* Subclass of sarif_object for SARIF "threadFlowLocation" objects + (SARIF v2.1.0 section 3.38). */ + +class sarif_thread_flow_location : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "reportingDescriptor" objects + (SARIF v2.1.0 section 3.49). */ + +class sarif_reporting_descriptor : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "reportingDescriptorReference" objects + (SARIF v2.1.0 section 3.53). */ + +class sarif_reporting_descriptor_reference : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "toolComponentReference" objects + (SARIF v2.1.0 section 3.54). */ + +class sarif_tool_component_reference : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "fix" objects + (SARIF v2.1.0 section 3.55). */ + +class sarif_fix : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "artifactChange" objects + (SARIF v2.1.0 section 3.56). */ + +class sarif_artifact_change : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "replacement" objects + (SARIF v2.1.0 section 3.57). */ + +class sarif_replacement : public sarif_object {}; + +/* Subclass of sarif_object for SARIF "notification" objects + (SARIF v2.1.0 section 3.58). + + This subclass is specifically for notifying when an + internal compiler error occurs. */ + +class sarif_ice_notification : public sarif_object +{ +public: + sarif_ice_notification (diagnostic_context *context, + const diagnostic_info &diagnostic, + sarif_builder *builder); +}; + /* A class for managing SARIF output (for -fdiagnostics-format=sarif-stderr and -fdiagnostics-format=sarif-file). @@ -219,70 +341,99 @@ public: json::array *make_locations_arr (const diagnostic_info &diagnostic, enum diagnostic_artifact_role role); - json::object *make_location_object (const rich_location &rich_loc, - const logical_location *logical_loc, - enum diagnostic_artifact_role role); - json::object *make_message_object (const char *msg) const; - json::object * + sarif_location * + make_location_object (const rich_location &rich_loc, + const logical_location *logical_loc, + enum diagnostic_artifact_role role); + sarif_message * + make_message_object (const char *msg) const; + sarif_message * make_message_object_for_diagram (diagnostic_context *context, const diagnostic_diagram &diagram); - json::object *maybe_make_artifact_content_object (const char *filename) const; + sarif_artifact_content * + maybe_make_artifact_content_object (const char *filename) const; private: - sarif_result *make_result_object (diagnostic_context *context, - const diagnostic_info &diagnostic, - diagnostic_t orig_diag_kind); - void set_any_logical_locs_arr (json::object *location_obj, - const logical_location *logical_loc); - json::object *make_location_object (const diagnostic_event &event, - enum diagnostic_artifact_role role); - json::object *make_code_flow_object (const diagnostic_path &path); - json::object * + sarif_result * + make_result_object (diagnostic_context *context, + const diagnostic_info &diagnostic, + diagnostic_t orig_diag_kind); + void + set_any_logical_locs_arr (sarif_location *location_obj, + const logical_location *logical_loc); + sarif_location * + make_location_object (const diagnostic_event &event, + enum diagnostic_artifact_role role); + sarif_code_flow * + make_code_flow_object (const diagnostic_path &path); + sarif_thread_flow_location * make_thread_flow_location_object (const diagnostic_event &event, int path_event_idx); - json::array *maybe_make_kinds_array (diagnostic_event::meaning m) const; - json::object * + json::array * + maybe_make_kinds_array (diagnostic_event::meaning m) const; + sarif_physical_location * maybe_make_physical_location_object (location_t loc, enum diagnostic_artifact_role role, int column_override); - json::object *make_artifact_location_object (location_t loc); - json::object *make_artifact_location_object (const char *filename); - json::object *make_artifact_location_object_for_pwd () const; - json::object *maybe_make_region_object (location_t loc, - int column_override) const; - json::object *maybe_make_region_object_for_context (location_t loc) const; - json::object *make_region_object_for_hint (const fixit_hint &hint) const; - json::object *make_multiformat_message_string (const char *msg) const; - json::object *make_top_level_object (sarif_invocation *invocation_obj, - json::array *results); - json::object *make_run_object (sarif_invocation *invocation_obj, - json::array *results); - json::object *make_tool_object () const; - json::object *make_driver_tool_component_object () const; + sarif_artifact_location * + make_artifact_location_object (location_t loc); + sarif_artifact_location * + make_artifact_location_object (const char *filename); + sarif_artifact_location * + make_artifact_location_object_for_pwd () const; + sarif_region * + maybe_make_region_object (location_t loc, + int column_override) const; + sarif_region * + maybe_make_region_object_for_context (location_t loc) const; + sarif_region * + make_region_object_for_hint (const fixit_hint &hint) const; + sarif_multiformat_message_string * + make_multiformat_message_string (const char *msg) const; + sarif_log * + make_top_level_object (sarif_invocation *invocation_obj, + json::array *results); + sarif_run * + make_run_object (sarif_invocation *invocation_obj, + json::array *results); + sarif_tool * + make_tool_object () const; + sarif_tool_component * + make_driver_tool_component_object () const; json::array *maybe_make_taxonomies_array () const; - json::object *maybe_make_cwe_taxonomy_object () const; - json::object *make_tool_component_reference_object_for_cwe () const; - json::object * + sarif_tool_component * + maybe_make_cwe_taxonomy_object () const; + sarif_tool_component_reference * + make_tool_component_reference_object_for_cwe () const; + sarif_reporting_descriptor * make_reporting_descriptor_object_for_warning (diagnostic_context *context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind, const char *option_text); - json::object *make_reporting_descriptor_object_for_cwe_id (int cwe_id) const; - json::object * + sarif_reporting_descriptor * + make_reporting_descriptor_object_for_cwe_id (int cwe_id) const; + sarif_reporting_descriptor_reference * make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id); - sarif_artifact &get_or_create_artifact (const char *filename, - enum diagnostic_artifact_role role, - bool embed_contents); - char *get_source_lines (const char *filename, - int start_line, - int end_line) const; - json::object *maybe_make_artifact_content_object (const char *filename, - int start_line, - int end_line) const; - json::object *make_fix_object (const rich_location &rich_loc); - json::object *make_artifact_change_object (const rich_location &richloc); - json::object *make_replacement_object (const fixit_hint &hint) const; - json::object *make_artifact_content_object (const char *text) const; + sarif_artifact & + get_or_create_artifact (const char *filename, + enum diagnostic_artifact_role role, + bool embed_contents); + char * + get_source_lines (const char *filename, + int start_line, + int end_line) const; + sarif_artifact_content * + maybe_make_artifact_content_object (const char *filename, + int start_line, + int end_line) const; + sarif_fix * + make_fix_object (const rich_location &rich_loc); + sarif_artifact_change * + make_artifact_change_object (const rich_location &richloc); + sarif_replacement * + make_replacement_object (const fixit_hint &hint) const; + sarif_artifact_content * + make_artifact_content_object (const char *text) const; int get_sarif_column (expanded_location exploc) const; diagnostic_context *m_context; @@ -330,6 +481,12 @@ sarif_object::get_or_create_properties () /* class sarif_invocation : public sarif_object. */ +sarif_invocation::sarif_invocation () +: m_notifications_arr (new json::array ()), + m_success (true) +{ +} + /* Handle an internal compiler error DIAGNOSTIC occurring on CONTEXT. Add an object representing the ICE to the notifications array. */ @@ -394,7 +551,7 @@ sarif_artifact::add_role (enum diagnostic_artifact_role role, void sarif_artifact::populate_contents (sarif_builder &builder) { - if (json::object *artifact_content_obj + if (sarif_artifact_content *artifact_content_obj = builder.maybe_make_artifact_content_object (m_filename)) set ("contents", artifact_content_obj); } @@ -420,7 +577,7 @@ get_artifact_role_string (enum diagnostic_artifact_role role) } } -/* Populate the "roles" property of this json::object with a new +/* Populate the "roles" property of this sarif_artifact with a new json::array for the artifact.roles property (SARIF v2.1.0 section 3.24.6) containing strings such as "analysisTarget", "resultFile" and/or "tracedFile". */ @@ -457,10 +614,10 @@ sarif_result::on_nested_diagnostic (diagnostic_context *context, /* We don't yet generate meaningful logical locations for notes; sometimes these will related to current_function_decl, but often they won't. */ - json::object *location_obj + sarif_location *location_obj = builder->make_location_object (*diagnostic.richloc, NULL, diagnostic_artifact_role::result_file); - json::object *message_obj + sarif_message *message_obj = builder->make_message_object (pp_formatted_text (context->printer)); pp_clear_output_area (context->printer); location_obj->set ("message", message_obj); @@ -479,8 +636,8 @@ sarif_result::on_diagram (diagnostic_context *context, const diagnostic_diagram &diagram, sarif_builder *builder) { - json::object *location_obj = new json::object (); - json::object *message_obj + sarif_location *location_obj = new sarif_location (); + sarif_message *message_obj = builder->make_message_object_for_diagram (context, diagram); location_obj->set ("message", message_obj); @@ -491,7 +648,7 @@ sarif_result::on_diagram (diagnostic_context *context, creating it if it doesn't yet exist. */ void -sarif_result::add_related_location (json::object *location_obj) +sarif_result::add_related_location (sarif_location *location_obj) { if (!m_related_locations_arr) { @@ -517,7 +674,7 @@ sarif_ice_notification::sarif_ice_notification (diagnostic_context *context, set ("locations", locations_arr); /* "message" property (SARIF v2.1.0 section 3.85.5). */ - json::object *message_obj + sarif_message *message_obj = builder->make_message_object (pp_formatted_text (context->printer)); pp_clear_output_area (context->printer); set ("message", message_obj); @@ -539,6 +696,13 @@ sarif_thread_flow::sarif_thread_flow (const diagnostic_thread &thread) set ("locations", m_locations_arr); } +void +sarif_thread_flow:: +add_location (sarif_thread_flow_location *thread_flow_loc_obj) +{ + m_locations_arr->append (thread_flow_loc_obj); +} + /* class sarif_builder. */ /* sarif_builder's ctor. */ @@ -625,7 +789,7 @@ void sarif_builder::flush_to_file (FILE *outf) { m_invocation_obj->prepare_to_flush (m_context); - json::object *top = make_top_level_object (m_invocation_obj, m_results_array); + sarif_log *top = make_top_level_object (m_invocation_obj, m_results_array); top->dump (outf, m_formatted); m_invocation_obj = NULL; m_results_array = NULL; @@ -673,7 +837,7 @@ make_rule_id_for_diagnostic_kind (diagnostic_t diag_kind) return rstrip; } -/* Make a result object (SARIF v2.1.0 section 3.27) for DIAGNOSTIC. */ +/* Make a "result" object (SARIF v2.1.0 section 3.27) for DIAGNOSTIC. */ sarif_result * sarif_builder::make_result_object (diagnostic_context *context, @@ -699,7 +863,7 @@ sarif_builder::make_result_object (diagnostic_context *context, /* Add to set, taking ownership. */ m_rule_id_set.add (option_text); - json::object *reporting_desc_obj + sarif_reporting_descriptor *reporting_desc_obj = make_reporting_descriptor_object_for_warning (context, diagnostic, orig_diag_kind, @@ -724,7 +888,7 @@ sarif_builder::make_result_object (diagnostic_context *context, if (int cwe_id = diagnostic.metadata->get_cwe ()) { json::array *taxa_arr = new json::array (); - json::object *cwe_id_obj + sarif_reporting_descriptor_reference *cwe_id_obj = make_reporting_descriptor_reference_object_for_cwe_id (cwe_id); taxa_arr->append (cwe_id_obj); result_obj->set ("taxa", taxa_arr); @@ -738,7 +902,7 @@ sarif_builder::make_result_object (diagnostic_context *context, result_obj->set_string ("level", sarif_level); /* "message" property (SARIF v2.1.0 section 3.27.11). */ - json::object *message_obj + sarif_message *message_obj = make_message_object (pp_formatted_text (context->printer)); pp_clear_output_area (context->printer); result_obj->set ("message", message_obj); @@ -753,7 +917,7 @@ sarif_builder::make_result_object (diagnostic_context *context, if (const diagnostic_path *path = diagnostic.richloc->get_path ()) { json::array *code_flows_arr = new json::array (); - json::object *code_flow_obj = make_code_flow_object (*path); + sarif_code_flow *code_flow_obj = make_code_flow_object (*path); code_flows_arr->append (code_flow_obj); result_obj->set ("codeFlows", code_flows_arr); } @@ -767,7 +931,7 @@ sarif_builder::make_result_object (diagnostic_context *context, if (richloc->get_num_fixit_hints ()) { json::array *fix_arr = new json::array (); - json::object *fix_obj = make_fix_object (*richloc); + sarif_fix *fix_obj = make_fix_object (*richloc); fix_arr->append (fix_obj); result_obj->set ("fixes", fix_arr); } @@ -775,17 +939,18 @@ sarif_builder::make_result_object (diagnostic_context *context, return result_obj; } -/* Make a reportingDescriptor object (SARIF v2.1.0 section 3.49) +/* Make a "reportingDescriptor" object (SARIF v2.1.0 section 3.49) for a GCC warning. */ -json::object * +sarif_reporting_descriptor * sarif_builder:: make_reporting_descriptor_object_for_warning (diagnostic_context *context, const diagnostic_info &diagnostic, diagnostic_t /*orig_diag_kind*/, const char *option_text) { - json::object *reporting_desc = new json::object (); + sarif_reporting_descriptor *reporting_desc + = new sarif_reporting_descriptor (); /* "id" property (SARIF v2.1.0 section 3.49.3). */ reporting_desc->set_string ("id", option_text); @@ -803,13 +968,14 @@ make_reporting_descriptor_object_for_warning (diagnostic_context *context, return reporting_desc; } -/* Make a reportingDescriptor object (SARIF v2.1.0 section 3.49) +/* Make a "reportingDescriptor" object (SARIF v2.1.0 section 3.49) for CWE_ID, for use within the CWE taxa array. */ -json::object * +sarif_reporting_descriptor * sarif_builder::make_reporting_descriptor_object_for_cwe_id (int cwe_id) const { - json::object *reporting_desc = new json::object (); + sarif_reporting_descriptor *reporting_desc + = new sarif_reporting_descriptor (); /* "id" property (SARIF v2.1.0 section 3.49.3). */ { @@ -828,15 +994,16 @@ sarif_builder::make_reporting_descriptor_object_for_cwe_id (int cwe_id) const return reporting_desc; } -/* Make a reportingDescriptorReference object (SARIF v2.1.0 section 3.52) +/* Make a "reportingDescriptorReference" object (SARIF v2.1.0 section 3.52) referencing CWE_ID, for use within a result object. Also, add CWE_ID to m_cwe_id_set. */ -json::object * +sarif_reporting_descriptor_reference * sarif_builder:: make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id) { - json::object *desc_ref_obj = new json::object (); + sarif_reporting_descriptor_reference *desc_ref_obj + = new sarif_reporting_descriptor_reference (); /* "id" property (SARIF v2.1.0 section 3.52.4). */ { @@ -846,7 +1013,8 @@ make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id) } /* "toolComponent" property (SARIF v2.1.0 section 3.52.7). */ - json::object *comp_ref_obj = make_tool_component_reference_object_for_cwe (); + sarif_tool_component_reference *comp_ref_obj + = make_tool_component_reference_object_for_cwe (); desc_ref_obj->set ("toolComponent", comp_ref_obj); /* Add CWE_ID to our set. */ @@ -856,14 +1024,15 @@ make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id) return desc_ref_obj; } -/* Make a toolComponentReference object (SARIF v2.1.0 section 3.54) that +/* Make a "toolComponentReference" object (SARIF v2.1.0 section 3.54) that references the CWE taxonomy. */ -json::object * +sarif_tool_component_reference * sarif_builder:: make_tool_component_reference_object_for_cwe () const { - json::object *comp_ref_obj = new json::object (); + sarif_tool_component_reference *comp_ref_obj + = new sarif_tool_component_reference (); /* "name" property (SARIF v2.1.0 section 3.54.3). */ comp_ref_obj->set_string ("name", "cwe"); @@ -884,7 +1053,7 @@ sarif_builder::make_locations_arr (const diagnostic_info &diagnostic, if (auto client_data_hooks = m_context->get_client_data_hooks ()) logical_loc = client_data_hooks->get_current_logical_location (); - json::object *location_obj + sarif_location *location_obj = make_location_object (*diagnostic.richloc, logical_loc, role); locations_arr->append (location_obj); return locations_arr; @@ -895,32 +1064,33 @@ sarif_builder::make_locations_arr (const diagnostic_info &diagnostic, void sarif_builder:: -set_any_logical_locs_arr (json::object *location_obj, +set_any_logical_locs_arr (sarif_location *location_obj, const logical_location *logical_loc) { if (!logical_loc) return; - json::object *logical_loc_obj = make_sarif_logical_location_object (*logical_loc); + sarif_logical_location *logical_loc_obj + = make_sarif_logical_location_object (*logical_loc); json::array *location_locs_arr = new json::array (); location_locs_arr->append (logical_loc_obj); location_obj->set ("logicalLocations", location_locs_arr); } -/* Make a location object (SARIF v2.1.0 section 3.28) for RICH_LOC +/* Make a "location" object (SARIF v2.1.0 section 3.28) for RICH_LOC and LOGICAL_LOC. */ -json::object * +sarif_location * sarif_builder::make_location_object (const rich_location &rich_loc, const logical_location *logical_loc, enum diagnostic_artifact_role role) { - json::object *location_obj = new json::object (); + sarif_location *location_obj = new sarif_location (); /* Get primary loc from RICH_LOC. */ location_t loc = rich_loc.get_loc (); /* "physicalLocation" property (SARIF v2.1.0 section 3.28.3). */ - if (json::object *phs_loc_obj + if (sarif_physical_location *phs_loc_obj = maybe_make_physical_location_object (loc, role, rich_loc.get_column_override ())) location_obj->set ("physicalLocation", phs_loc_obj); @@ -931,18 +1101,18 @@ sarif_builder::make_location_object (const rich_location &rich_loc, return location_obj; } -/* Make a location object (SARIF v2.1.0 section 3.28) for EVENT +/* Make a "location" object (SARIF v2.1.0 section 3.28) for EVENT within a diagnostic_path. */ -json::object * +sarif_location * sarif_builder::make_location_object (const diagnostic_event &event, enum diagnostic_artifact_role role) { - json::object *location_obj = new json::object (); + sarif_location *location_obj = new sarif_location (); /* "physicalLocation" property (SARIF v2.1.0 section 3.28.3). */ location_t loc = event.get_location (); - if (json::object *phs_loc_obj + if (sarif_physical_location *phs_loc_obj = maybe_make_physical_location_object (loc, role, 0)) location_obj->set ("physicalLocation", phs_loc_obj); @@ -952,13 +1122,13 @@ sarif_builder::make_location_object (const diagnostic_event &event, /* "message" property (SARIF v2.1.0 section 3.28.5). */ label_text ev_desc = event.get_desc (false); - json::object *message_obj = make_message_object (ev_desc.get ()); + sarif_message *message_obj = make_message_object (ev_desc.get ()); location_obj->set ("message", message_obj); return location_obj; } -/* Make a physicalLocation object (SARIF v2.1.0 section 3.29) for LOC. +/* Make a "physicalLocation" object (SARIF v2.1.0 section 3.29) for LOC. If COLUMN_OVERRIDE is non-zero, then use it as the column number if LOC has no column information. @@ -967,7 +1137,7 @@ sarif_builder::make_location_object (const diagnostic_event &event, and flagging that we will attempt to embed the contents of the artifact when writing it out. */ -json::object * +sarif_physical_location * sarif_builder:: maybe_make_physical_location_object (location_t loc, enum diagnostic_artifact_role role, @@ -976,20 +1146,21 @@ maybe_make_physical_location_object (location_t loc, if (loc <= BUILTINS_LOCATION || LOCATION_FILE (loc) == NULL) return NULL; - json::object *phys_loc_obj = new json::object (); + sarif_physical_location *phys_loc_obj = new sarif_physical_location (); /* "artifactLocation" property (SARIF v2.1.0 section 3.29.3). */ - json::object *artifact_loc_obj = make_artifact_location_object (loc); + sarif_artifact_location *artifact_loc_obj + = make_artifact_location_object (loc); phys_loc_obj->set ("artifactLocation", artifact_loc_obj); get_or_create_artifact (LOCATION_FILE (loc), role, true); /* "region" property (SARIF v2.1.0 section 3.29.4). */ - if (json::object *region_obj = maybe_make_region_object (loc, + if (sarif_region *region_obj = maybe_make_region_object (loc, column_override)) phys_loc_obj->set ("region", region_obj); /* "contextRegion" property (SARIF v2.1.0 section 3.29.5). */ - if (json::object *context_region_obj + if (sarif_region *context_region_obj = maybe_make_region_object_for_context (loc)) phys_loc_obj->set ("contextRegion", context_region_obj); @@ -1000,10 +1171,10 @@ maybe_make_physical_location_object (location_t loc, return phys_loc_obj; } -/* Make an artifactLocation object (SARIF v2.1.0 section 3.4) for LOC, +/* Make an "artifactLocation" object (SARIF v2.1.0 section 3.4) for LOC, or return NULL. */ -json::object * +sarif_artifact_location * sarif_builder::make_artifact_location_object (location_t loc) { return make_artifact_location_object (LOCATION_FILE (loc)); @@ -1014,13 +1185,13 @@ sarif_builder::make_artifact_location_object (location_t loc) #define PWD_PROPERTY_NAME ("PWD") -/* Make an artifactLocation object (SARIF v2.1.0 section 3.4) for FILENAME, +/* Make an "artifactLocation" object (SARIF v2.1.0 section 3.4) for FILENAME, or return NULL. */ -json::object * +sarif_artifact_location * sarif_builder::make_artifact_location_object (const char *filename) { - json::object *artifact_loc_obj = new json::object (); + sarif_artifact_location *artifact_loc_obj = new sarif_artifact_location (); /* "uri" property (SARIF v2.1.0 section 3.4.3). */ artifact_loc_obj->set_string ("uri", filename); @@ -1059,14 +1230,14 @@ make_pwd_uri_str () } } -/* Make an artifactLocation object (SARIF v2.1.0 section 3.4) for the pwd, +/* Make an "artifactLocation" object (SARIF v2.1.0 section 3.4) for the pwd, for use in the "run.originalUriBaseIds" property (SARIF v2.1.0 section 3.14.14) when we have any relative paths. */ -json::object * +sarif_artifact_location * sarif_builder::make_artifact_location_object_for_pwd () const { - json::object *artifact_loc_obj = new json::object (); + sarif_artifact_location *artifact_loc_obj = new sarif_artifact_location (); /* "uri" property (SARIF v2.1.0 section 3.4.3). */ if (char *pwd = make_pwd_uri_str ()) @@ -1090,13 +1261,13 @@ sarif_builder::get_sarif_column (expanded_location exploc) const exploc, policy); } -/* Make a region object (SARIF v2.1.0 section 3.30) for LOC, +/* Make a "region" object (SARIF v2.1.0 section 3.30) for LOC, or return NULL. If COLUMN_OVERRIDE is non-zero, then use it as the column number if LOC has no column information. */ -json::object * +sarif_region * sarif_builder::maybe_make_region_object (location_t loc, int column_override) const { @@ -1117,7 +1288,7 @@ sarif_builder::maybe_make_region_object (location_t loc, if (exploc_finish.file !=exploc_caret.file) return NULL; - json::object *region_obj = new json::object (); + sarif_region *region_obj = new sarif_region (); /* "startLine" property (SARIF v2.1.0 section 3.30.5) */ if (exploc_start.line > 0) @@ -1158,15 +1329,15 @@ sarif_builder::maybe_make_region_object (location_t loc, return region_obj; } -/* Make a region object (SARIF v2.1.0 section 3.30) for the "contextRegion" - property (SARIF v2.1.0 section 3.29.5) of a physicalLocation. +/* Make a "region" object (SARIF v2.1.0 section 3.30) for the "contextRegion" + property (SARIF v2.1.0 section 3.29.5) of a "physicalLocation". This is similar to maybe_make_region_object, but ignores column numbers, covering the line(s) as a whole, and including a "snippet" property embedding those source lines, making it easier for consumers to show the pertinent source. */ -json::object * +sarif_region * sarif_builder::maybe_make_region_object_for_context (location_t loc) const { location_t caret_loc = get_pure_location (loc); @@ -1186,7 +1357,7 @@ sarif_builder::maybe_make_region_object_for_context (location_t loc) const if (exploc_finish.file !=exploc_caret.file) return NULL; - json::object *region_obj = new json::object (); + sarif_region *region_obj = new sarif_region (); /* "startLine" property (SARIF v2.1.0 section 3.30.5) */ if (exploc_start.line > 0) @@ -1198,19 +1369,19 @@ sarif_builder::maybe_make_region_object_for_context (location_t loc) const region_obj->set_integer ("endLine", exploc_finish.line); /* "snippet" property (SARIF v2.1.0 section 3.30.13). */ - if (json::object *artifact_content_obj - = maybe_make_artifact_content_object (exploc_start.file, - exploc_start.line, - exploc_finish.line)) + if (sarif_artifact_content *artifact_content_obj + = maybe_make_artifact_content_object (exploc_start.file, + exploc_start.line, + exploc_finish.line)) region_obj->set ("snippet", artifact_content_obj); return region_obj; } -/* Make a region object (SARIF v2.1.0 section 3.30) for the deletion region +/* Make a "region" object (SARIF v2.1.0 section 3.30) for the deletion region of HINT (as per SARIF v2.1.0 section 3.57.3). */ -json::object * +sarif_region * sarif_builder::make_region_object_for_hint (const fixit_hint &hint) const { location_t start_loc = hint.get_start_loc (); @@ -1219,7 +1390,7 @@ sarif_builder::make_region_object_for_hint (const fixit_hint &hint) const expanded_location exploc_start = expand_location (start_loc); expanded_location exploc_next = expand_location (next_loc); - json::object *region_obj = new json::object (); + sarif_region *region_obj = new sarif_region (); /* "startLine" property (SARIF v2.1.0 section 3.30.5) */ region_obj->set_integer ("startLine", exploc_start.line); @@ -1273,13 +1444,13 @@ maybe_get_sarif_kind (enum logical_location_kind kind) } } -/* Make a logicalLocation object (SARIF v2.1.0 section 3.33) for LOGICAL_LOC, +/* Make a "logicalLocation" object (SARIF v2.1.0 section 3.33) for LOGICAL_LOC, or return NULL. */ -json::object * +sarif_logical_location * make_sarif_logical_location_object (const logical_location &logical_loc) { - json::object *logical_loc_obj = new json::object (); + sarif_logical_location *logical_loc_obj = new sarif_logical_location (); /* "name" property (SARIF v2.1.0 section 3.33.4). */ if (const char *short_name = logical_loc.get_short_name ()) @@ -1301,12 +1472,12 @@ make_sarif_logical_location_object (const logical_location &logical_loc) return logical_loc_obj; } -/* Make a codeFlow object (SARIF v2.1.0 section 3.36) for PATH. */ +/* Make a "codeFlow" object (SARIF v2.1.0 section 3.36) for PATH. */ -json::object * +sarif_code_flow * sarif_builder::make_code_flow_object (const diagnostic_path &path) { - json::object *code_flow_obj = new json::object (); + sarif_code_flow *code_flow_obj = new sarif_code_flow (); /* "threadFlows" property (SARIF v2.1.0 section 3.36.3). */ json::array *thread_flows_arr = new json::array (); @@ -1332,7 +1503,7 @@ sarif_builder::make_code_flow_object (const diagnostic_path &path) } /* Add event to thread's threadFlow object. */ - json::object *thread_flow_loc_obj + sarif_thread_flow_location *thread_flow_loc_obj = make_thread_flow_location_object (event, i); thread_flow_obj->add_location (thread_flow_loc_obj); } @@ -1341,20 +1512,21 @@ sarif_builder::make_code_flow_object (const diagnostic_path &path) return code_flow_obj; } -/* Make a threadFlowLocation object (SARIF v2.1.0 section 3.38) for EVENT. */ +/* Make a "threadFlowLocation" object (SARIF v2.1.0 section 3.38) for EVENT. */ -json::object * +sarif_thread_flow_location * sarif_builder::make_thread_flow_location_object (const diagnostic_event &ev, int path_event_idx) { - sarif_object *thread_flow_loc_obj = new sarif_object (); + sarif_thread_flow_location *thread_flow_loc_obj + = new sarif_thread_flow_location (); /* Give diagnostic_event subclasses a chance to add custom properties via a property bag. */ ev.maybe_add_sarif_properties (*thread_flow_loc_obj); /* "location" property (SARIF v2.1.0 section 3.38.3). */ - json::object *location_obj + sarif_location *location_obj = make_location_object (ev, diagnostic_artifact_role::traced_file); thread_flow_loc_obj->set ("location", location_obj); @@ -1379,7 +1551,7 @@ sarif_builder::make_thread_flow_location_object (const diagnostic_event &ev, } /* If M has any known meaning, make a json array suitable for the "kinds" - property of a threadFlowLocation object (SARIF v2.1.0 section 3.38.8). + property of a "threadFlowLocation" object (SARIF v2.1.0 section 3.38.8). Otherwise, return NULL. */ @@ -1404,12 +1576,12 @@ sarif_builder::maybe_make_kinds_array (diagnostic_event::meaning m) const return kinds_arr; } -/* Make a message object (SARIF v2.1.0 section 3.11) for MSG. */ +/* Make a "message" object (SARIF v2.1.0 section 3.11) for MSG. */ -json::object * +sarif_message * sarif_builder::make_message_object (const char *msg) const { - json::object *message_obj = new json::object (); + sarif_message *message_obj = new sarif_message (); /* "text" property (SARIF v2.1.0 section 3.11.8). */ message_obj->set_string ("text", msg); @@ -1417,15 +1589,15 @@ sarif_builder::make_message_object (const char *msg) const return message_obj; } -/* Make a message object (SARIF v2.1.0 section 3.11) for DIAGRAM. +/* Make a "message" object (SARIF v2.1.0 section 3.11) for DIAGRAM. We emit the diagram as a code block within the Markdown part of the message. */ -json::object * +sarif_message * sarif_builder::make_message_object_for_diagram (diagnostic_context *context, const diagnostic_diagram &diagram) { - json::object *message_obj = new json::object (); + sarif_message *message_obj = new sarif_message (); /* "text" property (SARIF v2.1.0 section 3.11.8). */ message_obj->set_string ("text", diagram.get_alt_text ()); @@ -1447,13 +1619,14 @@ sarif_builder::make_message_object_for_diagram (diagnostic_context *context, return message_obj; } -/* Make a multiformatMessageString object (SARIF v2.1.0 section 3.12) +/* Make a "multiformatMessageString object" (SARIF v2.1.0 section 3.12) for MSG. */ -json::object * +sarif_multiformat_message_string * sarif_builder::make_multiformat_message_string (const char *msg) const { - json::object *message_obj = new json::object (); + sarif_multiformat_message_string *message_obj + = new sarif_multiformat_message_string (); /* "text" property (SARIF v2.1.0 section 3.12.3). */ message_obj->set_string ("text", msg); @@ -1464,14 +1637,14 @@ sarif_builder::make_multiformat_message_string (const char *msg) const #define SARIF_SCHEMA "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json" #define SARIF_VERSION "2.1.0" -/* Make a top-level sarifLog object (SARIF v2.1.0 section 3.13). +/* Make a top-level "sarifLog" object (SARIF v2.1.0 section 3.13). Take ownership of INVOCATION_OBJ and RESULTS. */ -json::object * +sarif_log * sarif_builder::make_top_level_object (sarif_invocation *invocation_obj, json::array *results) { - json::object *log_obj = new json::object (); + sarif_log *log_obj = new sarif_log (); /* "$schema" property (SARIF v2.1.0 section 3.13.3) . */ log_obj->set_string ("$schema", SARIF_SCHEMA); @@ -1481,24 +1654,24 @@ sarif_builder::make_top_level_object (sarif_invocation *invocation_obj, /* "runs" property (SARIF v2.1.0 section 3.13.4). */ json::array *run_arr = new json::array (); - json::object *run_obj = make_run_object (invocation_obj, results); + sarif_run *run_obj = make_run_object (invocation_obj, results); run_arr->append (run_obj); log_obj->set ("runs", run_arr); return log_obj; } -/* Make a run object (SARIF v2.1.0 section 3.14). +/* Make a "run" object (SARIF v2.1.0 section 3.14). Take ownership of INVOCATION_OBJ and RESULTS. */ -json::object * +sarif_run * sarif_builder::make_run_object (sarif_invocation *invocation_obj, json::array *results) { - json::object *run_obj = new json::object (); + sarif_run *run_obj = new sarif_run (); /* "tool" property (SARIF v2.1.0 section 3.14.6). */ - json::object *tool_obj = make_tool_object (); + sarif_tool *tool_obj = make_tool_object (); run_obj->set ("tool", tool_obj); /* "taxonomies" property (SARIF v2.1.0 section 3.14.8). */ @@ -1517,7 +1690,8 @@ sarif_builder::make_run_object (sarif_invocation *invocation_obj, { json::object *orig_uri_base_ids = new json::object (); run_obj->set ("originalUriBaseIds", orig_uri_base_ids); - json::object *pwd_art_loc_obj = make_artifact_location_object_for_pwd (); + sarif_artifact_location *pwd_art_loc_obj + = make_artifact_location_object_for_pwd (); orig_uri_base_ids->set (PWD_PROPERTY_NAME, pwd_art_loc_obj); } @@ -1539,15 +1713,15 @@ sarif_builder::make_run_object (sarif_invocation *invocation_obj, return run_obj; } -/* Make a tool object (SARIF v2.1.0 section 3.18). */ +/* Make a "tool" object (SARIF v2.1.0 section 3.18). */ -json::object * +sarif_tool * sarif_builder::make_tool_object () const { - json::object *tool_obj = new json::object (); + sarif_tool *tool_obj = new sarif_tool (); /* "driver" property (SARIF v2.1.0 section 3.18.2). */ - json::object *driver_obj = make_driver_tool_component_object (); + sarif_tool_component *driver_obj = make_driver_tool_component_object (); tool_obj->set ("driver", driver_obj); /* Report plugins via the "extensions" property @@ -1561,9 +1735,9 @@ sarif_builder::make_tool_object () const public: void on_plugin (const diagnostic_client_plugin_info &p) final override { - /* Create a toolComponent object (SARIF v2.1.0 section 3.19) + /* Create a "toolComponent" object (SARIF v2.1.0 section 3.19) for the plugin. */ - json::object *plugin_obj = new json::object (); + sarif_tool_component *plugin_obj = new sarif_tool_component (); m_plugin_objs.safe_push (plugin_obj); /* "name" property (SARIF v2.1.0 section 3.19.8). */ @@ -1578,7 +1752,7 @@ sarif_builder::make_tool_object () const if (const char *version = p.get_version ()) plugin_obj->set_string ("version", version); } - auto_vec m_plugin_objs; + auto_vec m_plugin_objs; }; my_plugin_visitor v; vinfo->for_each_plugin (v); @@ -1597,13 +1771,13 @@ sarif_builder::make_tool_object () const return tool_obj; } -/* Make a toolComponent object (SARIF v2.1.0 section 3.19) for what SARIF +/* Make a "toolComponent" object (SARIF v2.1.0 section 3.19) for what SARIF calls the "driver" (see SARIF v2.1.0 section 3.18.1). */ -json::object * +sarif_tool_component * sarif_builder::make_driver_tool_component_object () const { - json::object *driver_obj = new json::object (); + sarif_tool_component *driver_obj = new sarif_tool_component (); if (auto client_data_hooks = m_context->get_client_data_hooks ()) if (const client_version_info *vinfo @@ -1639,15 +1813,15 @@ sarif_builder::make_driver_tool_component_object () const } /* If we've seen any CWE IDs, make an array for the "taxonomies" property - (SARIF v2.1.0 section 3.14.8) of a run object, containting a singl - toolComponent (3.19) as per 3.19.3, representing the CWE. + (SARIF v2.1.0 section 3.14.8) of a run object, containing a single + "toolComponent" (3.19) as per 3.19.3, representing the CWE. Otherwise return NULL. */ json::array * sarif_builder::maybe_make_taxonomies_array () const { - json::object *cwe_obj = maybe_make_cwe_taxonomy_object (); + sarif_tool_component *cwe_obj = maybe_make_cwe_taxonomy_object (); if (!cwe_obj) return NULL; @@ -1657,19 +1831,19 @@ sarif_builder::maybe_make_taxonomies_array () const return taxonomies_arr; } -/* If we've seen any CWE IDs, make a toolComponent object +/* If we've seen any CWE IDs, make a "toolComponent" object (SARIF v2.1.0 section 3.19) representing the CWE taxonomy, as per 3.19.3. Populate the "taxa" property with all of the CWE IDs in m_cwe_id_set. Otherwise return NULL. */ -json::object * +sarif_tool_component * sarif_builder::maybe_make_cwe_taxonomy_object () const { if (m_cwe_id_set.is_empty ()) return NULL; - json::object *taxonomy_obj = new json::object (); + sarif_tool_component *taxonomy_obj = new sarif_tool_component (); /* "name" property (SARIF v2.1.0 section 3.19.8). */ taxonomy_obj->set_string ("name", "CWE"); @@ -1681,7 +1855,7 @@ sarif_builder::maybe_make_cwe_taxonomy_object () const taxonomy_obj->set_string ("organization", "MITRE"); /* "shortDescription" property (SARIF v2.1.0 section 3.19.19). */ - json::object *short_desc + sarif_multiformat_message_string *short_desc = make_multiformat_message_string ("The MITRE" " Common Weakness Enumeration"); taxonomy_obj->set ("shortDescription", short_desc); @@ -1690,7 +1864,7 @@ sarif_builder::maybe_make_cwe_taxonomy_object () const json::array *taxa_arr = new json::array (); for (auto cwe_id : m_cwe_id_set) { - json::object *cwe_taxon + sarif_reporting_descriptor *cwe_taxon = make_reporting_descriptor_object_for_cwe_id (cwe_id); taxa_arr->append (cwe_taxon); } @@ -1699,7 +1873,7 @@ sarif_builder::maybe_make_cwe_taxonomy_object () const return taxonomy_obj; } -/* Ensure that we have an artifact object (SARIF v2.1.0 section 3.24) +/* Ensure that we have an "artifact" object (SARIF v2.1.0 section 3.24) for FILENAME, adding it to m_filename_to_artifact_map if not already found, and adding ROLE to it. If EMBED_CONTENTS is true, then flag that we will attempt to embed the @@ -1721,7 +1895,8 @@ sarif_builder::get_or_create_artifact (const char *filename, m_filename_to_artifact_map.put (filename, artifact_obj); /* "location" property (SARIF v2.1.0 section 3.24.2). */ - json::object *artifact_loc_obj = make_artifact_location_object (filename); + sarif_artifact_location *artifact_loc_obj + = make_artifact_location_object (filename); artifact_obj->set ("location", artifact_loc_obj); /* "sourceLanguage" property (SARIF v2.1.0 section 3.24.10). */ @@ -1747,10 +1922,10 @@ sarif_builder::get_or_create_artifact (const char *filename, return *artifact_obj; } -/* Make an artifactContent object (SARIF v2.1.0 section 3.3) for the +/* Make an "artifactContent" object (SARIF v2.1.0 section 3.3) for the full contents of FILENAME. */ -json::object * +sarif_artifact_content * sarif_builder::maybe_make_artifact_content_object (const char *filename) const { /* Let input.cc handle any charset conversion. */ @@ -1763,7 +1938,7 @@ sarif_builder::maybe_make_artifact_content_object (const char *filename) const if (!cpp_valid_utf8_p(utf8_content.get_buffer (), utf8_content.length ())) return NULL; - json::object *artifact_content_obj = new json::object (); + sarif_artifact_content *artifact_content_obj = new sarif_artifact_content (); artifact_content_obj->set ("text", new json::string (utf8_content.get_buffer (), utf8_content.length ())); @@ -1796,10 +1971,10 @@ sarif_builder::get_source_lines (const char *filename, return xstrdup (result.address ()); } -/* Make an artifactContent object (SARIF v2.1.0 section 3.3) for the given +/* Make an "artifactContent" object (SARIF v2.1.0 section 3.3) for the given run of lines within FILENAME (including the endpoints). */ -json::object * +sarif_artifact_content * sarif_builder::maybe_make_artifact_content_object (const char *filename, int start_line, int end_line) const @@ -1816,39 +1991,40 @@ sarif_builder::maybe_make_artifact_content_object (const char *filename, return NULL; } - json::object *artifact_content_obj = new json::object (); + sarif_artifact_content *artifact_content_obj = new sarif_artifact_content (); artifact_content_obj->set_string ("text", text_utf8); free (text_utf8); return artifact_content_obj; } -/* Make a fix object (SARIF v2.1.0 section 3.55) for RICHLOC. */ +/* Make a "fix" object (SARIF v2.1.0 section 3.55) for RICHLOC. */ -json::object * +sarif_fix * sarif_builder::make_fix_object (const rich_location &richloc) { - json::object *fix_obj = new json::object (); + sarif_fix *fix_obj = new sarif_fix (); /* "artifactChanges" property (SARIF v2.1.0 section 3.55.3). */ /* We assume that all fix-it hints in RICHLOC affect the same file. */ json::array *artifact_change_arr = new json::array (); - json::object *artifact_change_obj = make_artifact_change_object (richloc); + sarif_artifact_change *artifact_change_obj + = make_artifact_change_object (richloc); artifact_change_arr->append (artifact_change_obj); fix_obj->set ("artifactChanges", artifact_change_arr); return fix_obj; } -/* Make an artifactChange object (SARIF v2.1.0 section 3.56) for RICHLOC. */ +/* Make an "artifactChange" object (SARIF v2.1.0 section 3.56) for RICHLOC. */ -json::object * +sarif_artifact_change * sarif_builder::make_artifact_change_object (const rich_location &richloc) { - json::object *artifact_change_obj = new json::object (); + sarif_artifact_change *artifact_change_obj = new sarif_artifact_change (); /* "artifactLocation" property (SARIF v2.1.0 section 3.56.2). */ - json::object *artifact_location_obj + sarif_artifact_location *artifact_location_obj = make_artifact_location_object (richloc.get_loc ()); artifact_change_obj->set ("artifactLocation", artifact_location_obj); @@ -1857,7 +2033,7 @@ sarif_builder::make_artifact_change_object (const rich_location &richloc) for (unsigned int i = 0; i < richloc.get_num_fixit_hints (); i++) { const fixit_hint *hint = richloc.get_fixit_hint (i); - json::object *replacement_obj = make_replacement_object (*hint); + sarif_replacement *replacement_obj = make_replacement_object (*hint); replacement_arr->append (replacement_obj); } artifact_change_obj->set ("replacements", replacement_arr); @@ -1865,30 +2041,31 @@ sarif_builder::make_artifact_change_object (const rich_location &richloc) return artifact_change_obj; } -/* Make a replacement object (SARIF v2.1.0 section 3.57) for HINT. */ +/* Make a "replacement" object (SARIF v2.1.0 section 3.57) for HINT. */ -json::object * +sarif_replacement * sarif_builder::make_replacement_object (const fixit_hint &hint) const { - json::object *replacement_obj = new json::object (); + sarif_replacement *replacement_obj = new sarif_replacement (); /* "deletedRegion" property (SARIF v2.1.0 section 3.57.3). */ - json::object *region_obj = make_region_object_for_hint (hint); + sarif_region *region_obj = make_region_object_for_hint (hint); replacement_obj->set ("deletedRegion", region_obj); /* "insertedContent" property (SARIF v2.1.0 section 3.57.4). */ - json::object *content_obj = make_artifact_content_object (hint.get_string ()); + sarif_artifact_content *content_obj + = make_artifact_content_object (hint.get_string ()); replacement_obj->set ("insertedContent", content_obj); return replacement_obj; } -/* Make an artifactContent object (SARIF v2.1.0 section 3.3) for TEXT. */ +/* Make an "artifactContent" object (SARIF v2.1.0 section 3.3) for TEXT. */ -json::object * +sarif_artifact_content * sarif_builder::make_artifact_content_object (const char *text) const { - json::object *content_obj = new json::object (); + sarif_artifact_content *content_obj = new sarif_artifact_content (); /* "text" property (SARIF v2.1.0 section 3.3.2). */ content_obj->set_string ("text", text); diff --git a/gcc/diagnostic-format-sarif.h b/gcc/diagnostic-format-sarif.h index fdbbd93de7a7..c492582eee4b 100644 --- a/gcc/diagnostic-format-sarif.h +++ b/gcc/diagnostic-format-sarif.h @@ -44,7 +44,14 @@ public: sarif_property_bag &get_or_create_properties (); }; -extern json::object * +/* Subclass of sarif_object for SARIF "logicalLocation" objects + (SARIF v2.1.0 section 3.33). */ + +class sarif_logical_location : public sarif_object +{ +}; + +extern sarif_logical_location * make_sarif_logical_location_object (const logical_location &logical_loc); #endif /* ! GCC_DIAGNOSTIC_FORMAT_SARIF_H */ From patchwork Wed Jul 24 22:18:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964561 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=FvRzYbxb; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpPT105vz1ydm for ; Thu, 25 Jul 2024 08:20:45 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 66AD5385E82A for ; Wed, 24 Jul 2024 22:20:43 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id A68B3385DDDA for ; Wed, 24 Jul 2024 22:18:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A68B3385DDDA Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A68B3385DDDA Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859536; cv=none; b=JZXyKg9/Kfvo3AuH94rp9nPBJhSTc5S99mPMsGHAEHjP5v4w+ydvkcj9fvIlxkE9TI6PiG+JaDhP1gMMgXTdm1b6/Q1dRIZW0I41GKtqx+dfmU9shn+p8QkukQ5iw9ZqbeR1vzrmesjqiQFaVSPsceLjiFD4DgQpLoxiShe2LPE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859536; c=relaxed/simple; bh=8J5DaZDhN40peNtylK2DjHNYlQbD0BJp86v8sbJ/7Rs=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=qfhg4mmAG88l5jnkaGiswMxgbyizRCKO2k2aBx7iaIcOD7DH1xPv9Qxg8epi/d3Djv+n0nAU6dHnTkO1wuEx61If0FTdZbNPjQSFMw1DYzz1Bq5dJOESh/nvrJGEb5ADQHGmYwmzfVeRkGuOKTIyHHrdBG93+3G0iummX6vCSII= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859528; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gyDTPWWX5YKQIjyunU8XDZjOlLs0FHfj0wJLrKNC4Oo=; b=FvRzYbxbDXdJt9ZTq3PwQQ84fDehdjzRYxU2Py8RjjERX3EQ6mmWHBCTteKiC1fvRtEMjC IM7AptWMihlRzNn6uTqfzokr7PzjFfY+GlUBdKrKF+9zERagCTgDg3sncG4lYvHR0T73nB SRfIce3JeXK5azxLFkCcpInH5Clehxw= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-27-_XPAscBcMfCIhO-RQoiJ_w-1; Wed, 24 Jul 2024 18:18:46 -0400 X-MC-Unique: _XPAscBcMfCIhO-RQoiJ_w-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id BF9771955F2D for ; Wed, 24 Jul 2024 22:18:45 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 88FBF1955E80; Wed, 24 Jul 2024 22:18:44 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 06/16] diagnostics: output formats: use references for non-null pointers Date: Wed, 24 Jul 2024 18:18:14 -0400 Message-Id: <20240724221824.585054-7-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org No functional change intended. gcc/ChangeLog: * diagnostic-format-json.cc (json_from_expanded_location): Make "static". Pass param "context" by reference, as it cannot be null. (json_from_location_range): Likewise for param "context". (json_from_fixit_hint): Likewise. (make_json_for_path): Likewise. (json_output_format::on_end_diagnostic): Update for above changes. (diagnostic_output_format_init_json::diagnostic_output_format_init_json): Pass param "context" by reference, as it cannot be null. (diagnostic_output_format_init_json_stderr): Likewise. (diagnostic_output_format_init_json_file): Likewise. (selftest::test_unknown_location): Update for above changes. (selftest::test_bad_endpoints): Likewise. * diagnostic-format-sarif.cc (sarif_builder::m_context): Convert from pointer to reference. (sarif_invocation::add_notification_for_ice): Convert both params from pointers to references. (sarif_invocation::prepare_to_flush): Likewise for "context". (sarif_result::on_nested_diagnostic): Likewise for "context" and "builder". (sarif_result::on_diagram): Likewise. (sarif_ice_notification::sarif_ice_notification): Likewise. (sarif_builder::sarif_builder): Likewise for "context". (sarif_builder::end_diagnostic): Likewise. (sarif_builder::emit_diagram): Likewise. (sarif_builder::make_result_object): Likewise. (make_reporting_descriptor_object_for_warning): Likewise. (sarif_builder::make_locations_arr): Update for change to m_context. (sarif_builder::get_sarif_column): Likewise. (sarif_builder::make_message_object_for_diagram): Convert "context" from pointer to reference. (sarif_builder::make_tool_object): Likewise for "m_context". (sarif_builder::make_driver_tool_component_object): Likewise. (sarif_builder::get_or_create_artifact): Likewise. (sarif_builder::maybe_make_artifact_content_object): Likewise. (sarif_builder::get_source_lines): Likewise. (sarif_output_format::on_end_diagnostic): Update for above changes. (sarif_output_format::on_diagram): Likewise. (sarif_output_format::sarif_output_format): Likewise. (diagnostic_output_format_init_sarif): Convert param "context" from pointer to reference. (diagnostic_output_format_init_sarif_stderr): Likewise. (diagnostic_output_format_init_sarif_file): Likewise. (diagnostic_output_format_init_sarif_stream): Likewise. * diagnostic.cc (diagnostic_output_format_init): Likewise. * diagnostic.h (diagnostic_output_format_init): Likewise. (diagnostic_output_format_init_json_stderr): Likewise. (diagnostic_output_format_init_json_file): Likewise. (diagnostic_output_format_init_sarif_stderr): Likewise. (diagnostic_output_format_init_sarif_file): Likewise. (diagnostic_output_format_init_sarif_stream): Likewise. (json_from_expanded_location): Delete decl. * gcc.cc (driver_handle_option): Update for change to diagnostic_output_format_init. * opts.cc (common_handle_option): Likewise. Signed-off-by: David Malcolm --- gcc/diagnostic-format-json.cc | 56 +++++------ gcc/diagnostic-format-sarif.cc | 166 ++++++++++++++++----------------- gcc/diagnostic.cc | 2 +- gcc/diagnostic.h | 15 ++- gcc/gcc.cc | 3 +- gcc/opts.cc | 3 +- 6 files changed, 122 insertions(+), 123 deletions(-) diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc index 4dc0f264fc70..1bf8da663cc2 100644 --- a/gcc/diagnostic-format-json.cc +++ b/gcc/diagnostic-format-json.cc @@ -94,8 +94,8 @@ private: /* Generate a JSON object for LOC. */ -json::value * -json_from_expanded_location (diagnostic_context *context, location_t loc) +static json::value * +json_from_expanded_location (diagnostic_context &context, location_t loc) { expanded_location exploc = expand_location (loc); json::object *result = new json::object (); @@ -103,7 +103,7 @@ json_from_expanded_location (diagnostic_context *context, location_t loc) result->set_string ("file", exploc.file); result->set_integer ("line", exploc.line); - const enum diagnostics_column_unit orig_unit = context->m_column_unit; + const enum diagnostics_column_unit orig_unit = context.m_column_unit; struct { const char *name; @@ -115,22 +115,22 @@ json_from_expanded_location (diagnostic_context *context, location_t loc) int the_column = INT_MIN; for (int i = 0; i != ARRAY_SIZE (column_fields); ++i) { - context->m_column_unit = column_fields[i].unit; - const int col = context->converted_column (exploc); + context.m_column_unit = column_fields[i].unit; + const int col = context.converted_column (exploc); result->set_integer (column_fields[i].name, col); if (column_fields[i].unit == orig_unit) the_column = col; } gcc_assert (the_column != INT_MIN); result->set_integer ("column", the_column); - context->m_column_unit = orig_unit; + context.m_column_unit = orig_unit; return result; } /* Generate a JSON object for LOC_RANGE. */ static json::object * -json_from_location_range (diagnostic_context *context, +json_from_location_range (diagnostic_context &context, const location_range *loc_range, unsigned range_idx) { location_t caret_loc = get_pure_location (loc_range->m_loc); @@ -163,7 +163,7 @@ json_from_location_range (diagnostic_context *context, /* Generate a JSON object for HINT. */ static json::object * -json_from_fixit_hint (diagnostic_context *context, const fixit_hint *hint) +json_from_fixit_hint (diagnostic_context &context, const fixit_hint *hint) { json::object *fixit_obj = new json::object (); @@ -192,7 +192,7 @@ json_from_metadata (const diagnostic_metadata *metadata) /* Make a JSON value for PATH. */ static json::value * -make_json_for_path (diagnostic_context *context, +make_json_for_path (diagnostic_context &context, const diagnostic_path *path) { json::array *path_array = new json::array (); @@ -288,7 +288,7 @@ json_output_format::on_end_diagnostic (const diagnostic_info &diagnostic, { const location_range *loc_range = richloc->get_range (i); json::object *loc_obj - = json_from_location_range (&m_context, loc_range, i); + = json_from_location_range (m_context, loc_range, i); if (loc_obj) loc_array->append (loc_obj); } @@ -300,7 +300,7 @@ json_output_format::on_end_diagnostic (const diagnostic_info &diagnostic, for (unsigned int i = 0; i < richloc->get_num_fixit_hints (); i++) { const fixit_hint *hint = richloc->get_fixit_hint (i); - json::object *fixit_obj = json_from_fixit_hint (&m_context, hint); + json::object *fixit_obj = json_from_fixit_hint (m_context, hint); fixit_array->append (fixit_obj); } } @@ -319,7 +319,7 @@ json_output_format::on_end_diagnostic (const diagnostic_info &diagnostic, const diagnostic_path *path = richloc->get_path (); if (path) { - json::value *path_value = make_json_for_path (&m_context, path); + json::value *path_value = make_json_for_path (m_context, path); diag_obj->set ("path", path_value); } @@ -387,46 +387,46 @@ private: to a file). */ static void -diagnostic_output_format_init_json (diagnostic_context *context) +diagnostic_output_format_init_json (diagnostic_context &context) { /* Suppress normal textual path output. */ - context->set_path_format (DPF_NONE); + context.set_path_format (DPF_NONE); /* The metadata is handled in JSON format, rather than as text. */ - context->set_show_cwe (false); - context->set_show_rules (false); + context.set_show_cwe (false); + context.set_show_rules (false); /* The option is handled in JSON format, rather than as text. */ - context->set_show_option_requested (false); + context.set_show_option_requested (false); /* Don't colorize the text. */ - pp_show_color (context->printer) = false; - context->set_show_highlight_colors (false); + pp_show_color (context.printer) = false; + context.set_show_highlight_colors (false); } /* Populate CONTEXT in preparation for JSON output to stderr. */ void -diagnostic_output_format_init_json_stderr (diagnostic_context *context, +diagnostic_output_format_init_json_stderr (diagnostic_context &context, bool formatted) { diagnostic_output_format_init_json (context); - context->set_output_format (new json_stderr_output_format (*context, - formatted)); + context.set_output_format (new json_stderr_output_format (context, + formatted)); } /* Populate CONTEXT in preparation for JSON output to a file named BASE_FILE_NAME.gcc.json. */ void -diagnostic_output_format_init_json_file (diagnostic_context *context, +diagnostic_output_format_init_json_file (diagnostic_context &context, bool formatted, const char *base_file_name) { diagnostic_output_format_init_json (context); - context->set_output_format (new json_file_output_format (*context, - formatted, - base_file_name)); + context.set_output_format (new json_file_output_format (context, + formatted, + base_file_name)); } #if CHECKING_P @@ -440,7 +440,7 @@ static void test_unknown_location () { test_diagnostic_context dc; - delete json_from_expanded_location (&dc, UNKNOWN_LOCATION); + delete json_from_expanded_location (dc, UNKNOWN_LOCATION); } /* Verify that we gracefully handle attempts to serialize bad @@ -459,7 +459,7 @@ test_bad_endpoints () loc_range.m_label = NULL; test_diagnostic_context dc; - json::object *obj = json_from_location_range (&dc, &loc_range, 0); + json::object *obj = json_from_location_range (dc, &loc_range, 0); /* We should have a "caret" value, but no "start" or "finish" values. */ ASSERT_TRUE (obj != NULL); ASSERT_TRUE (obj->get ("caret") != NULL); diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index c35d8788d6de..d6de5806f5ac 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -118,10 +118,10 @@ class sarif_invocation : public sarif_object public: sarif_invocation (); - void add_notification_for_ice (diagnostic_context *context, + void add_notification_for_ice (diagnostic_context &context, const diagnostic_info &diagnostic, - sarif_builder *builder); - void prepare_to_flush (diagnostic_context *context); + sarif_builder &builder); + void prepare_to_flush (diagnostic_context &context); private: json::array *m_notifications_arr; @@ -182,13 +182,13 @@ public: sarif_result () : m_related_locations_arr (NULL) {} void - on_nested_diagnostic (diagnostic_context *context, + on_nested_diagnostic (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind, - sarif_builder *builder); - void on_diagram (diagnostic_context *context, + sarif_builder &builder); + void on_diagram (diagnostic_context &context, const diagnostic_diagram &diagram, - sarif_builder *builder); + sarif_builder &builder); private: void @@ -275,9 +275,9 @@ class sarif_replacement : public sarif_object {}; class sarif_ice_notification : public sarif_object { public: - sarif_ice_notification (diagnostic_context *context, + sarif_ice_notification (diagnostic_context &context, const diagnostic_info &diagnostic, - sarif_builder *builder); + sarif_builder &builder); }; /* A class for managing SARIF output (for -fdiagnostics-format=sarif-stderr @@ -326,14 +326,14 @@ public: class sarif_builder { public: - sarif_builder (diagnostic_context *context, + sarif_builder (diagnostic_context &context, const char *main_input_filename_, bool formatted); - void end_diagnostic (diagnostic_context *context, + void end_diagnostic (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind); - void emit_diagram (diagnostic_context *context, + void emit_diagram (diagnostic_context &context, const diagnostic_diagram &diagram); void end_group (); @@ -348,14 +348,14 @@ public: sarif_message * make_message_object (const char *msg) const; sarif_message * - make_message_object_for_diagram (diagnostic_context *context, + make_message_object_for_diagram (diagnostic_context &context, const diagnostic_diagram &diagram); sarif_artifact_content * maybe_make_artifact_content_object (const char *filename) const; private: sarif_result * - make_result_object (diagnostic_context *context, + make_result_object (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind); void @@ -406,7 +406,7 @@ private: sarif_tool_component_reference * make_tool_component_reference_object_for_cwe () const; sarif_reporting_descriptor * - make_reporting_descriptor_object_for_warning (diagnostic_context *context, + make_reporting_descriptor_object_for_warning (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind, const char *option_text); @@ -436,7 +436,7 @@ private: make_artifact_content_object (const char *text) const; int get_sarif_column (expanded_location exploc) const; - diagnostic_context *m_context; + diagnostic_context &m_context; /* The JSON object for the invocation object. */ sarif_invocation *m_invocation_obj; @@ -491,9 +491,9 @@ sarif_invocation::sarif_invocation () Add an object representing the ICE to the notifications array. */ void -sarif_invocation::add_notification_for_ice (diagnostic_context *context, +sarif_invocation::add_notification_for_ice (diagnostic_context &context, const diagnostic_info &diagnostic, - sarif_builder *builder) + sarif_builder &builder) { m_success = false; @@ -503,7 +503,7 @@ sarif_invocation::add_notification_for_ice (diagnostic_context *context, } void -sarif_invocation::prepare_to_flush (diagnostic_context *context) +sarif_invocation::prepare_to_flush (diagnostic_context &context) { /* "executionSuccessful" property (SARIF v2.1.0 section 3.20.14). */ set_bool ("executionSuccessful", m_success); @@ -513,7 +513,7 @@ sarif_invocation::prepare_to_flush (diagnostic_context *context) /* Call client hook, allowing it to create a custom property bag for this object (SARIF v2.1.0 section 3.8) e.g. for recording time vars. */ - if (auto client_data_hooks = context->get_client_data_hooks ()) + if (auto client_data_hooks = context.get_client_data_hooks ()) client_data_hooks->add_sarif_invocation_properties (*this); } @@ -606,20 +606,20 @@ sarif_artifact::populate_roles () secondary diagnostics occur (such as notes to a warning). */ void -sarif_result::on_nested_diagnostic (diagnostic_context *context, +sarif_result::on_nested_diagnostic (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t /*orig_diag_kind*/, - sarif_builder *builder) + sarif_builder &builder) { /* We don't yet generate meaningful logical locations for notes; sometimes these will related to current_function_decl, but often they won't. */ sarif_location *location_obj - = builder->make_location_object (*diagnostic.richloc, NULL, - diagnostic_artifact_role::result_file); + = builder.make_location_object (*diagnostic.richloc, NULL, + diagnostic_artifact_role::result_file); sarif_message *message_obj - = builder->make_message_object (pp_formatted_text (context->printer)); - pp_clear_output_area (context->printer); + = builder.make_message_object (pp_formatted_text (context.printer)); + pp_clear_output_area (context.printer); location_obj->set ("message", message_obj); add_related_location (location_obj); @@ -632,13 +632,13 @@ sarif_result::on_nested_diagnostic (diagnostic_context *context, (SARIF v2.1.0 section 3.28.5). */ void -sarif_result::on_diagram (diagnostic_context *context, +sarif_result::on_diagram (diagnostic_context &context, const diagnostic_diagram &diagram, - sarif_builder *builder) + sarif_builder &builder) { sarif_location *location_obj = new sarif_location (); sarif_message *message_obj - = builder->make_message_object_for_diagram (context, diagram); + = builder.make_message_object_for_diagram (context, diagram); location_obj->set ("message", message_obj); add_related_location (location_obj); @@ -663,20 +663,20 @@ sarif_result::add_related_location (sarif_location *location_obj) /* sarif_ice_notification's ctor. DIAGNOSTIC is an internal compiler error. */ -sarif_ice_notification::sarif_ice_notification (diagnostic_context *context, +sarif_ice_notification::sarif_ice_notification (diagnostic_context &context, const diagnostic_info &diagnostic, - sarif_builder *builder) + sarif_builder &builder) { /* "locations" property (SARIF v2.1.0 section 3.58.4). */ json::array *locations_arr - = builder->make_locations_arr (diagnostic, - diagnostic_artifact_role::result_file); + = builder.make_locations_arr (diagnostic, + diagnostic_artifact_role::result_file); set ("locations", locations_arr); /* "message" property (SARIF v2.1.0 section 3.85.5). */ sarif_message *message_obj - = builder->make_message_object (pp_formatted_text (context->printer)); - pp_clear_output_area (context->printer); + = builder.make_message_object (pp_formatted_text (context.printer)); + pp_clear_output_area (context.printer); set ("message", message_obj); /* "level" property (SARIF v2.1.0 section 3.58.6). */ @@ -707,7 +707,7 @@ add_location (sarif_thread_flow_location *thread_flow_loc_obj) /* sarif_builder's ctor. */ -sarif_builder::sarif_builder (diagnostic_context *context, +sarif_builder::sarif_builder (diagnostic_context &context, const char *main_input_filename_, bool formatted) : m_context (context), @@ -717,7 +717,7 @@ sarif_builder::sarif_builder (diagnostic_context *context, m_seen_any_relative_paths (false), m_rule_id_set (), m_rules_arr (new json::array ()), - m_tabstop (context->m_tabstop), + m_tabstop (context.m_tabstop), m_formatted (formatted) { /* Mark MAIN_INPUT_FILENAME_ as the artifact that the tool was @@ -734,13 +734,13 @@ sarif_builder::sarif_builder (diagnostic_context *context, /* Implementation of "end_diagnostic" for SARIF output. */ void -sarif_builder::end_diagnostic (diagnostic_context *context, +sarif_builder::end_diagnostic (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind) { if (diagnostic.kind == DK_ICE || diagnostic.kind == DK_ICE_NOBT) { - m_invocation_obj->add_notification_for_ice (context, diagnostic, this); + m_invocation_obj->add_notification_for_ice (context, diagnostic, *this); return; } @@ -749,7 +749,7 @@ sarif_builder::end_diagnostic (diagnostic_context *context, m_cur_group_result->on_nested_diagnostic (context, diagnostic, orig_diag_kind, - this); + *this); else { /* Top-level diagnostic. */ @@ -764,12 +764,12 @@ sarif_builder::end_diagnostic (diagnostic_context *context, for SARIF output. */ void -sarif_builder::emit_diagram (diagnostic_context *context, +sarif_builder::emit_diagram (diagnostic_context &context, const diagnostic_diagram &diagram) { /* We must be within the emission of a top-level diagnostic. */ gcc_assert (m_cur_group_result); - m_cur_group_result->on_diagram (context, diagram, this); + m_cur_group_result->on_diagram (context, diagram, *this); } /* Implementation of "end_group_cb" for SARIF output. */ @@ -840,7 +840,7 @@ make_rule_id_for_diagnostic_kind (diagnostic_t diag_kind) /* Make a "result" object (SARIF v2.1.0 section 3.27) for DIAGNOSTIC. */ sarif_result * -sarif_builder::make_result_object (diagnostic_context *context, +sarif_builder::make_result_object (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind) { @@ -849,8 +849,8 @@ sarif_builder::make_result_object (diagnostic_context *context, /* "ruleId" property (SARIF v2.1.0 section 3.27.5). */ /* Ideally we'd have an option_name for these. */ if (char *option_text - = context->make_option_name (diagnostic.option_index, - orig_diag_kind, diagnostic.kind)) + = context.make_option_name (diagnostic.option_index, + orig_diag_kind, diagnostic.kind)) { /* Lazily create reportingDescriptor objects for and add to m_rules_arr. Set ruleId referencing them. */ @@ -903,8 +903,8 @@ sarif_builder::make_result_object (diagnostic_context *context, /* "message" property (SARIF v2.1.0 section 3.27.11). */ sarif_message *message_obj - = make_message_object (pp_formatted_text (context->printer)); - pp_clear_output_area (context->printer); + = make_message_object (pp_formatted_text (context.printer)); + pp_clear_output_area (context.printer); result_obj->set ("message", message_obj); /* "locations" property (SARIF v2.1.0 section 3.27.12). */ @@ -944,7 +944,7 @@ sarif_builder::make_result_object (diagnostic_context *context, sarif_reporting_descriptor * sarif_builder:: -make_reporting_descriptor_object_for_warning (diagnostic_context *context, +make_reporting_descriptor_object_for_warning (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t /*orig_diag_kind*/, const char *option_text) @@ -959,7 +959,7 @@ make_reporting_descriptor_object_for_warning (diagnostic_context *context, it seems redundant compared to "id". */ /* "helpUri" property (SARIF v2.1.0 section 3.49.12). */ - if (char *option_url = context->make_option_url (diagnostic.option_index)) + if (char *option_url = context.make_option_url (diagnostic.option_index)) { reporting_desc->set_string ("helpUri", option_url); free (option_url); @@ -1050,7 +1050,7 @@ sarif_builder::make_locations_arr (const diagnostic_info &diagnostic, { json::array *locations_arr = new json::array (); const logical_location *logical_loc = NULL; - if (auto client_data_hooks = m_context->get_client_data_hooks ()) + if (auto client_data_hooks = m_context.get_client_data_hooks ()) logical_loc = client_data_hooks->get_current_logical_location (); sarif_location *location_obj @@ -1257,7 +1257,7 @@ int sarif_builder::get_sarif_column (expanded_location exploc) const { cpp_char_column_policy policy (m_tabstop, cpp_wcwidth); - return location_compute_display_column (m_context->get_file_cache (), + return location_compute_display_column (m_context.get_file_cache (), exploc, policy); } @@ -1594,7 +1594,7 @@ sarif_builder::make_message_object (const char *msg) const of the message. */ sarif_message * -sarif_builder::make_message_object_for_diagram (diagnostic_context *context, +sarif_builder::make_message_object_for_diagram (diagnostic_context &context, const diagnostic_diagram &diagram) { sarif_message *message_obj = new sarif_message (); @@ -1602,19 +1602,19 @@ sarif_builder::make_message_object_for_diagram (diagnostic_context *context, /* "text" property (SARIF v2.1.0 section 3.11.8). */ message_obj->set_string ("text", diagram.get_alt_text ()); - char *saved_prefix = pp_take_prefix (context->printer); - pp_set_prefix (context->printer, NULL); + char *saved_prefix = pp_take_prefix (context.printer); + pp_set_prefix (context.printer, NULL); /* "To produce a code block in Markdown, simply indent every line of the block by at least 4 spaces or 1 tab." Here we use 4 spaces. */ - diagram.get_canvas ().print_to_pp (context->printer, " "); - pp_set_prefix (context->printer, saved_prefix); + diagram.get_canvas ().print_to_pp (context.printer, " "); + pp_set_prefix (context.printer, saved_prefix); /* "markdown" property (SARIF v2.1.0 section 3.11.9). */ - message_obj->set_string ("markdown", pp_formatted_text (context->printer)); + message_obj->set_string ("markdown", pp_formatted_text (context.printer)); - pp_clear_output_area (context->printer); + pp_clear_output_area (context.printer); return message_obj; } @@ -1726,7 +1726,7 @@ sarif_builder::make_tool_object () const /* Report plugins via the "extensions" property (SARIF v2.1.0 section 3.18.3). */ - if (auto client_data_hooks = m_context->get_client_data_hooks ()) + if (auto client_data_hooks = m_context.get_client_data_hooks ()) if (const client_version_info *vinfo = client_data_hooks->get_any_version_info ()) { @@ -1779,7 +1779,7 @@ sarif_builder::make_driver_tool_component_object () const { sarif_tool_component *driver_obj = new sarif_tool_component (); - if (auto client_data_hooks = m_context->get_client_data_hooks ()) + if (auto client_data_hooks = m_context.get_client_data_hooks ()) if (const client_version_info *vinfo = client_data_hooks->get_any_version_info ()) { @@ -1908,7 +1908,7 @@ sarif_builder::get_or_create_artifact (const char *filename, case diagnostic_artifact_role::result_file: case diagnostic_artifact_role::traced_file: /* Assume that these are in the source language. */ - if (auto client_data_hooks = m_context->get_client_data_hooks ()) + if (auto client_data_hooks = m_context.get_client_data_hooks ()) if (const char *source_lang = client_data_hooks->maybe_get_sarif_source_language (filename)) artifact_obj->set_string ("sourceLanguage", source_lang); @@ -1930,7 +1930,7 @@ sarif_builder::maybe_make_artifact_content_object (const char *filename) const { /* Let input.cc handle any charset conversion. */ char_span utf8_content - = m_context->get_file_cache ().get_source_file_content (filename); + = m_context.get_file_cache ().get_source_file_content (filename); if (!utf8_content) return NULL; @@ -1958,7 +1958,7 @@ sarif_builder::get_source_lines (const char *filename, for (int line = start_line; line <= end_line; line++) { char_span line_content - = m_context->get_file_cache ().get_source_line (filename, line); + = m_context.get_file_cache ().get_source_line (filename, line); if (!line_content.get_buffer ()) return NULL; result.reserve (line_content.length () + 1); @@ -2110,11 +2110,11 @@ public: on_end_diagnostic (const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind) final override { - m_builder.end_diagnostic (&m_context, diagnostic, orig_diag_kind); + m_builder.end_diagnostic (m_context, diagnostic, orig_diag_kind); } void on_diagram (const diagnostic_diagram &diagram) final override { - m_builder.emit_diagram (&m_context, diagram); + m_builder.emit_diagram (m_context, diagram); } protected: @@ -2122,7 +2122,7 @@ protected: const char *main_input_filename_, bool formatted) : diagnostic_output_format (context), - m_builder (&context, main_input_filename_, formatted) + m_builder (context, main_input_filename_, formatted) {} sarif_builder m_builder; @@ -2193,36 +2193,36 @@ private: to a file). */ static void -diagnostic_output_format_init_sarif (diagnostic_context *context) +diagnostic_output_format_init_sarif (diagnostic_context &context) { /* Suppress normal textual path output. */ - context->set_path_format (DPF_NONE); + context.set_path_format (DPF_NONE); /* Override callbacks. */ - context->set_ice_handler_callback (sarif_ice_handler); + context.set_ice_handler_callback (sarif_ice_handler); /* The metadata is handled in SARIF format, rather than as text. */ - context->set_show_cwe (false); - context->set_show_rules (false); + context.set_show_cwe (false); + context.set_show_rules (false); /* The option is handled in SARIF format, rather than as text. */ - context->set_show_option_requested (false); + context.set_show_option_requested (false); /* Don't colorize the text. */ - pp_show_color (context->printer) = false; - context->set_show_highlight_colors (false); + pp_show_color (context.printer) = false; + context.set_show_highlight_colors (false); } /* Populate CONTEXT in preparation for SARIF output to stderr. */ void -diagnostic_output_format_init_sarif_stderr (diagnostic_context *context, +diagnostic_output_format_init_sarif_stderr (diagnostic_context &context, const char *main_input_filename_, bool formatted) { diagnostic_output_format_init_sarif (context); - context->set_output_format - (new sarif_stream_output_format (*context, + context.set_output_format + (new sarif_stream_output_format (context, main_input_filename_, formatted, stderr)); @@ -2232,14 +2232,14 @@ diagnostic_output_format_init_sarif_stderr (diagnostic_context *context, BASE_FILE_NAME.sarif. */ void -diagnostic_output_format_init_sarif_file (diagnostic_context *context, +diagnostic_output_format_init_sarif_file (diagnostic_context &context, const char *main_input_filename_, bool formatted, const char *base_file_name) { diagnostic_output_format_init_sarif (context); - context->set_output_format - (new sarif_file_output_format (*context, + context.set_output_format + (new sarif_file_output_format (context, main_input_filename_, formatted, base_file_name)); @@ -2248,14 +2248,14 @@ diagnostic_output_format_init_sarif_file (diagnostic_context *context, /* Populate CONTEXT in preparation for SARIF output to STREAM. */ void -diagnostic_output_format_init_sarif_stream (diagnostic_context *context, +diagnostic_output_format_init_sarif_stream (diagnostic_context &context, const char *main_input_filename_, bool formatted, FILE *stream) { diagnostic_output_format_init_sarif (context); - context->set_output_format - (new sarif_stream_output_format (*context, + context.set_output_format + (new sarif_stream_output_format (context, main_input_filename_, formatted, stream)); diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index 196f34d9a2f4..aa8afd521fa2 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -1800,7 +1800,7 @@ diagnostic_text_output_format::on_diagram (const diagnostic_diagram &diagram) file-based output formats. */ void -diagnostic_output_format_init (diagnostic_context *context, +diagnostic_output_format_init (diagnostic_context &context, const char *main_input_filename_, const char *base_file_name, enum diagnostics_output_format format, diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index cb58bc63c2c3..84044b90dfcd 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -1091,24 +1091,24 @@ extern char *file_name_as_prefix (diagnostic_context *, const char *); extern char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1; -extern void diagnostic_output_format_init (diagnostic_context *, +extern void diagnostic_output_format_init (diagnostic_context &, const char *main_input_filename_, const char *base_file_name, enum diagnostics_output_format, bool json_formatting); -extern void diagnostic_output_format_init_json_stderr (diagnostic_context *context, +extern void diagnostic_output_format_init_json_stderr (diagnostic_context &context, bool formatted); -extern void diagnostic_output_format_init_json_file (diagnostic_context *context, +extern void diagnostic_output_format_init_json_file (diagnostic_context &context, bool formatted, const char *base_file_name); -extern void diagnostic_output_format_init_sarif_stderr (diagnostic_context *context, +extern void diagnostic_output_format_init_sarif_stderr (diagnostic_context &context, const char *main_input_filename_, bool formatted); -extern void diagnostic_output_format_init_sarif_file (diagnostic_context *context, +extern void diagnostic_output_format_init_sarif_file (diagnostic_context &context, const char *main_input_filename_, bool formatted, const char *base_file_name); -extern void diagnostic_output_format_init_sarif_stream (diagnostic_context *context, +extern void diagnostic_output_format_init_sarif_stream (diagnostic_context &context, const char *main_input_filename_, bool formatted, FILE *stream); @@ -1116,9 +1116,6 @@ extern void diagnostic_output_format_init_sarif_stream (diagnostic_context *cont /* Compute the number of digits in the decimal representation of an integer. */ extern int num_digits (int); -extern json::value *json_from_expanded_location (diagnostic_context *context, - location_t loc); - inline bool warning_enabled_at (location_t loc, int opt) { diff --git a/gcc/gcc.cc b/gcc/gcc.cc index 00f93d00f969..abdb40bfe6e0 100644 --- a/gcc/gcc.cc +++ b/gcc/gcc.cc @@ -4358,7 +4358,8 @@ driver_handle_option (struct gcc_options *opts, { const char *basename = (opts->x_dump_base_name ? opts->x_dump_base_name : opts->x_main_input_basename); - diagnostic_output_format_init (dc, + gcc_assert (dc); + diagnostic_output_format_init (*dc, opts->x_main_input_filename, basename, (enum diagnostics_output_format)value, opts->x_flag_diagnostics_json_formatting); diff --git a/gcc/opts.cc b/gcc/opts.cc index be90a632338f..0b7b137c3763 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -2963,7 +2963,8 @@ common_handle_option (struct gcc_options *opts, { const char *basename = (opts->x_dump_base_name ? opts->x_dump_base_name : opts->x_main_input_basename); - diagnostic_output_format_init (dc, + gcc_assert (dc); + diagnostic_output_format_init (*dc, opts->x_main_input_filename, basename, (enum diagnostics_output_format)value, opts->x_flag_diagnostics_json_formatting); From patchwork Wed Jul 24 22:18:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964557 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=NyRAkmeO; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpN44qTzz1ybY for ; Thu, 25 Jul 2024 08:19:32 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B2F11385DDCB for ; Wed, 24 Jul 2024 22:19:30 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id EF9FB385B82F for ; Wed, 24 Jul 2024 22:18:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EF9FB385B82F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org EF9FB385B82F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859532; cv=none; b=BjjW7M0GkWMGaNY1KVE3Ojr34zKucL4ryyw2xg+BHt+vCGIPem5dBxunsjnxqwGs6QChRh57a8cIRf3SIC9tHW6IIBPpVllU33CssNdXa6XiAu88CkTNbSwlEAEwkiWFc+FqAs2VmHnlylD7fFOOa3p7yTRvp8sURd52GB34Z9I= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859532; c=relaxed/simple; bh=fGtfB/hiHzR6xbqrTeTz+eOWLUj7cXo+2xXEtBRha3E=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=C4jmmongPvz3591iauBEeMvYFXwBT/h+1/NuYurdYdlEfeIUPxxsoq4e2+kKzgUbvWRGwn1CGjWVM653kBiNMJGY9mKuBXPgrDiV5IZsnW9EfpCrCXSPwnexN6WL7Gg6B9l/k9e4vPU8iL3UKk4Mfq0ZkGoz8dCJYjizyyYaXX4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859529; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NlSh/1kfhvjLb3/CAb8uNV436UfRwvIngVox1/o5sJQ=; b=NyRAkmeOHcn79GbRzNe2L2yuMtZtGQBNDsSsxDnFHsEodS4Qri6Tp+HQGRQnhfPW0Z4dAf 8mRVwzTGTZI+oGMDr0w1AFLihACh13gk0uo95avL+DIPl1ABwCvM5JKDlwC/seeHPVy7Ar LC+CrzmHV0mI+xlRR188QpuoDXiy8QQ= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-631-QZ1hFtkYOO6MFC7eZztIFA-1; Wed, 24 Jul 2024 18:18:48 -0400 X-MC-Unique: QZ1hFtkYOO6MFC7eZztIFA-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8034F1954227 for ; Wed, 24 Jul 2024 22:18:47 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 64EF11955F40; Wed, 24 Jul 2024 22:18:45 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 07/16] json: support std::unique_ptr in array::append and object::set Date: Wed, 24 Jul 2024 18:18:15 -0400 Message-Id: <20240724221824.585054-8-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org This patch uses templates to add overloads of json::array::append and json::object::set taking std::unique_ptr where T is a subclass of json::value. Doing so makes it much easier to track memory ownership and enforce schema validity when constructing non-trivial JSON; using the wrong kind of JSON value leads to compile-time errors like the following: error: cannot convert ‘unique_ptr’ to ‘unique_ptr’ 629 | location_obj->set ("message", std::move (message_obj)); | ~~~~~~~~~~^~~~~~~~~~~~~ | | | unique_ptr No functional change intended. gcc/ChangeLog: * diagnostic-format-json.cc: Define INCLUDE_MEMORY. * diagnostic-format-sarif.cc: Likewise. * dumpfile.cc: Likewise. * gcov.cc: Likewise. * json.cc: Likewise. Include "make-unique.h". (selftest::test_formatting): Exercise overloads of array::append and object::set that use unique_ptr. * json.h: Require INCLUDE_MEMORY to have been defined. (json::object::set): Add a template to add a family of overloads taking a std::unique_ptr (json::array::append): Likewise. * optinfo-emit-json.cc: Define INCLUDE_MEMORY. * optinfo.cc: Likewise. * timevar.cc: Likewise. * toplev.cc: Likewise. * tree-diagnostic-client-data-hooks.cc: Likewise. Signed-off-by: David Malcolm --- gcc/diagnostic-format-json.cc | 1 + gcc/diagnostic-format-sarif.cc | 1 + gcc/dumpfile.cc | 1 + gcc/gcov.cc | 1 + gcc/json.cc | 17 +++++++---- gcc/json.h | 38 ++++++++++++++++++++++++ gcc/optinfo-emit-json.cc | 1 + gcc/optinfo.cc | 1 + gcc/timevar.cc | 1 + gcc/toplev.cc | 1 + gcc/tree-diagnostic-client-data-hooks.cc | 1 + 11 files changed, 58 insertions(+), 6 deletions(-) diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc index 1bf8da663cc2..55ba39e0c532 100644 --- a/gcc/diagnostic-format-json.cc +++ b/gcc/diagnostic-format-json.cc @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "diagnostic.h" diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index d6de5806f5ac..6aba81c6ac9b 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" +#define INCLUDE_MEMORY #define INCLUDE_VECTOR #include "system.h" #include "coretypes.h" diff --git a/gcc/dumpfile.cc b/gcc/dumpfile.cc index 82bd8b06bebf..6353c0857449 100644 --- a/gcc/dumpfile.cc +++ b/gcc/dumpfile.cc @@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see . */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "options.h" diff --git a/gcc/gcov.cc b/gcc/gcov.cc index 85fdac4368e8..aa016c658ce0 100644 --- a/gcc/gcov.cc +++ b/gcc/gcov.cc @@ -32,6 +32,7 @@ along with Gcov; see the file COPYING3. If not see #include "config.h" #define INCLUDE_ALGORITHM +#define INCLUDE_MEMORY #define INCLUDE_VECTOR #define INCLUDE_STRING #define INCLUDE_MAP diff --git a/gcc/json.cc b/gcc/json.cc index 86490259dabf..275ef486faf1 100644 --- a/gcc/json.cc +++ b/gcc/json.cc @@ -19,11 +19,13 @@ along with GCC; see the file COPYING3. If not see . */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "json.h" #include "pretty-print.h" #include "math.h" +#include "make-unique.h" #include "selftest.h" using namespace json; @@ -499,28 +501,31 @@ test_writing_literals () ASSERT_PRINT_EQ (literal (false), true, "false"); } -/* Verify that nested values are formatted correctly when written. */ +/* Verify that nested values are formatted correctly when written. + + Also, make use of array::append(std::unique_ptr) and + object::set (const char *key, std::unique_ptr v).*/ static void test_formatting () { object obj; object *child = new object; - object *grandchild = new object; + std::unique_ptr grandchild = ::make_unique (); obj.set_string ("str", "bar"); obj.set ("child", child); obj.set_integer ("int", 42); - child->set ("grandchild", grandchild); - child->set_integer ("int", 1776); - array *arr = new array; for (int i = 0; i < 3; i++) - arr->append (new integer_number (i)); + arr->append (::make_unique (i)); grandchild->set ("arr", arr); grandchild->set_integer ("int", 1066); + child->set ("grandchild", std::move (grandchild)); + child->set_integer ("int", 1776); + /* This test relies on json::object writing out key/value pairs in key-insertion order. */ ASSERT_PRINT_EQ (obj, true, diff --git a/gcc/json.h b/gcc/json.h index d3493a72d525..f80a5e82caf3 100644 --- a/gcc/json.h +++ b/gcc/json.h @@ -21,6 +21,15 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_JSON_H #define GCC_JSON_H +/* This header uses std::unique_ptr, but can't be directly + included due to issues with macros. Hence must be included + from system.h by defining INCLUDE_MEMORY in any source file using + json.h. */ + +#ifndef INCLUDE_MEMORY +# error "You must define INCLUDE_MEMORY before including system.h to use make-unique.h" +#endif + /* Implementation of JSON, a lightweight data-interchange format. See http://www.json.org/ @@ -101,6 +110,21 @@ class object : public value void print (pretty_printer *pp, bool formatted) const final override; void set (const char *key, value *v); + + /* Set the property KEY of this object, requiring V + to be of a specific json::value subclass. + + This can be used to enforce type-checking, making it easier + to comply with a schema, e.g. + obj->set ("property_name", value) + leading to a compile-time error if VALUE is not of the + appropriate subclass. */ + template + void set (const char *key, std::unique_ptr v) + { + set (key, v.release ()); + } + value *get (const char *key) const; void set_string (const char *key, const char *utf8_value); @@ -132,6 +156,20 @@ class array : public value void append (value *v); void append_string (const char *utf8_value); + /* Append V to this array, requiring V + to be a specific json::value subclass. + + This can be used to enforce type-checking, making it easier + to comply with a schema, e.g. + arr->append (value) + leading to a compile-time error if VALUE is not of the + appropriate subclass. */ + template + void append (std::unique_ptr v) + { + append (v.release ()); + } + private: auto_vec m_elements; }; diff --git a/gcc/optinfo-emit-json.cc b/gcc/optinfo-emit-json.cc index faae95fc232a..87a05a72dd3c 100644 --- a/gcc/optinfo-emit-json.cc +++ b/gcc/optinfo-emit-json.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see . */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" diff --git a/gcc/optinfo.cc b/gcc/optinfo.cc index 3048581cf074..7a8256171744 100644 --- a/gcc/optinfo.cc +++ b/gcc/optinfo.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see . */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" diff --git a/gcc/timevar.cc b/gcc/timevar.cc index 36d95336949d..68bcf44864f9 100644 --- a/gcc/timevar.cc +++ b/gcc/timevar.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see . */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "timevar.h" diff --git a/gcc/toplev.cc b/gcc/toplev.cc index 8933a89bd281..d9e8b34ae7ca 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see Error messages and low-level interface to malloc also handled here. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "backend.h" diff --git a/gcc/tree-diagnostic-client-data-hooks.cc b/gcc/tree-diagnostic-client-data-hooks.cc index 3e8b031e2cc5..a2e4a5c97bd5 100644 --- a/gcc/tree-diagnostic-client-data-hooks.cc +++ b/gcc/tree-diagnostic-client-data-hooks.cc @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see . */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "version.h" From patchwork Wed Jul 24 22:18:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964563 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=FNsK3XC/; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpPw1Lm0z1yY9 for ; Thu, 25 Jul 2024 08:21:08 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6A741385DDD3 for ; Wed, 24 Jul 2024 22:21:06 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id D709D385DDEC for ; Wed, 24 Jul 2024 22:18:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D709D385DDEC Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D709D385DDEC Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859538; cv=none; b=J00KpAjx6HFmNNTjJyewME6nS+JDZm9dx/9ORuP2uEA9jhxfzxpdwXH1hX8r2N8GBQk/OCJRdS/HQyUknSnZQLg3BXY9JSDEqg7LQujhtSigpjNtMgpeGVe/7codORL1JgapAlf8QXO8vGnJgixklfBL17pOZvOwc2duv4J0gGU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859538; c=relaxed/simple; bh=EtganRH9pzFFANnOvTarHF3oSstUzqCr5M/tW2lJvhE=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=M95c6GP3b2C0dQocdPvA2OEMPG70gwv89dAKtJysr359eNFIxmkrs7FcZFVPLWZuZzshBrhkMLIIBSYMt9njqKSDJ1XM5aSFyxszBHl6FhFXcpW/SqzgMsyhph9+IkhtSiXskzG31nyEZQqVsb1LXdBp1CAqTOgZNMf/DzJ9Tnk= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859531; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VP2sD2Q3dkgaOlMh3o9zpKEDbq7t/ZEcmAelZtuWoRI=; b=FNsK3XC/MIDGBrrXDKzitwY3ux7EgYEYdmbwFIIjms55+TV8j4WpiNPE3lnRls0xyl/xyL My7bWKEs/xcjip+27vE9Z1fMvweAsvIl7eemr91NH3KzhqJSuHzvpuwCdrK/2D0q38zeLy pfNdRGVr+Y7M10Ms53gvz7KVWy/FXTM= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-352-wexw3pcyPJOQT8uJpda6Sg-1; Wed, 24 Jul 2024 18:18:50 -0400 X-MC-Unique: wexw3pcyPJOQT8uJpda6Sg-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 151741956048 for ; Wed, 24 Jul 2024 22:18:49 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CAE8A1955E7D; Wed, 24 Jul 2024 22:18:47 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 08/16] diagnostics: SARIF output: use std::unique_ptr throughout Date: Wed, 24 Jul 2024 18:18:16 -0400 Message-Id: <20240724221824.585054-9-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_FILL_THIS_FORM_SHORT, URIBL_SBL_A autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org No functional change intended. gcc/analyzer/ChangeLog: * checker-event.cc (maybe_add_sarif_properties): Update setting of "original_fndecl" to use typesafe unique_ptr variant of json::object::set. gcc/ChangeLog: * diagnostic-format-sarif.cc: Include "make-unique.h". Convert raw pointers to std::unique_ptr throughout to indicate ownership, adding comments in the few places where pointers are borrowed. Use typesafe unique_ptr variants of json::object::set and json::array::append throughout to make types of properties more explicit, whilst using "auto" to reduce typing. Use "nullptr" rather than "NULL" throughout. * diagnostic-format-sarif.h (make_sarif_logical_location_object): Use std::unique_ptr for return type. Signed-off-by: David Malcolm --- gcc/analyzer/checker-event.cc | 5 +- gcc/diagnostic-format-sarif.cc | 667 ++++++++++++++++----------------- gcc/diagnostic-format-sarif.h | 2 +- 3 files changed, 337 insertions(+), 337 deletions(-) diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc index 593f364e1d66..2f1438c983a5 100644 --- a/gcc/analyzer/checker-event.cc +++ b/gcc/analyzer/checker-event.cc @@ -161,8 +161,9 @@ maybe_add_sarif_properties (sarif_object &thread_flow_loc_obj) const if (m_original_fndecl != m_effective_fndecl) { tree_logical_location logical_loc (m_original_fndecl); - props.set (PROPERTY_PREFIX "original_fndecl", - make_sarif_logical_location_object (logical_loc)); + props.set + (PROPERTY_PREFIX "original_fndecl", + make_sarif_logical_location_object (logical_loc)); } if (m_original_depth != m_effective_depth) props.set_integer (PROPERTY_PREFIX "original_depth", m_original_depth); diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 6aba81c6ac9b..6f61d89363f2 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-format-sarif.h" #include "ordered-hash-map.h" #include "sbitmap.h" +#include "make-unique.h" /* Forward decls. */ class sarif_builder; @@ -125,7 +126,7 @@ public: void prepare_to_flush (diagnostic_context &context); private: - json::array *m_notifications_arr; + std::unique_ptr m_notifications_arr; bool m_success; }; @@ -180,7 +181,7 @@ private: class sarif_result : public sarif_object { public: - sarif_result () : m_related_locations_arr (NULL) {} + sarif_result () : m_related_locations_arr (nullptr) {} void on_nested_diagnostic (diagnostic_context &context, @@ -193,9 +194,9 @@ public: private: void - add_related_location (sarif_location *location_obj); + add_related_location (std::unique_ptr location_obj); - json::array *m_related_locations_arr; + json::array *m_related_locations_arr; // borrowed }; /* Subclass of sarif_object for SARIF "location" objects @@ -226,10 +227,12 @@ class sarif_thread_flow : public sarif_object public: sarif_thread_flow (const diagnostic_thread &thread); - void add_location (sarif_thread_flow_location *thread_flow_loc_obj); + void + add_location + (std::unique_ptr thread_flow_loc_obj); private: - json::array *m_locations_arr; + json::array *m_locations_arr; // borrowed }; /* Subclass of sarif_object for SARIF "threadFlowLocation" objects @@ -340,80 +343,81 @@ public: void flush_to_file (FILE *outf); - json::array *make_locations_arr (const diagnostic_info &diagnostic, - enum diagnostic_artifact_role role); - sarif_location * + std::unique_ptr + make_locations_arr (const diagnostic_info &diagnostic, + enum diagnostic_artifact_role role); + std::unique_ptr make_location_object (const rich_location &rich_loc, const logical_location *logical_loc, enum diagnostic_artifact_role role); - sarif_message * + std::unique_ptr make_message_object (const char *msg) const; - sarif_message * + std::unique_ptr make_message_object_for_diagram (diagnostic_context &context, const diagnostic_diagram &diagram); - sarif_artifact_content * + std::unique_ptr maybe_make_artifact_content_object (const char *filename) const; private: - sarif_result * + std::unique_ptr make_result_object (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind); void - set_any_logical_locs_arr (sarif_location *location_obj, + set_any_logical_locs_arr (sarif_location &location_obj, const logical_location *logical_loc); - sarif_location * + std::unique_ptr make_location_object (const diagnostic_event &event, enum diagnostic_artifact_role role); - sarif_code_flow * + std::unique_ptr make_code_flow_object (const diagnostic_path &path); - sarif_thread_flow_location * + std::unique_ptr make_thread_flow_location_object (const diagnostic_event &event, int path_event_idx); - json::array * + std::unique_ptr maybe_make_kinds_array (diagnostic_event::meaning m) const; - sarif_physical_location * + std::unique_ptr maybe_make_physical_location_object (location_t loc, enum diagnostic_artifact_role role, int column_override); - sarif_artifact_location * + std::unique_ptr make_artifact_location_object (location_t loc); - sarif_artifact_location * + std::unique_ptr make_artifact_location_object (const char *filename); - sarif_artifact_location * + std::unique_ptr make_artifact_location_object_for_pwd () const; - sarif_region * + std::unique_ptr maybe_make_region_object (location_t loc, int column_override) const; - sarif_region * + std::unique_ptr maybe_make_region_object_for_context (location_t loc) const; - sarif_region * + std::unique_ptr make_region_object_for_hint (const fixit_hint &hint) const; - sarif_multiformat_message_string * + std::unique_ptr make_multiformat_message_string (const char *msg) const; - sarif_log * - make_top_level_object (sarif_invocation *invocation_obj, - json::array *results); - sarif_run * - make_run_object (sarif_invocation *invocation_obj, - json::array *results); - sarif_tool * + std::unique_ptr + make_top_level_object (std::unique_ptr invocation_obj, + std::unique_ptr results); + std::unique_ptr + make_run_object (std::unique_ptr invocation_obj, + std::unique_ptr results); + std::unique_ptr make_tool_object () const; - sarif_tool_component * + std::unique_ptr make_driver_tool_component_object () const; - json::array *maybe_make_taxonomies_array () const; - sarif_tool_component * + std::unique_ptr maybe_make_taxonomies_array () const; + std::unique_ptr maybe_make_cwe_taxonomy_object () const; - sarif_tool_component_reference * + std::unique_ptr make_tool_component_reference_object_for_cwe () const; - sarif_reporting_descriptor * + std::unique_ptr make_reporting_descriptor_object_for_warning (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind, const char *option_text); - sarif_reporting_descriptor * + std::unique_ptr make_reporting_descriptor_object_for_cwe_id (int cwe_id) const; - sarif_reporting_descriptor_reference * + std::unique_ptr make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id); sarif_artifact & get_or_create_artifact (const char *filename, @@ -423,34 +427,37 @@ private: get_source_lines (const char *filename, int start_line, int end_line) const; - sarif_artifact_content * + std::unique_ptr maybe_make_artifact_content_object (const char *filename, int start_line, int end_line) const; - sarif_fix * + std::unique_ptr make_fix_object (const rich_location &rich_loc); - sarif_artifact_change * + std::unique_ptr make_artifact_change_object (const rich_location &richloc); - sarif_replacement * + std::unique_ptr make_replacement_object (const fixit_hint &hint) const; - sarif_artifact_content * + std::unique_ptr make_artifact_content_object (const char *text) const; int get_sarif_column (expanded_location exploc) const; diagnostic_context &m_context; /* The JSON object for the invocation object. */ - sarif_invocation *m_invocation_obj; + std::unique_ptr m_invocation_obj; /* The JSON array of pending diagnostics. */ - json::array *m_results_array; + std::unique_ptr m_results_array; /* The JSON object for the result object (if any) in the current diagnostic group. */ - sarif_result *m_cur_group_result; + sarif_result *m_cur_group_result; // borrowed + /* Ideally we'd use std::unique_ptr here, but I had + trouble getting this to work when building with GCC 4.8. */ ordered_hash_map m_filename_to_artifact_map; + bool m_seen_any_relative_paths; hash_set m_rule_id_set; json::array *m_rules_arr; @@ -483,7 +490,7 @@ sarif_object::get_or_create_properties () /* class sarif_invocation : public sarif_object. */ sarif_invocation::sarif_invocation () -: m_notifications_arr (new json::array ()), +: m_notifications_arr (::make_unique ()), m_success (true) { } @@ -498,9 +505,8 @@ sarif_invocation::add_notification_for_ice (diagnostic_context &context, { m_success = false; - sarif_ice_notification *notification_obj - = new sarif_ice_notification (context, diagnostic, builder); - m_notifications_arr->append (notification_obj); + m_notifications_arr->append + (::make_unique (context, diagnostic, builder)); } void @@ -510,7 +516,7 @@ sarif_invocation::prepare_to_flush (diagnostic_context &context) set_bool ("executionSuccessful", m_success); /* "toolExecutionNotifications" property (SARIF v2.1.0 section 3.20.21). */ - set ("toolExecutionNotifications", m_notifications_arr); + set ("toolExecutionNotifications", std::move (m_notifications_arr)); /* Call client hook, allowing it to create a custom property bag for this object (SARIF v2.1.0 section 3.8) e.g. for recording time vars. */ @@ -552,9 +558,9 @@ sarif_artifact::add_role (enum diagnostic_artifact_role role, void sarif_artifact::populate_contents (sarif_builder &builder) { - if (sarif_artifact_content *artifact_content_obj + if (auto artifact_content_obj = builder.maybe_make_artifact_content_object (m_filename)) - set ("contents", artifact_content_obj); + set ("contents", std::move (artifact_content_obj)); } /* Get a string for ROLE corresponding to the @@ -588,14 +594,14 @@ sarif_artifact::populate_roles () { if (bitmap_empty_p (m_roles)) return; - json::array *roles_arr = new json::array (); + auto roles_arr (::make_unique ()); for (int i = 0; i < (int)diagnostic_artifact_role::NUM_ROLES; i++) if (bitmap_bit_p (m_roles, i)) { enum diagnostic_artifact_role role = (enum diagnostic_artifact_role)i; roles_arr->append_string (get_artifact_role_string (role)); } - set ("roles", roles_arr); + set ("roles", std::move (roles_arr)); } /* class sarif_result : public sarif_object. */ @@ -615,15 +621,15 @@ sarif_result::on_nested_diagnostic (diagnostic_context &context, /* We don't yet generate meaningful logical locations for notes; sometimes these will related to current_function_decl, but often they won't. */ - sarif_location *location_obj - = builder.make_location_object (*diagnostic.richloc, NULL, + auto location_obj + = builder.make_location_object (*diagnostic.richloc, nullptr, diagnostic_artifact_role::result_file); - sarif_message *message_obj + auto message_obj = builder.make_message_object (pp_formatted_text (context.printer)); pp_clear_output_area (context.printer); - location_obj->set ("message", message_obj); + location_obj->set ("message", std::move (message_obj)); - add_related_location (location_obj); + add_related_location (std::move (location_obj)); } /* Handle diagrams that occur within a diagnostic group. @@ -637,26 +643,29 @@ sarif_result::on_diagram (diagnostic_context &context, const diagnostic_diagram &diagram, sarif_builder &builder) { - sarif_location *location_obj = new sarif_location (); - sarif_message *message_obj + auto location_obj = ::make_unique (); + auto message_obj = builder.make_message_object_for_diagram (context, diagram); - location_obj->set ("message", message_obj); + location_obj->set ("message", std::move (message_obj)); - add_related_location (location_obj); + add_related_location (std::move (location_obj)); } /* Add LOCATION_OBJ to this result's "relatedLocations" array, creating it if it doesn't yet exist. */ void -sarif_result::add_related_location (sarif_location *location_obj) +sarif_result:: +add_related_location (std::unique_ptr location_obj) { if (!m_related_locations_arr) { m_related_locations_arr = new json::array (); + /* Give ownership of m_related_locations_arr to json::object; + keep a borrowed ptr. */ set ("relatedLocations", m_related_locations_arr); } - m_related_locations_arr->append (location_obj); + m_related_locations_arr->append (std::move (location_obj)); } /* class sarif_ice_notification : public sarif_object. */ @@ -669,16 +678,16 @@ sarif_ice_notification::sarif_ice_notification (diagnostic_context &context, sarif_builder &builder) { /* "locations" property (SARIF v2.1.0 section 3.58.4). */ - json::array *locations_arr + auto locations_arr = builder.make_locations_arr (diagnostic, diagnostic_artifact_role::result_file); - set ("locations", locations_arr); + set ("locations", std::move (locations_arr)); /* "message" property (SARIF v2.1.0 section 3.85.5). */ - sarif_message *message_obj + auto message_obj = builder.make_message_object (pp_formatted_text (context.printer)); pp_clear_output_area (context.printer); - set ("message", message_obj); + set ("message", std::move (message_obj)); /* "level" property (SARIF v2.1.0 section 3.58.6). */ set_string ("level", "error"); @@ -694,14 +703,17 @@ sarif_thread_flow::sarif_thread_flow (const diagnostic_thread &thread) /* "locations" property (SARIF v2.1.0 section 3.37.6). */ m_locations_arr = new json::array (); + + /* Give ownership of m_locations_arr to json::object; + keep a borrowed ptr. */ set ("locations", m_locations_arr); } void sarif_thread_flow:: -add_location (sarif_thread_flow_location *thread_flow_loc_obj) +add_location (std::unique_ptr thread_flow_loc_obj) { - m_locations_arr->append (thread_flow_loc_obj); + m_locations_arr->append (std::move (thread_flow_loc_obj)); } /* class sarif_builder. */ @@ -712,9 +724,9 @@ sarif_builder::sarif_builder (diagnostic_context &context, const char *main_input_filename_, bool formatted) : m_context (context), - m_invocation_obj (new sarif_invocation ()), + m_invocation_obj (::make_unique ()), m_results_array (new json::array ()), - m_cur_group_result (NULL), + m_cur_group_result (nullptr), m_seen_any_relative_paths (false), m_rule_id_set (), m_rules_arr (new json::array ()), @@ -754,10 +766,10 @@ sarif_builder::end_diagnostic (diagnostic_context &context, else { /* Top-level diagnostic. */ - sarif_result *result_obj + std::unique_ptr result_obj = make_result_object (context, diagnostic, orig_diag_kind); - m_results_array->append (result_obj); - m_cur_group_result = result_obj; + m_cur_group_result = result_obj.get (); // borrowed + m_results_array->append (std::move (result_obj)); } } @@ -778,7 +790,7 @@ sarif_builder::emit_diagram (diagnostic_context &context, void sarif_builder::end_group () { - m_cur_group_result = NULL; + m_cur_group_result = nullptr; } /* Create a top-level object, and add it to all the results @@ -790,18 +802,18 @@ void sarif_builder::flush_to_file (FILE *outf) { m_invocation_obj->prepare_to_flush (m_context); - sarif_log *top = make_top_level_object (m_invocation_obj, m_results_array); + std::unique_ptr top + = make_top_level_object (std::move (m_invocation_obj), + std::move (m_results_array)); top->dump (outf, m_formatted); - m_invocation_obj = NULL; - m_results_array = NULL; + m_invocation_obj = nullptr; fprintf (outf, "\n"); - delete top; } /* Attempt to convert DIAG_KIND to a suitable value for the "level" property (SARIF v2.1.0 section 3.27.10). - Return NULL if there isn't one. */ + Return nullptr if there isn't one. */ static const char * maybe_get_sarif_level (diagnostic_t diag_kind) @@ -816,7 +828,7 @@ maybe_get_sarif_level (diagnostic_t diag_kind) case DK_ANACHRONISM: return "note"; default: - return NULL; + return nullptr; } } @@ -840,12 +852,12 @@ make_rule_id_for_diagnostic_kind (diagnostic_t diag_kind) /* Make a "result" object (SARIF v2.1.0 section 3.27) for DIAGNOSTIC. */ -sarif_result * +std::unique_ptr sarif_builder::make_result_object (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind) { - sarif_result *result_obj = new sarif_result (); + auto result_obj = ::make_unique (); /* "ruleId" property (SARIF v2.1.0 section 3.27.5). */ /* Ideally we'd have an option_name for these. */ @@ -864,12 +876,11 @@ sarif_builder::make_result_object (diagnostic_context &context, /* Add to set, taking ownership. */ m_rule_id_set.add (option_text); - sarif_reporting_descriptor *reporting_desc_obj - = make_reporting_descriptor_object_for_warning (context, - diagnostic, - orig_diag_kind, - option_text); - m_rules_arr->append (reporting_desc_obj); + m_rules_arr->append + (make_reporting_descriptor_object_for_warning (context, + diagnostic, + orig_diag_kind, + option_text)); } } else @@ -888,11 +899,10 @@ sarif_builder::make_result_object (diagnostic_context &context, /* "taxa" property (SARIF v2.1.0 section 3.27.8). */ if (int cwe_id = diagnostic.metadata->get_cwe ()) { - json::array *taxa_arr = new json::array (); - sarif_reporting_descriptor_reference *cwe_id_obj - = make_reporting_descriptor_reference_object_for_cwe_id (cwe_id); - taxa_arr->append (cwe_id_obj); - result_obj->set ("taxa", taxa_arr); + auto taxa_arr = ::make_unique (); + taxa_arr->append + (make_reporting_descriptor_reference_object_for_cwe_id (cwe_id)); + result_obj->set ("taxa", std::move (taxa_arr)); } diagnostic.metadata->maybe_add_sarif_properties (*result_obj); @@ -903,24 +913,22 @@ sarif_builder::make_result_object (diagnostic_context &context, result_obj->set_string ("level", sarif_level); /* "message" property (SARIF v2.1.0 section 3.27.11). */ - sarif_message *message_obj + auto message_obj = make_message_object (pp_formatted_text (context.printer)); pp_clear_output_area (context.printer); - result_obj->set ("message", message_obj); + result_obj->set ("message", std::move (message_obj)); /* "locations" property (SARIF v2.1.0 section 3.27.12). */ - json::array *locations_arr - = make_locations_arr (diagnostic, - diagnostic_artifact_role::result_file); - result_obj->set ("locations", locations_arr); + result_obj->set + ("locations", + make_locations_arr (diagnostic, diagnostic_artifact_role::result_file)); /* "codeFlows" property (SARIF v2.1.0 section 3.27.18). */ if (const diagnostic_path *path = diagnostic.richloc->get_path ()) { - json::array *code_flows_arr = new json::array (); - sarif_code_flow *code_flow_obj = make_code_flow_object (*path); - code_flows_arr->append (code_flow_obj); - result_obj->set ("codeFlows", code_flows_arr); + auto code_flows_arr = ::make_unique (); + code_flows_arr->append (make_code_flow_object (*path)); + result_obj->set ("codeFlows", std::move (code_flows_arr)); } /* The "relatedLocations" property (SARIF v2.1.0 section 3.27.22) is @@ -931,10 +939,9 @@ sarif_builder::make_result_object (diagnostic_context &context, const rich_location *richloc = diagnostic.richloc; if (richloc->get_num_fixit_hints ()) { - json::array *fix_arr = new json::array (); - sarif_fix *fix_obj = make_fix_object (*richloc); - fix_arr->append (fix_obj); - result_obj->set ("fixes", fix_arr); + auto fix_arr = ::make_unique (); + fix_arr->append (make_fix_object (*richloc)); + result_obj->set ("fixes", std::move (fix_arr)); } return result_obj; @@ -943,15 +950,14 @@ sarif_builder::make_result_object (diagnostic_context &context, /* Make a "reportingDescriptor" object (SARIF v2.1.0 section 3.49) for a GCC warning. */ -sarif_reporting_descriptor * +std::unique_ptr sarif_builder:: make_reporting_descriptor_object_for_warning (diagnostic_context &context, const diagnostic_info &diagnostic, diagnostic_t /*orig_diag_kind*/, const char *option_text) { - sarif_reporting_descriptor *reporting_desc - = new sarif_reporting_descriptor (); + auto reporting_desc = ::make_unique (); /* "id" property (SARIF v2.1.0 section 3.49.3). */ reporting_desc->set_string ("id", option_text); @@ -972,11 +978,10 @@ make_reporting_descriptor_object_for_warning (diagnostic_context &context, /* Make a "reportingDescriptor" object (SARIF v2.1.0 section 3.49) for CWE_ID, for use within the CWE taxa array. */ -sarif_reporting_descriptor * +std::unique_ptr sarif_builder::make_reporting_descriptor_object_for_cwe_id (int cwe_id) const { - sarif_reporting_descriptor *reporting_desc - = new sarif_reporting_descriptor (); + auto reporting_desc = ::make_unique (); /* "id" property (SARIF v2.1.0 section 3.49.3). */ { @@ -999,12 +1004,11 @@ sarif_builder::make_reporting_descriptor_object_for_cwe_id (int cwe_id) const referencing CWE_ID, for use within a result object. Also, add CWE_ID to m_cwe_id_set. */ -sarif_reporting_descriptor_reference * +std::unique_ptr sarif_builder:: make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id) { - sarif_reporting_descriptor_reference *desc_ref_obj - = new sarif_reporting_descriptor_reference (); + auto desc_ref_obj = ::make_unique (); /* "id" property (SARIF v2.1.0 section 3.52.4). */ { @@ -1014,9 +1018,8 @@ make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id) } /* "toolComponent" property (SARIF v2.1.0 section 3.52.7). */ - sarif_tool_component_reference *comp_ref_obj - = make_tool_component_reference_object_for_cwe (); - desc_ref_obj->set ("toolComponent", comp_ref_obj); + desc_ref_obj->set + ("toolComponent", make_tool_component_reference_object_for_cwe ()); /* Add CWE_ID to our set. */ gcc_assert (cwe_id > 0); @@ -1028,12 +1031,11 @@ make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id) /* Make a "toolComponentReference" object (SARIF v2.1.0 section 3.54) that references the CWE taxonomy. */ -sarif_tool_component_reference * +std::unique_ptr sarif_builder:: make_tool_component_reference_object_for_cwe () const { - sarif_tool_component_reference *comp_ref_obj - = new sarif_tool_component_reference (); + auto comp_ref_obj = ::make_unique (); /* "name" property (SARIF v2.1.0 section 3.54.3). */ comp_ref_obj->set_string ("name", "cwe"); @@ -1045,59 +1047,59 @@ make_tool_component_reference_object_for_cwe () const - a "result" object (SARIF v2.1.0 section 3.27.12), or - a "notification" object (SARIF v2.1.0 section 3.58.4). */ -json::array * +std::unique_ptr sarif_builder::make_locations_arr (const diagnostic_info &diagnostic, enum diagnostic_artifact_role role) { - json::array *locations_arr = new json::array (); - const logical_location *logical_loc = NULL; + auto locations_arr = ::make_unique (); + const logical_location *logical_loc = nullptr; if (auto client_data_hooks = m_context.get_client_data_hooks ()) logical_loc = client_data_hooks->get_current_logical_location (); - sarif_location *location_obj - = make_location_object (*diagnostic.richloc, logical_loc, role); - locations_arr->append (location_obj); + locations_arr->append + (make_location_object (*diagnostic.richloc, logical_loc, role)); return locations_arr; } -/* If LOGICAL_LOC is non-NULL, use it to create a "logicalLocations" property +/* If LOGICAL_LOC is non-null, use it to create a "logicalLocations" property within LOCATION_OBJ (SARIF v2.1.0 section 3.28.4). */ void sarif_builder:: -set_any_logical_locs_arr (sarif_location *location_obj, +set_any_logical_locs_arr (sarif_location &location_obj, const logical_location *logical_loc) { if (!logical_loc) return; - sarif_logical_location *logical_loc_obj - = make_sarif_logical_location_object (*logical_loc); - json::array *location_locs_arr = new json::array (); - location_locs_arr->append (logical_loc_obj); - location_obj->set ("logicalLocations", location_locs_arr); + auto location_locs_arr = ::make_unique (); + location_locs_arr->append + (make_sarif_logical_location_object (*logical_loc)); + location_obj.set ("logicalLocations", + std::move (location_locs_arr)); } /* Make a "location" object (SARIF v2.1.0 section 3.28) for RICH_LOC and LOGICAL_LOC. */ -sarif_location * +std::unique_ptr sarif_builder::make_location_object (const rich_location &rich_loc, const logical_location *logical_loc, enum diagnostic_artifact_role role) { - sarif_location *location_obj = new sarif_location (); + auto location_obj = ::make_unique (); /* Get primary loc from RICH_LOC. */ location_t loc = rich_loc.get_loc (); /* "physicalLocation" property (SARIF v2.1.0 section 3.28.3). */ - if (sarif_physical_location *phs_loc_obj + if (auto phs_loc_obj = maybe_make_physical_location_object (loc, role, rich_loc.get_column_override ())) - location_obj->set ("physicalLocation", phs_loc_obj); + location_obj->set ("physicalLocation", + std::move (phs_loc_obj)); /* "logicalLocations" property (SARIF v2.1.0 section 3.28.4). */ - set_any_logical_locs_arr (location_obj, logical_loc); + set_any_logical_locs_arr (*location_obj, logical_loc); return location_obj; } @@ -1105,26 +1107,26 @@ sarif_builder::make_location_object (const rich_location &rich_loc, /* Make a "location" object (SARIF v2.1.0 section 3.28) for EVENT within a diagnostic_path. */ -sarif_location * +std::unique_ptr sarif_builder::make_location_object (const diagnostic_event &event, enum diagnostic_artifact_role role) { - sarif_location *location_obj = new sarif_location (); + auto location_obj = ::make_unique (); /* "physicalLocation" property (SARIF v2.1.0 section 3.28.3). */ location_t loc = event.get_location (); - if (sarif_physical_location *phs_loc_obj - = maybe_make_physical_location_object (loc, role, 0)) - location_obj->set ("physicalLocation", phs_loc_obj); + if (auto phs_loc_obj = maybe_make_physical_location_object (loc, role, 0)) + location_obj->set ("physicalLocation", + std::move (phs_loc_obj)); /* "logicalLocations" property (SARIF v2.1.0 section 3.28.4). */ const logical_location *logical_loc = event.get_logical_location (); - set_any_logical_locs_arr (location_obj, logical_loc); + set_any_logical_locs_arr (*location_obj, logical_loc); /* "message" property (SARIF v2.1.0 section 3.28.5). */ label_text ev_desc = event.get_desc (false); - sarif_message *message_obj = make_message_object (ev_desc.get ()); - location_obj->set ("message", message_obj); + location_obj->set ("message", + make_message_object (ev_desc.get ())); return location_obj; } @@ -1138,32 +1140,30 @@ sarif_builder::make_location_object (const diagnostic_event &event, and flagging that we will attempt to embed the contents of the artifact when writing it out. */ -sarif_physical_location * +std::unique_ptr sarif_builder:: maybe_make_physical_location_object (location_t loc, enum diagnostic_artifact_role role, int column_override) { - if (loc <= BUILTINS_LOCATION || LOCATION_FILE (loc) == NULL) - return NULL; + if (loc <= BUILTINS_LOCATION || LOCATION_FILE (loc) == nullptr) + return nullptr; - sarif_physical_location *phys_loc_obj = new sarif_physical_location (); + auto phys_loc_obj = ::make_unique (); /* "artifactLocation" property (SARIF v2.1.0 section 3.29.3). */ - sarif_artifact_location *artifact_loc_obj - = make_artifact_location_object (loc); - phys_loc_obj->set ("artifactLocation", artifact_loc_obj); + phys_loc_obj->set + ("artifactLocation", make_artifact_location_object (loc)); get_or_create_artifact (LOCATION_FILE (loc), role, true); /* "region" property (SARIF v2.1.0 section 3.29.4). */ - if (sarif_region *region_obj = maybe_make_region_object (loc, - column_override)) - phys_loc_obj->set ("region", region_obj); + if (auto region_obj = maybe_make_region_object (loc, column_override)) + phys_loc_obj->set ("region", std::move (region_obj)); /* "contextRegion" property (SARIF v2.1.0 section 3.29.5). */ - if (sarif_region *context_region_obj - = maybe_make_region_object_for_context (loc)) - phys_loc_obj->set ("contextRegion", context_region_obj); + if (auto context_region_obj = maybe_make_region_object_for_context (loc)) + phys_loc_obj->set ("contextRegion", + std::move (context_region_obj)); /* Instead, we add artifacts to the run as a whole, with artifact.contents. @@ -1173,9 +1173,9 @@ maybe_make_physical_location_object (location_t loc, } /* Make an "artifactLocation" object (SARIF v2.1.0 section 3.4) for LOC, - or return NULL. */ + or return nullptr. */ -sarif_artifact_location * +std::unique_ptr sarif_builder::make_artifact_location_object (location_t loc) { return make_artifact_location_object (LOCATION_FILE (loc)); @@ -1187,12 +1187,12 @@ sarif_builder::make_artifact_location_object (location_t loc) #define PWD_PROPERTY_NAME ("PWD") /* Make an "artifactLocation" object (SARIF v2.1.0 section 3.4) for FILENAME, - or return NULL. */ + or return nullptr. */ -sarif_artifact_location * +std::unique_ptr sarif_builder::make_artifact_location_object (const char *filename) { - sarif_artifact_location *artifact_loc_obj = new sarif_artifact_location (); + auto artifact_loc_obj = ::make_unique (); /* "uri" property (SARIF v2.1.0 section 3.4.3). */ artifact_loc_obj->set_string ("uri", filename); @@ -1208,7 +1208,7 @@ sarif_builder::make_artifact_location_object (const char *filename) return artifact_loc_obj; } -/* Get the PWD, or NULL, as an absolute file-based URI, +/* Get the PWD, or nullptr, as an absolute file-based URI, adding a trailing forward slash (as required by SARIF v2.1.0 section 3.14.14). */ @@ -1220,14 +1220,14 @@ make_pwd_uri_str () const char *pwd = getpwd (); if (!pwd) - return NULL; + return nullptr; size_t len = strlen (pwd); if (len == 0 || pwd[len - 1] != '/') - return concat (FILE_PREFIX, pwd, "/", NULL); + return concat (FILE_PREFIX, pwd, "/", nullptr); else { gcc_assert (pwd[len - 1] == '/'); - return concat (FILE_PREFIX, pwd, NULL); + return concat (FILE_PREFIX, pwd, nullptr); } } @@ -1235,10 +1235,10 @@ make_pwd_uri_str () for use in the "run.originalUriBaseIds" property (SARIF v2.1.0 section 3.14.14) when we have any relative paths. */ -sarif_artifact_location * +std::unique_ptr sarif_builder::make_artifact_location_object_for_pwd () const { - sarif_artifact_location *artifact_loc_obj = new sarif_artifact_location (); + auto artifact_loc_obj = ::make_unique (); /* "uri" property (SARIF v2.1.0 section 3.4.3). */ if (char *pwd = make_pwd_uri_str ()) @@ -1263,19 +1263,19 @@ sarif_builder::get_sarif_column (expanded_location exploc) const } /* Make a "region" object (SARIF v2.1.0 section 3.30) for LOC, - or return NULL. + or return nullptr. If COLUMN_OVERRIDE is non-zero, then use it as the column number if LOC has no column information. */ -sarif_region * +std::unique_ptr sarif_builder::maybe_make_region_object (location_t loc, int column_override) const { location_t caret_loc = get_pure_location (loc); if (caret_loc <= BUILTINS_LOCATION) - return NULL; + return nullptr; location_t start_loc = get_start (loc); location_t finish_loc = get_finish (loc); @@ -1285,11 +1285,11 @@ sarif_builder::maybe_make_region_object (location_t loc, expanded_location exploc_finish = expand_location (finish_loc); if (exploc_start.file !=exploc_caret.file) - return NULL; + return nullptr; if (exploc_finish.file !=exploc_caret.file) - return NULL; + return nullptr; - sarif_region *region_obj = new sarif_region (); + auto region_obj = ::make_unique (); /* "startLine" property (SARIF v2.1.0 section 3.30.5) */ if (exploc_start.line > 0) @@ -1338,13 +1338,13 @@ sarif_builder::maybe_make_region_object (location_t loc, embedding those source lines, making it easier for consumers to show the pertinent source. */ -sarif_region * +std::unique_ptr sarif_builder::maybe_make_region_object_for_context (location_t loc) const { location_t caret_loc = get_pure_location (loc); if (caret_loc <= BUILTINS_LOCATION) - return NULL; + return nullptr; location_t start_loc = get_start (loc); location_t finish_loc = get_finish (loc); @@ -1354,11 +1354,11 @@ sarif_builder::maybe_make_region_object_for_context (location_t loc) const expanded_location exploc_finish = expand_location (finish_loc); if (exploc_start.file !=exploc_caret.file) - return NULL; + return nullptr; if (exploc_finish.file !=exploc_caret.file) - return NULL; + return nullptr; - sarif_region *region_obj = new sarif_region (); + auto region_obj = ::make_unique (); /* "startLine" property (SARIF v2.1.0 section 3.30.5) */ if (exploc_start.line > 0) @@ -1370,11 +1370,12 @@ sarif_builder::maybe_make_region_object_for_context (location_t loc) const region_obj->set_integer ("endLine", exploc_finish.line); /* "snippet" property (SARIF v2.1.0 section 3.30.13). */ - if (sarif_artifact_content *artifact_content_obj + if (auto artifact_content_obj = maybe_make_artifact_content_object (exploc_start.file, exploc_start.line, exploc_finish.line)) - region_obj->set ("snippet", artifact_content_obj); + region_obj->set ("snippet", + std::move (artifact_content_obj)); return region_obj; } @@ -1382,7 +1383,7 @@ sarif_builder::maybe_make_region_object_for_context (location_t loc) const /* Make a "region" object (SARIF v2.1.0 section 3.30) for the deletion region of HINT (as per SARIF v2.1.0 section 3.57.3). */ -sarif_region * +std::unique_ptr sarif_builder::make_region_object_for_hint (const fixit_hint &hint) const { location_t start_loc = hint.get_start_loc (); @@ -1391,7 +1392,7 @@ sarif_builder::make_region_object_for_hint (const fixit_hint &hint) const expanded_location exploc_start = expand_location (start_loc); expanded_location exploc_next = expand_location (next_loc); - sarif_region *region_obj = new sarif_region (); + auto region_obj = ::make_unique (); /* "startLine" property (SARIF v2.1.0 section 3.30.5) */ region_obj->set_integer ("startLine", exploc_start.line); @@ -1414,7 +1415,7 @@ sarif_builder::make_region_object_for_hint (const fixit_hint &hint) const /* Attempt to get a string for a logicalLocation's "kind" property (SARIF v2.1.0 section 3.33.7). - Return NULL if unknown. */ + Return nullptr if unknown. */ static const char * maybe_get_sarif_kind (enum logical_location_kind kind) @@ -1424,7 +1425,7 @@ maybe_get_sarif_kind (enum logical_location_kind kind) default: gcc_unreachable (); case LOGICAL_LOCATION_KIND_UNKNOWN: - return NULL; + return nullptr; case LOGICAL_LOCATION_KIND_FUNCTION: return "function"; @@ -1446,12 +1447,12 @@ maybe_get_sarif_kind (enum logical_location_kind kind) } /* Make a "logicalLocation" object (SARIF v2.1.0 section 3.33) for LOGICAL_LOC, - or return NULL. */ + or return nullptr. */ -sarif_logical_location * +std::unique_ptr make_sarif_logical_location_object (const logical_location &logical_loc) { - sarif_logical_location *logical_loc_obj = new sarif_logical_location (); + auto logical_loc_obj = ::make_unique (); /* "name" property (SARIF v2.1.0 section 3.33.4). */ if (const char *short_name = logical_loc.get_short_name ()) @@ -1475,18 +1476,18 @@ make_sarif_logical_location_object (const logical_location &logical_loc) /* Make a "codeFlow" object (SARIF v2.1.0 section 3.36) for PATH. */ -sarif_code_flow * +std::unique_ptr sarif_builder::make_code_flow_object (const diagnostic_path &path) { - sarif_code_flow *code_flow_obj = new sarif_code_flow (); + auto code_flow_obj = ::make_unique (); /* "threadFlows" property (SARIF v2.1.0 section 3.36.3). */ - json::array *thread_flows_arr = new json::array (); + auto thread_flows_arr = ::make_unique (); /* Walk the events, consolidating into per-thread threadFlow objects, using the index with PATH as the overall executionOrder. */ hash_map, - sarif_thread_flow *> thread_id_map; + sarif_thread_flow *> thread_id_map; // borrowed for (unsigned i = 0; i < path.num_events (); i++) { const diagnostic_event &event = path.get_event (i); @@ -1499,42 +1500,41 @@ sarif_builder::make_code_flow_object (const diagnostic_path &path) { const diagnostic_thread &thread = path.get_thread (thread_id); thread_flow_obj = new sarif_thread_flow (thread); + thread_id_map.put (thread_id, thread_flow_obj); // borrowed thread_flows_arr->append (thread_flow_obj); - thread_id_map.put (thread_id, thread_flow_obj); } /* Add event to thread's threadFlow object. */ - sarif_thread_flow_location *thread_flow_loc_obj + std::unique_ptr thread_flow_loc_obj = make_thread_flow_location_object (event, i); - thread_flow_obj->add_location (thread_flow_loc_obj); + thread_flow_obj->add_location (std::move (thread_flow_loc_obj)); } - code_flow_obj->set ("threadFlows", thread_flows_arr); + code_flow_obj->set ("threadFlows", std::move (thread_flows_arr)); return code_flow_obj; } /* Make a "threadFlowLocation" object (SARIF v2.1.0 section 3.38) for EVENT. */ -sarif_thread_flow_location * +std::unique_ptr sarif_builder::make_thread_flow_location_object (const diagnostic_event &ev, int path_event_idx) { - sarif_thread_flow_location *thread_flow_loc_obj - = new sarif_thread_flow_location (); + auto thread_flow_loc_obj = ::make_unique (); /* Give diagnostic_event subclasses a chance to add custom properties via a property bag. */ ev.maybe_add_sarif_properties (*thread_flow_loc_obj); /* "location" property (SARIF v2.1.0 section 3.38.3). */ - sarif_location *location_obj - = make_location_object (ev, diagnostic_artifact_role::traced_file); - thread_flow_loc_obj->set ("location", location_obj); + thread_flow_loc_obj->set + ("location", + make_location_object (ev, diagnostic_artifact_role::traced_file)); /* "kinds" property (SARIF v2.1.0 section 3.38.8). */ diagnostic_event::meaning m = ev.get_meaning (); - if (json::array *kinds_arr = maybe_make_kinds_array (m)) - thread_flow_loc_obj->set ("kinds", kinds_arr); + if (auto kinds_arr = maybe_make_kinds_array (m)) + thread_flow_loc_obj->set ("kinds", std::move (kinds_arr)); /* "nestingLevel" property (SARIF v2.1.0 section 3.38.10). */ thread_flow_loc_obj->set_integer ("nestingLevel", ev.get_stack_depth ()); @@ -1554,17 +1554,17 @@ sarif_builder::make_thread_flow_location_object (const diagnostic_event &ev, /* If M has any known meaning, make a json array suitable for the "kinds" property of a "threadFlowLocation" object (SARIF v2.1.0 section 3.38.8). - Otherwise, return NULL. */ + Otherwise, return nullptr. */ -json::array * +std::unique_ptr sarif_builder::maybe_make_kinds_array (diagnostic_event::meaning m) const { if (m.m_verb == diagnostic_event::VERB_unknown && m.m_noun == diagnostic_event::NOUN_unknown && m.m_property == diagnostic_event::PROPERTY_unknown) - return NULL; + return nullptr; - json::array *kinds_arr = new json::array (); + auto kinds_arr = ::make_unique (); if (const char *verb_str = diagnostic_event::meaning::maybe_get_verb_str (m.m_verb)) kinds_arr->append_string (verb_str); @@ -1579,10 +1579,10 @@ sarif_builder::maybe_make_kinds_array (diagnostic_event::meaning m) const /* Make a "message" object (SARIF v2.1.0 section 3.11) for MSG. */ -sarif_message * +std::unique_ptr sarif_builder::make_message_object (const char *msg) const { - sarif_message *message_obj = new sarif_message (); + auto message_obj = ::make_unique (); /* "text" property (SARIF v2.1.0 section 3.11.8). */ message_obj->set_string ("text", msg); @@ -1594,17 +1594,17 @@ sarif_builder::make_message_object (const char *msg) const We emit the diagram as a code block within the Markdown part of the message. */ -sarif_message * +std::unique_ptr sarif_builder::make_message_object_for_diagram (diagnostic_context &context, const diagnostic_diagram &diagram) { - sarif_message *message_obj = new sarif_message (); + auto message_obj = ::make_unique (); /* "text" property (SARIF v2.1.0 section 3.11.8). */ message_obj->set_string ("text", diagram.get_alt_text ()); char *saved_prefix = pp_take_prefix (context.printer); - pp_set_prefix (context.printer, NULL); + pp_set_prefix (context.printer, nullptr); /* "To produce a code block in Markdown, simply indent every line of the block by at least 4 spaces or 1 tab." @@ -1623,11 +1623,10 @@ sarif_builder::make_message_object_for_diagram (diagnostic_context &context, /* Make a "multiformatMessageString object" (SARIF v2.1.0 section 3.12) for MSG. */ -sarif_multiformat_message_string * +std::unique_ptr sarif_builder::make_multiformat_message_string (const char *msg) const { - sarif_multiformat_message_string *message_obj - = new sarif_multiformat_message_string (); + auto message_obj = ::make_unique (); /* "text" property (SARIF v2.1.0 section 3.12.3). */ message_obj->set_string ("text", msg); @@ -1638,14 +1637,14 @@ sarif_builder::make_multiformat_message_string (const char *msg) const #define SARIF_SCHEMA "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json" #define SARIF_VERSION "2.1.0" -/* Make a top-level "sarifLog" object (SARIF v2.1.0 section 3.13). - Take ownership of INVOCATION_OBJ and RESULTS. */ +/* Make a top-level "sarifLog" object (SARIF v2.1.0 section 3.13). */ -sarif_log * -sarif_builder::make_top_level_object (sarif_invocation *invocation_obj, - json::array *results) +std::unique_ptr +sarif_builder:: +make_top_level_object (std::unique_ptr invocation_obj, + std::unique_ptr results) { - sarif_log *log_obj = new sarif_log (); + auto log_obj = ::make_unique (); /* "$schema" property (SARIF v2.1.0 section 3.13.3) . */ log_obj->set_string ("$schema", SARIF_SCHEMA); @@ -1654,50 +1653,50 @@ sarif_builder::make_top_level_object (sarif_invocation *invocation_obj, log_obj->set_string ("version", SARIF_VERSION); /* "runs" property (SARIF v2.1.0 section 3.13.4). */ - json::array *run_arr = new json::array (); - sarif_run *run_obj = make_run_object (invocation_obj, results); - run_arr->append (run_obj); - log_obj->set ("runs", run_arr); + auto run_arr = ::make_unique (); + auto run_obj = make_run_object (std::move (invocation_obj), + std::move (results)); + run_arr->append (std::move (run_obj)); + log_obj->set ("runs", std::move (run_arr)); return log_obj; } -/* Make a "run" object (SARIF v2.1.0 section 3.14). - Take ownership of INVOCATION_OBJ and RESULTS. */ +/* Make a "run" object (SARIF v2.1.0 section 3.14). */ -sarif_run * -sarif_builder::make_run_object (sarif_invocation *invocation_obj, - json::array *results) +std::unique_ptr +sarif_builder:: +make_run_object (std::unique_ptr invocation_obj, + std::unique_ptr results) { - sarif_run *run_obj = new sarif_run (); + auto run_obj = ::make_unique (); /* "tool" property (SARIF v2.1.0 section 3.14.6). */ - sarif_tool *tool_obj = make_tool_object (); - run_obj->set ("tool", tool_obj); + run_obj->set ("tool", make_tool_object ()); /* "taxonomies" property (SARIF v2.1.0 section 3.14.8). */ - if (json::array *taxonomies_arr = maybe_make_taxonomies_array ()) - run_obj->set ("taxonomies", taxonomies_arr); + if (auto taxonomies_arr = maybe_make_taxonomies_array ()) + run_obj->set ("taxonomies", std::move (taxonomies_arr)); /* "invocations" property (SARIF v2.1.0 section 3.14.11). */ { - json::array *invocations_arr = new json::array (); - invocations_arr->append (invocation_obj); - run_obj->set ("invocations", invocations_arr); + auto invocations_arr = ::make_unique (); + invocations_arr->append (std::move (invocation_obj)); + run_obj->set ("invocations", std::move (invocations_arr)); } /* "originalUriBaseIds (SARIF v2.1.0 section 3.14.14). */ if (m_seen_any_relative_paths) { - json::object *orig_uri_base_ids = new json::object (); - run_obj->set ("originalUriBaseIds", orig_uri_base_ids); - sarif_artifact_location *pwd_art_loc_obj - = make_artifact_location_object_for_pwd (); - orig_uri_base_ids->set (PWD_PROPERTY_NAME, pwd_art_loc_obj); + auto orig_uri_base_ids = ::make_unique (); + orig_uri_base_ids->set + (PWD_PROPERTY_NAME, make_artifact_location_object_for_pwd ()); + run_obj->set ("originalUriBaseIds", + std::move (orig_uri_base_ids)); } /* "artifacts" property (SARIF v2.1.0 section 3.14.15). */ - json::array *artifacts_arr = new json::array (); + auto artifacts_arr = ::make_unique (); for (auto iter : m_filename_to_artifact_map) { sarif_artifact *artifact_obj = iter.second; @@ -1706,24 +1705,24 @@ sarif_builder::make_run_object (sarif_invocation *invocation_obj, artifact_obj->populate_roles (); artifacts_arr->append (artifact_obj); } - run_obj->set ("artifacts", artifacts_arr); + run_obj->set ("artifacts", std::move (artifacts_arr)); /* "results" property (SARIF v2.1.0 section 3.14.23). */ - run_obj->set ("results", results); + run_obj->set ("results", std::move (results)); return run_obj; } /* Make a "tool" object (SARIF v2.1.0 section 3.18). */ -sarif_tool * +std::unique_ptr sarif_builder::make_tool_object () const { - sarif_tool *tool_obj = new sarif_tool (); + auto tool_obj = ::make_unique (); /* "driver" property (SARIF v2.1.0 section 3.18.2). */ - sarif_tool_component *driver_obj = make_driver_tool_component_object (); - tool_obj->set ("driver", driver_obj); + tool_obj->set ("driver", + make_driver_tool_component_object ()); /* Report plugins via the "extensions" property (SARIF v2.1.0 section 3.18.3). */ @@ -1738,8 +1737,7 @@ sarif_builder::make_tool_object () const { /* Create a "toolComponent" object (SARIF v2.1.0 section 3.19) for the plugin. */ - sarif_tool_component *plugin_obj = new sarif_tool_component (); - m_plugin_objs.safe_push (plugin_obj); + auto plugin_obj = ::make_unique (); /* "name" property (SARIF v2.1.0 section 3.19.8). */ if (const char *short_name = p.get_short_name ()) @@ -1752,17 +1750,20 @@ sarif_builder::make_tool_object () const /* "version" property (SARIF v2.1.0 section 3.19.13). */ if (const char *version = p.get_version ()) plugin_obj->set_string ("version", version); + + m_plugin_objs.push_back (std::move (plugin_obj)); } - auto_vec m_plugin_objs; + std::vector> m_plugin_objs; }; my_plugin_visitor v; vinfo->for_each_plugin (v); - if (v.m_plugin_objs.length () > 0) + if (v.m_plugin_objs.size () > 0) { - json::array *extensions_arr = new json::array (); - tool_obj->set ("extensions", extensions_arr); - for (auto iter : v.m_plugin_objs) - extensions_arr->append (iter); + auto extensions_arr = ::make_unique (); + for (auto &iter : v.m_plugin_objs) + extensions_arr->append (std::move (iter)); + tool_obj->set ("extensions", + std::move (extensions_arr)); } } @@ -1775,10 +1776,10 @@ sarif_builder::make_tool_object () const /* Make a "toolComponent" object (SARIF v2.1.0 section 3.19) for what SARIF calls the "driver" (see SARIF v2.1.0 section 3.18.1). */ -sarif_tool_component * +std::unique_ptr sarif_builder::make_driver_tool_component_object () const { - sarif_tool_component *driver_obj = new sarif_tool_component (); + auto driver_obj = ::make_unique (); if (auto client_data_hooks = m_context.get_client_data_hooks ()) if (const client_version_info *vinfo @@ -1817,18 +1818,18 @@ sarif_builder::make_driver_tool_component_object () const (SARIF v2.1.0 section 3.14.8) of a run object, containing a single "toolComponent" (3.19) as per 3.19.3, representing the CWE. - Otherwise return NULL. */ + Otherwise return nullptr. */ -json::array * +std::unique_ptr sarif_builder::maybe_make_taxonomies_array () const { - sarif_tool_component *cwe_obj = maybe_make_cwe_taxonomy_object (); + auto cwe_obj = maybe_make_cwe_taxonomy_object (); if (!cwe_obj) - return NULL; + return nullptr; /* "taxonomies" property (SARIF v2.1.0 section 3.14.8). */ - json::array *taxonomies_arr = new json::array (); - taxonomies_arr->append (cwe_obj); + auto taxonomies_arr = ::make_unique (); + taxonomies_arr->append (std::move (cwe_obj)); return taxonomies_arr; } @@ -1836,15 +1837,15 @@ sarif_builder::maybe_make_taxonomies_array () const (SARIF v2.1.0 section 3.19) representing the CWE taxonomy, as per 3.19.3. Populate the "taxa" property with all of the CWE IDs in m_cwe_id_set. - Otherwise return NULL. */ + Otherwise return nullptr. */ -sarif_tool_component * +std::unique_ptr sarif_builder::maybe_make_cwe_taxonomy_object () const { if (m_cwe_id_set.is_empty ()) - return NULL; + return nullptr; - sarif_tool_component *taxonomy_obj = new sarif_tool_component (); + auto taxonomy_obj = ::make_unique (); /* "name" property (SARIF v2.1.0 section 3.19.8). */ taxonomy_obj->set_string ("name", "CWE"); @@ -1856,20 +1857,17 @@ sarif_builder::maybe_make_cwe_taxonomy_object () const taxonomy_obj->set_string ("organization", "MITRE"); /* "shortDescription" property (SARIF v2.1.0 section 3.19.19). */ - sarif_multiformat_message_string *short_desc - = make_multiformat_message_string ("The MITRE" - " Common Weakness Enumeration"); - taxonomy_obj->set ("shortDescription", short_desc); + taxonomy_obj->set + ("shortDescription", + make_multiformat_message_string ("The MITRE" + " Common Weakness Enumeration")); /* "taxa" property (SARIF v2.1.0 3.section 3.19.25). */ - json::array *taxa_arr = new json::array (); + auto taxa_arr = ::make_unique (); for (auto cwe_id : m_cwe_id_set) - { - sarif_reporting_descriptor *cwe_taxon - = make_reporting_descriptor_object_for_cwe_id (cwe_id); - taxa_arr->append (cwe_taxon); - } - taxonomy_obj->set ("taxa", taxa_arr); + taxa_arr->append + (make_reporting_descriptor_object_for_cwe_id (cwe_id)); + taxonomy_obj->set ("taxa", std::move (taxa_arr)); return taxonomy_obj; } @@ -1896,9 +1894,8 @@ sarif_builder::get_or_create_artifact (const char *filename, m_filename_to_artifact_map.put (filename, artifact_obj); /* "location" property (SARIF v2.1.0 section 3.24.2). */ - sarif_artifact_location *artifact_loc_obj - = make_artifact_location_object (filename); - artifact_obj->set ("location", artifact_loc_obj); + artifact_obj->set + ("location", make_artifact_location_object (filename)); /* "sourceLanguage" property (SARIF v2.1.0 section 3.24.10). */ switch (role) @@ -1926,28 +1923,29 @@ sarif_builder::get_or_create_artifact (const char *filename, /* Make an "artifactContent" object (SARIF v2.1.0 section 3.3) for the full contents of FILENAME. */ -sarif_artifact_content * +std::unique_ptr sarif_builder::maybe_make_artifact_content_object (const char *filename) const { /* Let input.cc handle any charset conversion. */ char_span utf8_content = m_context.get_file_cache ().get_source_file_content (filename); if (!utf8_content) - return NULL; + return nullptr; /* Don't add it if it's not valid UTF-8. */ if (!cpp_valid_utf8_p(utf8_content.get_buffer (), utf8_content.length ())) - return NULL; + return nullptr; - sarif_artifact_content *artifact_content_obj = new sarif_artifact_content (); - artifact_content_obj->set ("text", - new json::string (utf8_content.get_buffer (), - utf8_content.length ())); + auto artifact_content_obj = ::make_unique (); + artifact_content_obj->set + ("text", + ::make_unique (utf8_content.get_buffer (), + utf8_content.length ())); return artifact_content_obj; } /* Attempt to read the given range of lines from FILENAME; return - a freshly-allocated 0-terminated buffer containing them, or NULL. */ + a freshly-allocated 0-terminated buffer containing them, or nullptr. */ char * sarif_builder::get_source_lines (const char *filename, @@ -1961,7 +1959,7 @@ sarif_builder::get_source_lines (const char *filename, char_span line_content = m_context.get_file_cache ().get_source_line (filename, line); if (!line_content.get_buffer ()) - return NULL; + return nullptr; result.reserve (line_content.length () + 1); for (size_t i = 0; i < line_content.length (); i++) result.quick_push (line_content[i]); @@ -1975,7 +1973,7 @@ sarif_builder::get_source_lines (const char *filename, /* Make an "artifactContent" object (SARIF v2.1.0 section 3.3) for the given run of lines within FILENAME (including the endpoints). */ -sarif_artifact_content * +std::unique_ptr sarif_builder::maybe_make_artifact_content_object (const char *filename, int start_line, int end_line) const @@ -1983,16 +1981,16 @@ sarif_builder::maybe_make_artifact_content_object (const char *filename, char *text_utf8 = get_source_lines (filename, start_line, end_line); if (!text_utf8) - return NULL; + return nullptr; /* Don't add it if it's not valid UTF-8. */ if (!cpp_valid_utf8_p(text_utf8, strlen(text_utf8))) { free (text_utf8); - return NULL; + return nullptr; } - sarif_artifact_content *artifact_content_obj = new sarif_artifact_content (); + auto artifact_content_obj = ::make_unique (); artifact_content_obj->set_string ("text", text_utf8); free (text_utf8); @@ -2001,72 +1999,73 @@ sarif_builder::maybe_make_artifact_content_object (const char *filename, /* Make a "fix" object (SARIF v2.1.0 section 3.55) for RICHLOC. */ -sarif_fix * +std::unique_ptr sarif_builder::make_fix_object (const rich_location &richloc) { - sarif_fix *fix_obj = new sarif_fix (); + auto fix_obj = ::make_unique (); /* "artifactChanges" property (SARIF v2.1.0 section 3.55.3). */ /* We assume that all fix-it hints in RICHLOC affect the same file. */ - json::array *artifact_change_arr = new json::array (); - sarif_artifact_change *artifact_change_obj - = make_artifact_change_object (richloc); - artifact_change_arr->append (artifact_change_obj); - fix_obj->set ("artifactChanges", artifact_change_arr); + auto artifact_change_arr = ::make_unique (); + artifact_change_arr->append + (make_artifact_change_object (richloc)); + fix_obj->set ("artifactChanges", + std::move (artifact_change_arr)); return fix_obj; } /* Make an "artifactChange" object (SARIF v2.1.0 section 3.56) for RICHLOC. */ -sarif_artifact_change * +std::unique_ptr sarif_builder::make_artifact_change_object (const rich_location &richloc) { - sarif_artifact_change *artifact_change_obj = new sarif_artifact_change (); + auto artifact_change_obj = ::make_unique (); /* "artifactLocation" property (SARIF v2.1.0 section 3.56.2). */ - sarif_artifact_location *artifact_location_obj - = make_artifact_location_object (richloc.get_loc ()); - artifact_change_obj->set ("artifactLocation", artifact_location_obj); + artifact_change_obj->set + ("artifactLocation", + make_artifact_location_object (richloc.get_loc ())); /* "replacements" property (SARIF v2.1.0 section 3.56.3). */ - json::array *replacement_arr = new json::array (); + auto replacement_arr = ::make_unique (); for (unsigned int i = 0; i < richloc.get_num_fixit_hints (); i++) { const fixit_hint *hint = richloc.get_fixit_hint (i); - sarif_replacement *replacement_obj = make_replacement_object (*hint); - replacement_arr->append (replacement_obj); + replacement_arr->append + (make_replacement_object (*hint)); } - artifact_change_obj->set ("replacements", replacement_arr); + artifact_change_obj->set ("replacements", + std::move (replacement_arr)); return artifact_change_obj; } /* Make a "replacement" object (SARIF v2.1.0 section 3.57) for HINT. */ -sarif_replacement * +std::unique_ptr sarif_builder::make_replacement_object (const fixit_hint &hint) const { - sarif_replacement *replacement_obj = new sarif_replacement (); + auto replacement_obj = ::make_unique (); /* "deletedRegion" property (SARIF v2.1.0 section 3.57.3). */ - sarif_region *region_obj = make_region_object_for_hint (hint); - replacement_obj->set ("deletedRegion", region_obj); + replacement_obj->set ("deletedRegion", + make_region_object_for_hint (hint)); /* "insertedContent" property (SARIF v2.1.0 section 3.57.4). */ - sarif_artifact_content *content_obj - = make_artifact_content_object (hint.get_string ()); - replacement_obj->set ("insertedContent", content_obj); + replacement_obj->set + ("insertedContent", + make_artifact_content_object (hint.get_string ())); return replacement_obj; } /* Make an "artifactContent" object (SARIF v2.1.0 section 3.3) for TEXT. */ -sarif_artifact_content * +std::unique_ptr sarif_builder::make_artifact_content_object (const char *text) const { - sarif_artifact_content *content_obj = new sarif_artifact_content (); + auto content_obj = ::make_unique (); /* "text" property (SARIF v2.1.0 section 3.3.2). */ content_obj->set_string ("text", text); @@ -2165,7 +2164,7 @@ public: } ~sarif_file_output_format () { - char *filename = concat (m_base_file_name, ".sarif", NULL); + char *filename = concat (m_base_file_name, ".sarif", nullptr); free (m_base_file_name); m_base_file_name = nullptr; FILE *outf = fopen (filename, "w"); diff --git a/gcc/diagnostic-format-sarif.h b/gcc/diagnostic-format-sarif.h index c492582eee4b..781c3c31e8c4 100644 --- a/gcc/diagnostic-format-sarif.h +++ b/gcc/diagnostic-format-sarif.h @@ -51,7 +51,7 @@ class sarif_logical_location : public sarif_object { }; -extern sarif_logical_location * +extern std::unique_ptr make_sarif_logical_location_object (const logical_location &logical_loc); #endif /* ! GCC_DIAGNOSTIC_FORMAT_SARIF_H */ From patchwork Wed Jul 24 22:18:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964564 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=CkCHhQIH; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpQd1dQRz1yY9 for ; Thu, 25 Jul 2024 08:21:45 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6D80D385C6CB for ; Wed, 24 Jul 2024 22:21:43 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id F0932385B532 for ; Wed, 24 Jul 2024 22:18:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F0932385B532 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org F0932385B532 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859537; cv=none; b=f+loWuXt1NHM3DYbUoV3/ENsfW0X+HewDvtShMArYzl2EC4NImc0ThaEPMgNB17zt/wSmLF2/1qN3SQBH0YXY4tH7eTc7t9b9C2kXAGrMAjbJy/u15LQZcHweBlsVUblRksEsFGSZSUPGXZV5Fu2YmxtVQn6/3dBJKqo6mr96ec= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859537; c=relaxed/simple; bh=w15cZT9tDVxBt5xneCleHsuFDqiGLQvBASdvRNagnhc=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=A8suOokwqbVKntXDB8ETW6oQSFo8up4Ko+dQOzGpquki/fZLJWFg1vt1vO6dkj0x54rc5K8ttS0+9QdrG10pmZINmt/DzHKU65NC8FjB1Rr/QCua+otVvyQVsD5wKFXdqOOqMdJUQYDVTK5mdEoKR8kz37ri7xjRg5MA2QnILfc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859532; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AKOeJAb5btB0lnqI+Sb+p2wF2qa4OJsOPxxZ/926684=; b=CkCHhQIHbdR+59vh9mWyCTYm9hEy4wH1lKUd91zfQ5v+x85YaEQIsMMTGTulomY4mn5FSM W4SuY6mCn9p62fhqO67fGOXz1rCCNh1/P+/9hzl7Cw7gxiwqrYrhVpe5b4++mqOmgYedWF txfCRXY9oX3ilwmsV5wJLTksYKSNzNY= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-442-IVeD-lFmMquqeKlBjHYIHQ-1; Wed, 24 Jul 2024 18:18:51 -0400 X-MC-Unique: IVeD-lFmMquqeKlBjHYIHQ-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 56D2F1955D58 for ; Wed, 24 Jul 2024 22:18:50 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 426621955F40; Wed, 24 Jul 2024 22:18:48 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 09/16] diagnostics: JSON output: use std::unique_ptr throughout Date: Wed, 24 Jul 2024 18:18:17 -0400 Message-Id: <20240724221824.585054-10-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org No functional change intended. gcc/ChangeLog: * diagnostic-format-json.cc: Include "make-unique.h". (json_output_format::m_toplevel_array): Convert to std::unique_ptr. (json_output_format::json_output_format): Update accordingly. (json_output_format::~json_output_format): Remove manual "delete" of field. (json_from_expanded_location): Convert return type to std::unique_ptr. (json_from_location_range): Likewise. Use nullptr rather than NULL. (json_from_fixit_hint): Convert return type to std::unique_ptr. (json_from_metadata): Likewise. (make_json_for_path): Likewise. (json_output_format::on_end_diagnostic): Use std::unique_ptr throughout. (json_file_output_format::~json_file_output_format): Use nullptr. (selftest::test_unknown_location): Update to use std::unique_ptr. (selftest::test_bad_endpoints): Likewise. Replace NULL with nullptr. Signed-off-by: David Malcolm --- gcc/diagnostic-format-json.cc | 122 +++++++++++++++++----------------- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc index 55ba39e0c532..b78cb92cfd7a 100644 --- a/gcc/diagnostic-format-json.cc +++ b/gcc/diagnostic-format-json.cc @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "json.h" #include "selftest.h" #include "logical-location.h" +#include "make-unique.h" /* Subclass of diagnostic_output_format for JSON output. */ @@ -62,7 +63,7 @@ protected: json_output_format (diagnostic_context &context, bool formatted) : diagnostic_output_format (context), - m_toplevel_array (new json::array ()), + m_toplevel_array (::make_unique ()), m_cur_group (nullptr), m_cur_children_array (nullptr), m_formatted (formatted) @@ -75,31 +76,30 @@ protected: { m_toplevel_array->dump (outf, m_formatted); fprintf (outf, "\n"); - delete m_toplevel_array; m_toplevel_array = nullptr; } private: /* The top-level JSON array of pending diagnostics. */ - json::array *m_toplevel_array; + std::unique_ptr m_toplevel_array; /* The JSON object for the current diagnostic group. */ - json::object *m_cur_group; + json::object *m_cur_group; // borrowed /* The JSON array for the "children" array within the current diagnostic group. */ - json::array *m_cur_children_array; + json::array *m_cur_children_array; // borrowed bool m_formatted; }; /* Generate a JSON object for LOC. */ -static json::value * +static std::unique_ptr json_from_expanded_location (diagnostic_context &context, location_t loc) { expanded_location exploc = expand_location (loc); - json::object *result = new json::object (); + std::unique_ptr result = ::make_unique (); if (exploc.file) result->set_string ("file", exploc.file); result->set_integer ("line", exploc.line); @@ -130,26 +130,29 @@ json_from_expanded_location (diagnostic_context &context, location_t loc) /* Generate a JSON object for LOC_RANGE. */ -static json::object * +static std::unique_ptr json_from_location_range (diagnostic_context &context, const location_range *loc_range, unsigned range_idx) { location_t caret_loc = get_pure_location (loc_range->m_loc); if (caret_loc == UNKNOWN_LOCATION) - return NULL; + return nullptr; location_t start_loc = get_start (loc_range->m_loc); location_t finish_loc = get_finish (loc_range->m_loc); - json::object *result = new json::object (); - result->set ("caret", json_from_expanded_location (context, caret_loc)); + std::unique_ptr result = ::make_unique (); + result->set ("caret", + json_from_expanded_location (context, caret_loc)); if (start_loc != caret_loc && start_loc != UNKNOWN_LOCATION) - result->set ("start", json_from_expanded_location (context, start_loc)); + result->set ("start", + json_from_expanded_location (context, start_loc)); if (finish_loc != caret_loc && finish_loc != UNKNOWN_LOCATION) - result->set ("finish", json_from_expanded_location (context, finish_loc)); + result->set ("finish", + json_from_expanded_location (context, finish_loc)); if (loc_range->m_label) { @@ -163,15 +166,17 @@ json_from_location_range (diagnostic_context &context, /* Generate a JSON object for HINT. */ -static json::object * +static std::unique_ptr json_from_fixit_hint (diagnostic_context &context, const fixit_hint *hint) { - json::object *fixit_obj = new json::object (); + std::unique_ptr fixit_obj = ::make_unique (); location_t start_loc = hint->get_start_loc (); - fixit_obj->set ("start", json_from_expanded_location (context, start_loc)); + fixit_obj->set ("start", + json_from_expanded_location (context, start_loc)); location_t next_loc = hint->get_next_loc (); - fixit_obj->set ("next", json_from_expanded_location (context, next_loc)); + fixit_obj->set ("next", + json_from_expanded_location (context, next_loc). release ()); fixit_obj->set_string ("string", hint->get_string ()); return fixit_obj; @@ -179,10 +184,10 @@ json_from_fixit_hint (diagnostic_context &context, const fixit_hint *hint) /* Generate a JSON object for METADATA. */ -static json::object * +static std::unique_ptr json_from_metadata (const diagnostic_metadata *metadata) { - json::object *metadata_obj = new json::object (); + std::unique_ptr metadata_obj = ::make_unique (); if (metadata->get_cwe ()) metadata_obj->set_integer ("cwe", metadata->get_cwe ()); @@ -192,16 +197,16 @@ json_from_metadata (const diagnostic_metadata *metadata) /* Make a JSON value for PATH. */ -static json::value * +static std::unique_ptr make_json_for_path (diagnostic_context &context, const diagnostic_path *path) { - json::array *path_array = new json::array (); + std::unique_ptr path_array = ::make_unique (); for (unsigned i = 0; i < path->num_events (); i++) { const diagnostic_event &event = path->get_event (i); - json::object *event_obj = new json::object (); + std::unique_ptr event_obj = ::make_unique (); if (event.get_location ()) event_obj->set ("location", json_from_expanded_location (context, @@ -214,7 +219,7 @@ make_json_for_path (diagnostic_context &context, event_obj->set_string ("function", name.get ()); } event_obj->set_integer ("depth", event.get_stack_depth ()); - path_array->append (event_obj); + path_array->append (std::move (event_obj)); } return path_array; } @@ -273,37 +278,41 @@ json_output_format::on_end_diagnostic (const diagnostic_info &diagnostic, { /* Otherwise, make diag_obj be the top-level object within the group; add a "children" array and record the column origin. */ - m_toplevel_array->append (diag_obj); m_cur_group = diag_obj; - m_cur_children_array = new json::array (); - diag_obj->set ("children", m_cur_children_array); + std::unique_ptr children_array + = ::make_unique (); + m_cur_children_array = children_array.get (); // borrowed + diag_obj->set ("children", std::move (children_array)); diag_obj->set_integer ("column-origin", m_context.m_column_origin); + m_toplevel_array->append (diag_obj); } - const rich_location *richloc = diagnostic.richloc; + /* diag_obj is now owned by either m_cur_children_array or + m_toplevel_array; further uses of diag_obj are borrowing it. */ - json::array *loc_array = new json::array (); - diag_obj->set ("locations", loc_array); + const rich_location *richloc = diagnostic.richloc; - for (unsigned int i = 0; i < richloc->get_num_locations (); i++) - { - const location_range *loc_range = richloc->get_range (i); - json::object *loc_obj - = json_from_location_range (m_context, loc_range, i); - if (loc_obj) - loc_array->append (loc_obj); - } + { + std::unique_ptr loc_array = ::make_unique (); + for (unsigned int i = 0; i < richloc->get_num_locations (); i++) + { + const location_range *loc_range = richloc->get_range (i); + if (std::unique_ptr loc_obj + = json_from_location_range (m_context, loc_range, i)) + loc_array->append (std::move (loc_obj)); + } + diag_obj->set ("locations", std::move (loc_array)); + } if (richloc->get_num_fixit_hints ()) { - json::array *fixit_array = new json::array (); - diag_obj->set ("fixits", fixit_array); + std::unique_ptr fixit_array = ::make_unique (); for (unsigned int i = 0; i < richloc->get_num_fixit_hints (); i++) { const fixit_hint *hint = richloc->get_fixit_hint (i); - json::object *fixit_obj = json_from_fixit_hint (m_context, hint); - fixit_array->append (fixit_obj); + fixit_array->append (json_from_fixit_hint (m_context, hint)); } + diag_obj->set ("fixits", std::move (fixit_array)); } /* TODO: tree-ish things: @@ -312,20 +321,13 @@ json_output_format::on_end_diagnostic (const diagnostic_info &diagnostic, TODO: macro expansion information. */ if (diagnostic.metadata) - { - json::object *metadata_obj = json_from_metadata (diagnostic.metadata); - diag_obj->set ("metadata", metadata_obj); - } + diag_obj->set ("metadata", json_from_metadata (diagnostic.metadata)); const diagnostic_path *path = richloc->get_path (); if (path) - { - json::value *path_value = make_json_for_path (m_context, path); - diag_obj->set ("path", path_value); - } + diag_obj->set ("path", make_json_for_path (m_context, path)); - diag_obj->set ("escape-source", - new json::literal (richloc->escape_on_output_p ())); + diag_obj->set_bool ("escape-source", richloc->escape_on_output_p ()); } class json_stderr_output_format : public json_output_format @@ -359,7 +361,7 @@ public: ~json_file_output_format () { - char *filename = concat (m_base_file_name, ".gcc.json", NULL); + char *filename = concat (m_base_file_name, ".gcc.json", nullptr); free (m_base_file_name); m_base_file_name = nullptr; FILE *outf = fopen (filename, "w"); @@ -441,7 +443,7 @@ static void test_unknown_location () { test_diagnostic_context dc; - delete json_from_expanded_location (dc, UNKNOWN_LOCATION); + json_from_expanded_location (dc, UNKNOWN_LOCATION); } /* Verify that we gracefully handle attempts to serialize bad @@ -457,16 +459,16 @@ test_bad_endpoints () location_range loc_range; loc_range.m_loc = bad_endpoints; loc_range.m_range_display_kind = SHOW_RANGE_WITH_CARET; - loc_range.m_label = NULL; + loc_range.m_label = nullptr; test_diagnostic_context dc; - json::object *obj = json_from_location_range (dc, &loc_range, 0); + std::unique_ptr obj + = json_from_location_range (dc, &loc_range, 0); /* We should have a "caret" value, but no "start" or "finish" values. */ - ASSERT_TRUE (obj != NULL); - ASSERT_TRUE (obj->get ("caret") != NULL); - ASSERT_TRUE (obj->get ("start") == NULL); - ASSERT_TRUE (obj->get ("finish") == NULL); - delete obj; + ASSERT_TRUE (obj != nullptr); + ASSERT_TRUE (obj->get ("caret") != nullptr); + ASSERT_TRUE (obj->get ("start") == nullptr); + ASSERT_TRUE (obj->get ("finish") == nullptr); } /* Run all of the selftests within this file. */ From patchwork Wed Jul 24 22:18:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964570 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=JKoT53Ri; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpTQ01Rkz1yY9 for ; Thu, 25 Jul 2024 08:24:09 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E03D9385DDC3 for ; Wed, 24 Jul 2024 22:24:07 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 6029A385C6C8 for ; Wed, 24 Jul 2024 22:18:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6029A385C6C8 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6029A385C6C8 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859542; cv=none; b=Q/RRlJ4hKZY5CCQ1rRdjVtTyU5pImLby1eiHsX+wTgDHuvlJhkvLjZdw0ISTrg31G5ulGDXOdwTr7RAc8PE+wIHs1sWabxdbbn0U7gTuJrFF0yGVXxWYZAEzfnskdDVd3f/D2+JssHisxQKLaQWoVzAuqN880ZvXa7Mm7AwZECA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859542; c=relaxed/simple; bh=y6jJpZFxfwb57hzjI3S1r426t/5MyeFyo3WmQuMcusE=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=Sa5wAvhfJStHFgGjWFvOyi47xyH194JLC5oJF0IrvfhTpbs4apGusV5FWnPhTd+UTqZ6GsMF/OKiwbOfGjZDc/UGwimAKIzb2RnXiuUGa7NV2xw+7u5CA9902UFhAs9Zunxz5BzQSxUkBGY08WJJ3vx3OClEV0jd5f1jwb4ArYE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859536; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NOs9D+L6Drw5i6QEw9D/DJ0BL17rgy6ORJE7pa/G2oY=; b=JKoT53RiIfPa8d0GOgAKm1c5kX2VvCfR22epb2rcM7eeQJ3WEK8gBnqPEXn1M6TkfOdYCF EU+3NFn+mIexfUtIVQYzalWaf4gPwMPw7qfiFazMgO/sne/3J8X1VoOmmkfE337cBo7qq6 gCd1+oxBhXLVR7N6hKFs+5d4jpLFM8w= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-197-r6X_TM6bMGy-WdwexLz_7w-1; Wed, 24 Jul 2024 18:18:52 -0400 X-MC-Unique: r6X_TM6bMGy-WdwexLz_7w-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A7C4E1944A83 for ; Wed, 24 Jul 2024 22:18:51 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id ACF121955F40; Wed, 24 Jul 2024 22:18:50 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 10/16] =?utf-8?q?diagnostics=3A_SARIF_output=3A_potentially_?= =?utf-8?q?add_escaped_renderings_of_source_=28=C2=A73=2E3=2E4=29?= Date: Wed, 24 Jul 2024 18:18:18 -0400 Message-Id: <20240724221824.585054-11-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LOTSOFHASH, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org This patch adds support to our SARIF output for cases where rich_loc.escape_on_output_p () is true, such as for -Wbidi-chars. In such cases, the pertinent SARIF "location" object gains a property bag with property "gcc/escapeNonAscii": true, and the "artifactContent" within the location's physical location's snippet" gains a "rendered" property (§3.3.4) that escapes non-ASCII text in the snippet, such as: "rendered": {"text": where "text" has a string value such as (for a "trojan source" attack): "9 | /* } if (isAdmin) begin admins only */\n" " | ~~~~~~~~ ~~~~~~~~ ^\n" " | | | |\n" " | | | end of bidirectional context\n" " | U+202E (RIGHT-TO-LEFT OVERRIDE) U+2066 (LEFT-TO-RIGHT ISOLATE)\n" where the escaping is affected by -fdiagnostics-escape-format=; with -fdiagnostics-escape-format=bytes, the rendered text of the above is: "9 | /*<80> } <81>if (isAdmin)<81> <81> begin admins only */\n" " | ~~~~~~~~~~~~ ~~~~~~~~~~~~ ^\n" " | | | |\n" " | U+202E (RIGHT-TO-LEFT OVERRIDE) U+2066 (LEFT-TO-RIGHT ISOLATE) end of bidirectional context\n" The patch also refactors/adds enough selftest machinery to be able to test the snippet generation from within the selftest framework, rather than just within DejaGnu (where the regex-based testing isn't sophisticated enough to verify such properties as the above). gcc/ChangeLog: * Makefile.in (OBJS-libcommon): Add selftest-json.o. * diagnostic-format-sarif.cc: Include "selftest.h", "selftest-diagnostic.h", "selftest-diagnostic-show-locus.h", "selftest-json.h", and "text-range-label.h". (class content_renderer): New. (sarif_builder::m_rules_arr): Convert to std::unique_ptr. (sarif_builder::make_location_object): Add class escape_nonascii_renderer. If rich_loc.escape_on_output_p (), pass a nonnull escape_nonascii_renderer to maybe_make_physical_location_object as its snippet_renderer, and add a property bag property "gcc/escapeNonAscii" to the SARIF location object. For other overloads of make_location_object, pass nullptr for the snippet_renderer. (sarif_builder::maybe_make_region_object_for_context): Add "snippet_renderer" param and pass it to maybe_make_artifact_content_object. (sarif_builder::make_tool_object): Drop "const". (sarif_builder::make_driver_tool_component_object): Likewise. Use typesafe unique_ptr variant of object::set for setting "rules" property on driver_obj. (sarif_builder::maybe_make_artifact_content_object): Add param "r" and use it to potentially set the "rendered" property (§3.3.4). (selftest::test_make_location_object): New. (selftest::diagnostic_format_sarif_cc_tests): New. * diagnostic-show-locus.cc: Include "text-range-label.h" and "selftest-diagnostic-show-locus.h". (selftests::diagnostic_show_locus_fixture::diagnostic_show_locus_fixture): New. (selftests::test_layout_x_offset_display_utf8): Use diagnostic_show_locus_fixture to simplify and consolidate setup code. (selftests::test_diagnostic_show_locus_one_liner): Likewise. (selftests::test_one_liner_colorized_utf8): Likewise. (selftests::test_diagnostic_show_locus_one_liner_utf8): Likewise. * gcc-rich-location.h (class text_range_label): Move to new file text-range-label.h. * selftest-diagnostic-show-locus.h: New file, based on material in diagnostic-show-locus.cc. * selftest-json.cc: New file. * selftest-json.h: New file. * selftest-run-tests.cc (selftest::run_tests): Call selftest::diagnostic_format_sarif_cc_tests. * selftest.h (selftest::diagnostic_format_sarif_cc_tests): New decl. gcc/testsuite/ChangeLog: * c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c: Verify that we have a property bag with property "gcc/escapeNonAscii": true. Verify that we have a "rendered" property for a snippet. * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c: Include "text-range-label.h". gcc/ChangeLog: * text-range-label.h: New file, taking class text_range_label from gcc-rich-location.h. libcpp/ChangeLog: * include/rich-location.h (semi_embedded_vec::semi_embedded_vec): Add copy ctor. (rich_location::rich_location): Remove "= delete" from decl of copy ctor. Add deleted decl of move ctor. (rich_location::operator=): Remove "= delete" from decl of copy assignment. Add deleted decl of move assignment. (fixit_hint::fixit_hint): Add copy ctor decl. Add deleted decl of move. (fixit_hint::operator=): Add copy assignment decl. Add deleted decl of move assignment. * line-map.cc (rich_location::rich_location): New copy ctor. (fixit_hint::fixit_hint): New copy ctor. Signed-off-by: David Malcolm --- gcc/Makefile.in | 1 + gcc/diagnostic-format-sarif.cc | 229 ++++++++++++++++-- gcc/diagnostic-show-locus.cc | 98 ++++---- gcc/gcc-rich-location.h | 17 -- gcc/selftest-diagnostic-show-locus.h | 82 +++++++ gcc/selftest-json.cc | 119 +++++++++ gcc/selftest-json.h | 100 ++++++++ gcc/selftest-run-tests.cc | 1 + gcc/selftest.h | 1 + ...diagnostic-format-sarif-file-Wbidi-chars.c | 9 + .../diagnostic_plugin_test_show_locus.c | 1 + gcc/text-range-label.h | 42 ++++ libcpp/include/rich-location.h | 31 ++- libcpp/line-map.cc | 28 +++ 14 files changed, 669 insertions(+), 90 deletions(-) create mode 100644 gcc/selftest-diagnostic-show-locus.h create mode 100644 gcc/selftest-json.cc create mode 100644 gcc/selftest-json.h create mode 100644 gcc/text-range-label.h diff --git a/gcc/Makefile.in b/gcc/Makefile.in index f4bb4a88cf31..3798caaf60f7 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1836,6 +1836,7 @@ OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \ vec.o input.o hash-table.o ggc-none.o memory-block.o \ selftest.o selftest-diagnostic.o sort.o \ selftest-diagnostic-path.o \ + selftest-json.o \ selftest-logical-location.o \ text-art/box-drawing.o \ text-art/canvas.o \ diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 6f61d89363f2..847e1eb9bdfc 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -37,9 +37,16 @@ along with GCC; see the file COPYING3. If not see #include "ordered-hash-map.h" #include "sbitmap.h" #include "make-unique.h" +#include "selftest.h" +#include "selftest-diagnostic.h" +#include "selftest-diagnostic-show-locus.h" +#include "selftest-json.h" +#include "text-range-label.h" /* Forward decls. */ class sarif_builder; +class content_renderer; + class escape_nonascii_renderer; /* Subclasses of sarif_object. Keep these in order of their descriptions in the specification. */ @@ -284,6 +291,20 @@ public: sarif_builder &builder); }; +/* Abstract base class for use when making an "artifactContent" + object (SARIF v2.1.0 section 3.3): generate a value for the + 3.3.4 "rendered" property. + Can return nullptr, for "no property". */ + +class content_renderer +{ +public: + virtual ~content_renderer () {} + + virtual std::unique_ptr + render (const sarif_builder &builder) const = 0; +}; + /* A class for managing SARIF output (for -fdiagnostics-format=sarif-stderr and -fdiagnostics-format=sarif-file). @@ -312,7 +333,6 @@ public: property (SARIF v2.1.0 section 3.14.11), as invocation objects (SARIF v2.1.0 section 3.20), but we'd want to capture the arguments to toplev::main, and the response files. - - doesn't capture escape_on_output_p - doesn't capture secondary locations within a rich_location (perhaps we should use the "relatedLocations" property: SARIF v2.1.0 section 3.27.22) @@ -379,7 +399,8 @@ private: std::unique_ptr maybe_make_physical_location_object (location_t loc, enum diagnostic_artifact_role role, - int column_override); + int column_override, + const content_renderer *snippet_renderer); std::unique_ptr make_artifact_location_object (location_t loc); std::unique_ptr @@ -390,7 +411,8 @@ private: maybe_make_region_object (location_t loc, int column_override) const; std::unique_ptr - maybe_make_region_object_for_context (location_t loc) const; + maybe_make_region_object_for_context (location_t loc, + const content_renderer *snippet_renderer) const; std::unique_ptr make_region_object_for_hint (const fixit_hint &hint) const; std::unique_ptr @@ -402,9 +424,9 @@ private: make_run_object (std::unique_ptr invocation_obj, std::unique_ptr results); std::unique_ptr - make_tool_object () const; + make_tool_object (); std::unique_ptr - make_driver_tool_component_object () const; + make_driver_tool_component_object (); std::unique_ptr maybe_make_taxonomies_array () const; std::unique_ptr maybe_make_cwe_taxonomy_object () const; @@ -430,7 +452,8 @@ private: std::unique_ptr maybe_make_artifact_content_object (const char *filename, int start_line, - int end_line) const; + int end_line, + const content_renderer *r) const; std::unique_ptr make_fix_object (const rich_location &rich_loc); std::unique_ptr @@ -460,7 +483,7 @@ private: bool m_seen_any_relative_paths; hash_set m_rule_id_set; - json::array *m_rules_arr; + std::unique_ptr m_rules_arr; /* The set of all CWE IDs we've seen, if any. */ hash_set > m_cwe_id_set; @@ -1086,21 +1109,74 @@ sarif_builder::make_location_object (const rich_location &rich_loc, const logical_location *logical_loc, enum diagnostic_artifact_role role) { + class escape_nonascii_renderer : public content_renderer + { + public: + escape_nonascii_renderer (const rich_location &richloc, + enum diagnostics_escape_format escape_format) + : m_richloc (richloc), + m_escape_format (escape_format) + {} + + std::unique_ptr + render (const sarif_builder &builder) const final override + { + diagnostic_context dc; + diagnostic_initialize (&dc, 0); + dc.m_source_printing.enabled = true; + dc.m_source_printing.colorize_source_p = false; + dc.m_source_printing.show_labels_p = true; + dc.m_source_printing.show_line_numbers_p = true; + + rich_location my_rich_loc (m_richloc); + my_rich_loc.set_escape_on_output (true); + + dc.set_escape_format (m_escape_format); + diagnostic_show_locus (&dc, &my_rich_loc, DK_ERROR); + + std::unique_ptr result + = builder.make_multiformat_message_string + (pp_formatted_text (dc.printer)); + + diagnostic_finish (&dc); + + return result; + } + private: + const rich_location &m_richloc; + enum diagnostics_escape_format m_escape_format; + } the_renderer (rich_loc, + m_context.get_escape_format ()); + auto location_obj = ::make_unique (); /* Get primary loc from RICH_LOC. */ location_t loc = rich_loc.get_loc (); /* "physicalLocation" property (SARIF v2.1.0 section 3.28.3). */ + const content_renderer *snippet_renderer + = rich_loc.escape_on_output_p () ? &the_renderer : nullptr; if (auto phs_loc_obj = maybe_make_physical_location_object (loc, role, - rich_loc.get_column_override ())) + rich_loc.get_column_override (), + snippet_renderer)) location_obj->set ("physicalLocation", std::move (phs_loc_obj)); /* "logicalLocations" property (SARIF v2.1.0 section 3.28.4). */ set_any_logical_locs_arr (*location_obj, logical_loc); + /* A flag for hinting that the diagnostic involves issues at the + level of character encodings (such as homoglyphs, or misleading + bidirectional control codes), and thus that it will be helpful + to the user if we show some representation of + how the characters in the pertinent source lines are encoded. */ + if (rich_loc.escape_on_output_p ()) + { + sarif_property_bag &bag = location_obj->get_or_create_properties (); + bag.set_bool ("gcc/escapeNonAscii", rich_loc.escape_on_output_p ()); + } + return location_obj; } @@ -1115,7 +1191,8 @@ sarif_builder::make_location_object (const diagnostic_event &event, /* "physicalLocation" property (SARIF v2.1.0 section 3.28.3). */ location_t loc = event.get_location (); - if (auto phs_loc_obj = maybe_make_physical_location_object (loc, role, 0)) + if (auto phs_loc_obj + = maybe_make_physical_location_object (loc, role, 0, nullptr)) location_obj->set ("physicalLocation", std::move (phs_loc_obj)); @@ -1144,7 +1221,8 @@ std::unique_ptr sarif_builder:: maybe_make_physical_location_object (location_t loc, enum diagnostic_artifact_role role, - int column_override) + int column_override, + const content_renderer *snippet_renderer) { if (loc <= BUILTINS_LOCATION || LOCATION_FILE (loc) == nullptr) return nullptr; @@ -1161,7 +1239,8 @@ maybe_make_physical_location_object (location_t loc, phys_loc_obj->set ("region", std::move (region_obj)); /* "contextRegion" property (SARIF v2.1.0 section 3.29.5). */ - if (auto context_region_obj = maybe_make_region_object_for_context (loc)) + if (auto context_region_obj + = maybe_make_region_object_for_context (loc, snippet_renderer)) phys_loc_obj->set ("contextRegion", std::move (context_region_obj)); @@ -1339,7 +1418,10 @@ sarif_builder::maybe_make_region_object (location_t loc, the pertinent source. */ std::unique_ptr -sarif_builder::maybe_make_region_object_for_context (location_t loc) const +sarif_builder:: +maybe_make_region_object_for_context (location_t loc, + const content_renderer *snippet_renderer) + const { location_t caret_loc = get_pure_location (loc); @@ -1373,7 +1455,8 @@ sarif_builder::maybe_make_region_object_for_context (location_t loc) const if (auto artifact_content_obj = maybe_make_artifact_content_object (exploc_start.file, exploc_start.line, - exploc_finish.line)) + exploc_finish.line, + snippet_renderer)) region_obj->set ("snippet", std::move (artifact_content_obj)); @@ -1716,7 +1799,7 @@ make_run_object (std::unique_ptr invocation_obj, /* Make a "tool" object (SARIF v2.1.0 section 3.18). */ std::unique_ptr -sarif_builder::make_tool_object () const +sarif_builder::make_tool_object () { auto tool_obj = ::make_unique (); @@ -1777,7 +1860,7 @@ sarif_builder::make_tool_object () const calls the "driver" (see SARIF v2.1.0 section 3.18.1). */ std::unique_ptr -sarif_builder::make_driver_tool_component_object () const +sarif_builder::make_driver_tool_component_object () { auto driver_obj = ::make_unique (); @@ -1809,7 +1892,7 @@ sarif_builder::make_driver_tool_component_object () const } /* "rules" property (SARIF v2.1.0 section 3.19.23). */ - driver_obj->set ("rules", m_rules_arr); + driver_obj->set ("rules", std::move (m_rules_arr)); return driver_obj; } @@ -1971,12 +2054,16 @@ sarif_builder::get_source_lines (const char *filename, } /* Make an "artifactContent" object (SARIF v2.1.0 section 3.3) for the given - run of lines within FILENAME (including the endpoints). */ + run of lines within FILENAME (including the endpoints). + If R is non-NULL, use it to potentially set the "rendered" + property (3.3.4). */ std::unique_ptr -sarif_builder::maybe_make_artifact_content_object (const char *filename, - int start_line, - int end_line) const +sarif_builder:: +maybe_make_artifact_content_object (const char *filename, + int start_line, + int end_line, + const content_renderer *r) const { char *text_utf8 = get_source_lines (filename, start_line, end_line); @@ -1994,6 +2081,12 @@ sarif_builder::maybe_make_artifact_content_object (const char *filename, artifact_content_obj->set_string ("text", text_utf8); free (text_utf8); + /* 3.3.4 "rendered" property. */ + if (r) + if (std::unique_ptr rendered + = r->render (*this)) + artifact_content_obj->set ("rendered", std::move (rendered)); + return artifact_content_obj; } @@ -2260,3 +2353,99 @@ diagnostic_output_format_init_sarif_stream (diagnostic_context &context, formatted, stream)); } + +#if CHECKING_P + +namespace selftest { + +static void +test_make_location_object (const line_table_case &case_) +{ + diagnostic_show_locus_fixture_one_liner_utf8 f (case_); + location_t line_end = linemap_position_for_column (line_table, 31); + + /* Don't attempt to run the tests if column data might be unavailable. */ + if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) + return; + + test_diagnostic_context dc; + + sarif_builder builder (dc, "MAIN_INPUT_FILENAME", true); + + const location_t foo + = make_location (linemap_position_for_column (line_table, 1), + linemap_position_for_column (line_table, 1), + linemap_position_for_column (line_table, 8)); + const location_t bar + = make_location (linemap_position_for_column (line_table, 12), + linemap_position_for_column (line_table, 12), + linemap_position_for_column (line_table, 17)); + const location_t field + = make_location (linemap_position_for_column (line_table, 19), + linemap_position_for_column (line_table, 19), + linemap_position_for_column (line_table, 30)); + + text_range_label label0 ("label0"); + text_range_label label1 ("label1"); + text_range_label label2 ("label2"); + + rich_location richloc (line_table, foo, &label0, nullptr); + richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1); + richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2); + richloc.set_escape_on_output (true); + + std::unique_ptr location_obj + = builder.make_location_object + (richloc, nullptr, diagnostic_artifact_role::analysis_target); + ASSERT_NE (location_obj, nullptr); + + auto physical_location + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (location_obj.get (), + "physicalLocation"); + { + auto region + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (physical_location, "region"); + ASSERT_JSON_INT_PROPERTY_EQ (region, "startLine", 1); + ASSERT_JSON_INT_PROPERTY_EQ (region, "startColumn", 1); + ASSERT_JSON_INT_PROPERTY_EQ (region, "endColumn", 7); + } + { + auto context_region + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (physical_location, + "contextRegion"); + ASSERT_JSON_INT_PROPERTY_EQ (context_region, "startLine", 1); + + { + auto snippet + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (context_region, "snippet"); + + /* We expect the snippet's "text" to be a copy of the content. */ + ASSERT_JSON_STRING_PROPERTY_EQ (snippet, "text", f.m_content); + + /* We expect the snippet to have a "rendered" whose "text" has a + pure ASCII escaped copy of the line (with labels, etc). */ + { + auto rendered + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (snippet, "rendered"); + ASSERT_JSON_STRING_PROPERTY_EQ + (rendered, "text", + "1 | _foo = _bar._field;\n" + " | ^~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n" + " | | | |\n" + " | label0 label1 label2\n"); + } + } + } +} + +/* Run all of the selftests within this file. */ + +void +diagnostic_format_sarif_cc_tests () +{ + for_each_line_table_case (test_make_location_object); +} + +} // namespace selftest + +#endif /* CHECKING_P */ diff --git a/gcc/diagnostic-show-locus.cc b/gcc/diagnostic-show-locus.cc index d0fc2ff1b6d2..8079809be93d 100644 --- a/gcc/diagnostic-show-locus.cc +++ b/gcc/diagnostic-show-locus.cc @@ -29,8 +29,10 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic.h" #include "diagnostic-color.h" #include "gcc-rich-location.h" +#include "text-range-label.h" #include "selftest.h" #include "selftest-diagnostic.h" +#include "selftest-diagnostic-show-locus.h" #include "cpplib.h" #include "text-art/types.h" #include "text-art/theme.h" @@ -3291,6 +3293,18 @@ namespace selftest { /* Selftests for diagnostic_show_locus. */ +diagnostic_show_locus_fixture:: +diagnostic_show_locus_fixture (const line_table_case &case_, + const char *content) +: m_content (content), + m_tmp_source_file (SELFTEST_LOCATION, ".c", content), + m_ltt (case_), + m_fc () +{ + linemap_add (line_table, LC_ENTER, false, + m_tmp_source_file.get_filename (), 1); +} + /* Verify that cpp_display_width correctly handles escaping. */ static void @@ -3395,11 +3409,9 @@ test_layout_x_offset_display_utf8 (const line_table_case &case_) no multibyte characters earlier on the line. */ const int emoji_col = 102; - temp_source_file tmp (SELFTEST_LOCATION, ".c", content); - file_cache fc; - line_table_test ltt (case_); + diagnostic_show_locus_fixture f (case_, content); - linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1); + linemap_add (line_table, LC_ENTER, false, f.get_filename (), 1); location_t line_end = linemap_position_for_column (line_table, line_bytes); @@ -3407,16 +3419,16 @@ test_layout_x_offset_display_utf8 (const line_table_case &case_) if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) return; - ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end)); + ASSERT_STREQ (f.get_filename (), LOCATION_FILE (line_end)); ASSERT_EQ (1, LOCATION_LINE (line_end)); ASSERT_EQ (line_bytes, LOCATION_COLUMN (line_end)); - char_span lspan = fc.get_source_line (tmp.get_filename (), 1); + char_span lspan = f.m_fc.get_source_line (f.get_filename (), 1); ASSERT_EQ (line_display_cols, cpp_display_width (lspan.get_buffer (), lspan.length (), def_policy ())); ASSERT_EQ (line_display_cols, - location_compute_display_column (fc, + location_compute_display_column (f.m_fc, expand_location (line_end), def_policy ())); ASSERT_EQ (0, memcmp (lspan.get_buffer () + (emoji_col - 1), @@ -4215,10 +4227,8 @@ test_diagnostic_show_locus_one_liner (const line_table_case &case_) ....................0000000001111111. ....................1234567890123456. */ const char *content = "foo = bar.field;\n"; - temp_source_file tmp (SELFTEST_LOCATION, ".c", content); - line_table_test ltt (case_); - linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1); + diagnostic_show_locus_fixture f (case_, content); location_t line_end = linemap_position_for_column (line_table, 16); @@ -4226,7 +4236,7 @@ test_diagnostic_show_locus_one_liner (const line_table_case &case_) if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) return; - ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end)); + ASSERT_STREQ (f.get_filename (), LOCATION_FILE (line_end)); ASSERT_EQ (1, LOCATION_LINE (line_end)); ASSERT_EQ (16, LOCATION_COLUMN (line_end)); @@ -4246,27 +4256,17 @@ test_diagnostic_show_locus_one_liner (const line_table_case &case_) test_one_liner_labels (); } -/* Version of all one-liner tests exercising multibyte awareness. For - simplicity we stick to using two multibyte characters in the test, U+1F602 - == "\xf0\x9f\x98\x82", which uses 4 bytes and 2 display columns, and U+03C0 - == "\xcf\x80", which uses 2 bytes and 1 display column. Note: all of the - below asserts would be easier to read if we used UTF-8 directly in the - string constants, but it seems better not to demand the host compiler - support this, when it isn't otherwise necessary. Instead, whenever an - extended character appears in a string, we put a line break after it so that - all succeeding characters can appear visually at the correct display column. +/* Version of all one-liner tests exercising multibyte awareness. + These are all called from test_diagnostic_show_locus_one_liner, + which uses diagnostic_show_locus_fixture_one_liner_utf8 to create + the test file; see the notes in diagnostic-show-locus-selftest.h. - All of these work on the following 1-line source file: - - .0000000001111111111222222 display - .1234567890123456789012345 columns - "SS_foo = P_bar.SS_fieldP;\n" - .0000000111111111222222223 byte - .1356789012456789134567891 columns - - which is set up by test_diagnostic_show_locus_one_liner and calls - them. Here SS represents the two display columns for the U+1F602 emoji and - P represents the one display column for the U+03C0 pi symbol. */ + Note: all of the below asserts would be easier to read if we used UTF-8 + directly in the string constants, but it seems better not to demand the + host compiler support this, when it isn't otherwise necessary. Instead, + whenever an extended character appears in a string, we put a line break + after it so that all succeeding characters can appear visually at the + correct display column. */ /* Just a caret. */ @@ -4784,25 +4784,27 @@ test_one_liner_colorized_utf8 () ASSERT_STR_CONTAINS (first_pi + 2, "\xcf\x80"); } +static const char * const one_liner_utf8_content + /* Display columns. + 0000000000000000000000011111111111111111111111111111112222222222222 + 1111111122222222345678900000000123456666666677777777890123444444445 */ + = "\xf0\x9f\x98\x82_foo = \xcf\x80_bar.\xf0\x9f\x98\x82_field\xcf\x80;\n"; + /* 0000000000000000000001111111111111111111222222222222222222222233333 + 1111222233334444567890122223333456789999000011112222345678999900001 + Byte columns. */ + +diagnostic_show_locus_fixture_one_liner_utf8:: +diagnostic_show_locus_fixture_one_liner_utf8 (const line_table_case &case_) +: diagnostic_show_locus_fixture (case_, one_liner_utf8_content) +{ +} + /* Run the various one-liner tests. */ static void test_diagnostic_show_locus_one_liner_utf8 (const line_table_case &case_) { - /* Create a tempfile and write some text to it. */ - const char *content - /* Display columns. - 0000000000000000000000011111111111111111111111111111112222222222222 - 1111111122222222345678900000000123456666666677777777890123444444445 */ - = "\xf0\x9f\x98\x82_foo = \xcf\x80_bar.\xf0\x9f\x98\x82_field\xcf\x80;\n"; - /* 0000000000000000000001111111111111111111222222222222222222222233333 - 1111222233334444567890122223333456789999000011112222345678999900001 - Byte columns. */ - temp_source_file tmp (SELFTEST_LOCATION, ".c", content); - file_cache fc; - line_table_test ltt (case_); - - linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1); + diagnostic_show_locus_fixture_one_liner_utf8 f (case_); location_t line_end = linemap_position_for_column (line_table, 31); @@ -4810,14 +4812,14 @@ test_diagnostic_show_locus_one_liner_utf8 (const line_table_case &case_) if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) return; - ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end)); + ASSERT_STREQ (f.get_filename (), LOCATION_FILE (line_end)); ASSERT_EQ (1, LOCATION_LINE (line_end)); ASSERT_EQ (31, LOCATION_COLUMN (line_end)); - char_span lspan = fc.get_source_line (tmp.get_filename (), 1); + char_span lspan = f.m_fc.get_source_line (f.get_filename (), 1); ASSERT_EQ (25, cpp_display_width (lspan.get_buffer (), lspan.length (), def_policy ())); - ASSERT_EQ (25, location_compute_display_column (fc, + ASSERT_EQ (25, location_compute_display_column (f.m_fc, expand_location (line_end), def_policy ())); diff --git a/gcc/gcc-rich-location.h b/gcc/gcc-rich-location.h index 0cd19aab1a7e..55798847726f 100644 --- a/gcc/gcc-rich-location.h +++ b/gcc/gcc-rich-location.h @@ -121,21 +121,4 @@ class gcc_rich_location : public rich_location location_t indent); }; -/* Concrete subclass of libcpp's range_label. - Simple implementation using a string literal. */ - -class text_range_label : public range_label -{ - public: - text_range_label (const char *text) : m_text (text) {} - - label_text get_text (unsigned /*range_idx*/) const final override - { - return label_text::borrow (m_text); - } - - private: - const char *m_text; -}; - #endif /* GCC_RICH_LOCATION_H */ diff --git a/gcc/selftest-diagnostic-show-locus.h b/gcc/selftest-diagnostic-show-locus.h new file mode 100644 index 000000000000..6454b09ac21d --- /dev/null +++ b/gcc/selftest-diagnostic-show-locus.h @@ -0,0 +1,82 @@ +/* Support for selftests involving diagnostic_show_locus. + Copyright (C) 1999-2024 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_SELFTEST_DIAGNOSTIC_SHOW_LOCUS_H +#define GCC_SELFTEST_DIAGNOSTIC_SHOW_LOCUS_H + +#include "selftest.h" + +/* The selftest code should entirely disappear in a production + configuration, hence we guard all of it with #if CHECKING_P. */ + +#if CHECKING_P + +namespace selftest { + +/* RAII class for use in selftests involving diagnostic_show_locus. + + Manages creating and cleaning up the following: + - writing out a temporary .c file containing CONTENT + - temporarily override the global "line_table" (using CASE_) and + push a line_map starting at the first line of the temporary file + - provide a file_cache. */ + +struct diagnostic_show_locus_fixture +{ + diagnostic_show_locus_fixture (const line_table_case &case_, + const char *content); + + const char *get_filename () const + { + return m_tmp_source_file.get_filename (); + } + + const char *m_content; + temp_source_file m_tmp_source_file; + line_table_test m_ltt; + file_cache m_fc; +}; + +/* Fixture for one-liner tests exercising multibyte awareness. For + simplicity we stick to using two multibyte characters in the test, U+1F602 + == "\xf0\x9f\x98\x82", which uses 4 bytes and 2 display columns, and U+03C0 + == "\xcf\x80", which uses 2 bytes and 1 display column. + + This works with the following 1-line source file: + + .0000000001111111111222222 display + .1234567890123456789012345 columns + "SS_foo = P_bar.SS_fieldP;\n" + .0000000111111111222222223 byte + .1356789012456789134567891 columns + + Here SS represents the two display columns for the U+1F602 emoji and + P represents the one display column for the U+03C0 pi symbol. */ + +struct diagnostic_show_locus_fixture_one_liner_utf8 + : public diagnostic_show_locus_fixture +{ + diagnostic_show_locus_fixture_one_liner_utf8 (const line_table_case &case_); +}; + +} // namespace selftest + +#endif /* #if CHECKING_P */ + +#endif /* GCC_SELFTEST_DIAGNOSTIC_SHOW_LOCUS_H */ diff --git a/gcc/selftest-json.cc b/gcc/selftest-json.cc new file mode 100644 index 000000000000..86f27cb82999 --- /dev/null +++ b/gcc/selftest-json.cc @@ -0,0 +1,119 @@ +/* Selftest support for JSON. + Copyright (C) 2024 Free Software Foundation, Inc. + Contributed by David Malcolm . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#define INCLUDE_MEMORY +#include "system.h" +#include "coretypes.h" +#include "diagnostic.h" +#include "selftest.h" +#include "selftest-json.h" + +/* The selftest code should entirely disappear in a production + configuration, hence we guard all of it with #if CHECKING_P. */ + +#if CHECKING_P + +namespace selftest { + +/* Assert that VALUE is a non-null json::object, + returning it as such, failing at LOC if this isn't the case. */ + +const json::object * +expect_json_object (const location &loc, + const json::value *value) +{ + ASSERT_NE_AT (loc, value, nullptr); + ASSERT_EQ_AT (loc, value->get_kind (), json::JSON_OBJECT); + return static_cast (value); +} + +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME. + Return the value of the property. + Use LOC for any failures. */ + +const json::value * +expect_json_object_with_property (const location &loc, + const json::value *value, + const char *property_name) +{ + const json::object *obj = expect_json_object (loc, value); + const json::value *property_value = obj->get (property_name); + ASSERT_NE_AT (loc, property_value, nullptr); + return property_value; +} + +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the value of that property is a non-null + json::integer_number equalling EXPECTED_VALUE. + Use LOC for any failures. */ + +void +assert_json_int_property_eq (const location &loc, + const json::value *value, + const char *property_name, + long expected_value) +{ + const json::value *property_value + = expect_json_object_with_property (loc, value, property_name); + ASSERT_EQ_AT (loc, property_value->get_kind (), json::JSON_INTEGER); + long actual_value + = static_cast (property_value)->get (); + ASSERT_EQ_AT (loc, expected_value, actual_value); +} + +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the property value is a non-null JSON object. + Return the value of the property as a json::object. + Use LOC for any failures. */ + +const json::object * +expect_json_object_with_object_property (const location &loc, + const json::value *value, + const char *property_name) +{ + const json::value *property_value + = expect_json_object_with_property (loc, value, property_name); + ASSERT_EQ_AT (loc, property_value->get_kind (), json::JSON_OBJECT); + return static_cast (property_value); +} + +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the value of that property is a non-null + JSON string equalling EXPECTED_VALUE. + Use LOC for any failures. */ + +void +assert_json_string_property_eq (const location &loc, + const json::value *value, + const char *property_name, + const char *expected_value) +{ + const json::value *property_value + = expect_json_object_with_property (loc, value, property_name); + ASSERT_EQ_AT (loc, property_value->get_kind (), json::JSON_STRING); + const json::string *str = static_cast (property_value); + ASSERT_STREQ_AT (loc, expected_value, str->get_string ()); +} + +} // namespace selftest + +#endif /* #if CHECKING_P */ diff --git a/gcc/selftest-json.h b/gcc/selftest-json.h new file mode 100644 index 000000000000..75a20d519a4c --- /dev/null +++ b/gcc/selftest-json.h @@ -0,0 +1,100 @@ +/* Selftest support for JSON. + Copyright (C) 2024 Free Software Foundation, Inc. + Contributed by David Malcolm . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_SELFTEST_JSON_H +#define GCC_SELFTEST_JSON_H + +#include "json.h" + +/* The selftest code should entirely disappear in a production + configuration, hence we guard all of it with #if CHECKING_P. */ + +#if CHECKING_P + +namespace selftest { + +/* Assert that VALUE is a non-null json::object, + returning it as such, failing at LOC if this isn't the case. */ + +const json::object * +expect_json_object (const location &loc, + const json::value *value); + +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME. + Return the value of the property. + Use LOC for any failures. */ + +const json::value * +expect_json_object_with_property (const location &loc, + const json::value *value, + const char *property_name); + +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the value of that property is a non-null + json::integer_number equalling EXPECTED_VALUE. + Use LOC for any failures. */ + +void +assert_json_int_property_eq (const location &loc, + const json::value *value, + const char *property_name, + long expected_value); +#define ASSERT_JSON_INT_PROPERTY_EQ(JSON_VALUE, PROPERTY_NAME, EXPECTED_VALUE) \ + assert_json_int_property_eq ((SELFTEST_LOCATION), \ + (JSON_VALUE), \ + (PROPERTY_NAME), \ + (EXPECTED_VALUE)) + +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the property value is a non-null JSON object. + Return the value of the property as a json::object. + Use LOC for any failures. */ + +const json::object * +expect_json_object_with_object_property (const location &loc, + const json::value *value, + const char *property_name); +#define EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY(JSON_VALUE, PROPERTY_NAME) \ + expect_json_object_with_object_property ((SELFTEST_LOCATION), \ + (JSON_VALUE), \ + (PROPERTY_NAME)) + +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the value of that property is a non-null + JSON string equalling EXPECTED_VALUE. + Use LOC for any failures. */ + +void +assert_json_string_property_eq (const location &loc, + const json::value *value, + const char *property_name, + const char *expected_value); +#define ASSERT_JSON_STRING_PROPERTY_EQ(JSON_VALUE, PROPERTY_NAME, EXPECTED_VALUE) \ + assert_json_string_property_eq ((SELFTEST_LOCATION), \ + (JSON_VALUE), \ + (PROPERTY_NAME), \ + (EXPECTED_VALUE)) + +} // namespace selftest + +#endif /* #if CHECKING_P */ + +#endif /* GCC_SELFTEST_JSON_H */ diff --git a/gcc/selftest-run-tests.cc b/gcc/selftest-run-tests.cc index e6779206c470..d6c88f864ba7 100644 --- a/gcc/selftest-run-tests.cc +++ b/gcc/selftest-run-tests.cc @@ -97,6 +97,7 @@ selftest::run_tests () diagnostic_color_cc_tests (); diagnostic_show_locus_cc_tests (); diagnostic_format_json_cc_tests (); + diagnostic_format_sarif_cc_tests (); edit_context_cc_tests (); fold_const_cc_tests (); spellcheck_cc_tests (); diff --git a/gcc/selftest.h b/gcc/selftest.h index dcb1463ed906..5afc9399c619 100644 --- a/gcc/selftest.h +++ b/gcc/selftest.h @@ -222,6 +222,7 @@ extern void cgraph_cc_tests (); extern void convert_cc_tests (); extern void diagnostic_color_cc_tests (); extern void diagnostic_format_json_cc_tests (); +extern void diagnostic_format_sarif_cc_tests (); extern void diagnostic_path_cc_tests (); extern void diagnostic_show_locus_cc_tests (); extern void digraph_cc_tests (); diff --git a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c index 283df75670d0..8a287d6c8683 100644 --- a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c +++ b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c @@ -20,4 +20,13 @@ int main() { { dg-final { scan-sarif-file {"text": "unpaired UTF-8 bidirectional control characters detected"} } } { dg-final { scan-sarif-file {"text": "unpaired UTF-8 bidirectional control characters detected"} } } + + Verify that the expected property bag property is present. + { dg-final { scan-sarif-file {"gcc/escapeNonAscii": true} } } + + Verify that the snippets have a "rendered" property. + We check the contents of the property via a selftest. + + { dg-final { scan-sarif-file {"rendered": } } } + */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c index 3bd8cab8c7f3..ad84a4a12ce2 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c @@ -61,6 +61,7 @@ #include "context.h" #include "print-tree.h" #include "gcc-rich-location.h" +#include "text-range-label.h" int plugin_is_GPL_compatible; diff --git a/gcc/text-range-label.h b/gcc/text-range-label.h new file mode 100644 index 000000000000..8507720e929b --- /dev/null +++ b/gcc/text-range-label.h @@ -0,0 +1,42 @@ +/* Simple implementation of range_label. + Copyright (C) 2014-2024 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_TEXT_RANGE_LABEL_H +#define GCC_TEXT_RANGE_LABEL_H + +#include "rich-location.h" + +/* Concrete subclass of libcpp's range_label. + Simple implementation using a string literal. */ + +class text_range_label : public range_label +{ + public: + text_range_label (const char *text) : m_text (text) {} + + label_text get_text (unsigned /*range_idx*/) const final override + { + return label_text::borrow (m_text); + } + + private: + const char *m_text; +}; + +#endif /* GCC_TEXT_RANGE_LABEL_H */ diff --git a/libcpp/include/rich-location.h b/libcpp/include/rich-location.h index ae4886f13bac..11c181ef0755 100644 --- a/libcpp/include/rich-location.h +++ b/libcpp/include/rich-location.h @@ -91,6 +91,7 @@ class semi_embedded_vec public: semi_embedded_vec (); ~semi_embedded_vec (); + semi_embedded_vec (const semi_embedded_vec &other); unsigned int count () const { return m_num; } T& operator[] (int idx); @@ -115,6 +116,21 @@ semi_embedded_vec::semi_embedded_vec () { } +/* Copy constructor for semi_embedded_vec. */ + +template +semi_embedded_vec::semi_embedded_vec (const semi_embedded_vec &other) +: m_num (0), + m_alloc (other.m_alloc), + m_extra (nullptr) +{ + if (other.m_extra) + m_extra = XNEWVEC (T, m_alloc); + + for (int i = 0; i < other.m_num; i++) + push (other[i]); +} + /* semi_embedded_vec's dtor. Release any dynamically-allocated memory. */ template @@ -387,11 +403,10 @@ class rich_location /* Destructor. */ ~rich_location (); - /* The class manages the memory pointed to by the elements of - the M_FIXIT_HINTS vector and is not meant to be copied or - assigned. */ - rich_location (const rich_location &) = delete; - void operator= (const rich_location &) = delete; + rich_location (const rich_location &); + rich_location (rich_location &&) = delete; + rich_location &operator= (const rich_location &) = delete; + rich_location &operator= (rich_location &&) = delete; /* Accessors. */ location_t get_loc () const { return get_loc (0); } @@ -547,6 +562,8 @@ protected: mutable expanded_location m_expanded_location; + /* The class manages the memory pointed to by the elements of + the m_fixit_hints vector. */ static const int MAX_STATIC_FIXIT_HINTS = 2; semi_embedded_vec m_fixit_hints; @@ -605,7 +622,11 @@ class fixit_hint fixit_hint (location_t start, location_t next_loc, const char *new_content); + fixit_hint (const fixit_hint &other); + fixit_hint (fixit_hint &&other) = delete; ~fixit_hint () { free (m_bytes); } + fixit_hint &operator= (const fixit_hint &) = delete; + fixit_hint &operator= (fixit_hint &&) = delete; bool affects_line_p (const line_maps *set, const char *file, diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc index 41aee987b292..05c4dafd89dd 100644 --- a/libcpp/line-map.cc +++ b/libcpp/line-map.cc @@ -2175,6 +2175,26 @@ rich_location::rich_location (line_maps *set, location_t loc, add_range (loc, SHOW_RANGE_WITH_CARET, label, label_highlight_color); } +/* Copy ctor for rich_location. + Take a deep copy of the fixit hints, which are owneed; + everything else is borrowed. */ + +rich_location::rich_location (const rich_location &other) +: m_line_table (other.m_line_table), + m_ranges (other.m_ranges), + m_column_override (other.m_column_override), + m_have_expanded_location (other.m_have_expanded_location), + m_seen_impossible_fixit (other.m_seen_impossible_fixit), + m_fixits_cannot_be_auto_applied (other.m_fixits_cannot_be_auto_applied), + m_escape_on_output (other.m_escape_on_output), + m_expanded_location (other.m_expanded_location), + m_fixit_hints (), + m_path (other.m_path) +{ + for (unsigned i = 0; i < other.m_fixit_hints.count (); i++) + m_fixit_hints.push (new fixit_hint (*other.m_fixit_hints[i])); +} + /* The destructor for class rich_location. */ rich_location::~rich_location () @@ -2595,6 +2615,14 @@ fixit_hint::fixit_hint (location_t start, { } +fixit_hint::fixit_hint (const fixit_hint &other) +: m_start (other.m_start), + m_next_loc (other.m_next_loc), + m_bytes (xstrdup (other.m_bytes)), + m_len (other.m_len) +{ +} + /* Does this fix-it hint affect the given line? */ bool From patchwork Wed Jul 24 22:18:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964566 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ft6tcct4; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpQx4LHTz1yY9 for ; Thu, 25 Jul 2024 08:22:01 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DDEA6385DDD7 for ; Wed, 24 Jul 2024 22:21:59 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id B68D9385DDCC for ; Wed, 24 Jul 2024 22:18:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B68D9385DDCC Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B68D9385DDCC Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859538; cv=none; b=EIwReSVVcVpJl44QaLWjEoMru3wlHCGIcNLN+WLxbu7wUXrHgCQxxIyaFfLBQqF+kGlYWQRHJdut41Y+pEpFmi6lyXb3CwCEF/rgx1lpuD4ARsEWZaFqTyNsxRGo8GLfObEVwXKBEYg4nyV8x185rGJi0CtO9C5qGXM0wq+rEhA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859538; c=relaxed/simple; bh=Ii3K3iix1SrD7LVKXnt62gCLIWVwWKxGfVZ6UslSTWs=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=Hjm3Fzn7k9nW2f+qp8SEKQzy9MgW7CZB8D5D/cfWGV79+PUXFtFaa2UqTQIm40J7T7DAKNf6Rro4sd6XFJHsasn9Qm/insiSZvrXDVnBd8fZhv1q3rXqLsqozQUOroeBiWgixr10U3s63YYZ6MfUF2YTS4oc2sKEvLgWaNztbgg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859535; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=I0lr7gk5mcrwrKd1Ey7/l/+yP8SCRSwRJBWRo0E6ANU=; b=ft6tcct4PqNdWXwiD2Y6xbkgo8bMQt3iCi/2+ZnuzZ4D2sqoWzOjAUtoSAvzJQVfPjv8vZ BJOwOMWN5y8BY+HQ6qySENVdb/mYjpc7Rkq18Qx55KZQv5x7bniFPzKugY3GvG9Eml82vw BHChtyf8rMVLFVLxTJu4TwJxdObSrGE= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-73-tXC6ZwhFOve5HafWgqlgGg-1; Wed, 24 Jul 2024 18:18:53 -0400 X-MC-Unique: tXC6ZwhFOve5HafWgqlgGg-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E0E1919560A1 for ; Wed, 24 Jul 2024 22:18:52 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0714C1955F40; Wed, 24 Jul 2024 22:18:51 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 11/16] =?utf-8?q?diagnostics=3A_SARIF_output=3A_add_=22worki?= =?utf-8?q?ngDirectory=22_property_=28=C2=A73=2E20=2E19=29?= Date: Wed, 24 Jul 2024 18:18:19 -0400 Message-Id: <20240724221824.585054-12-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org gcc/ChangeLog: * diagnostic-format-sarif.cc (sarif_builder::make_artifact_location_object): Make public. (sarif_invocation::sarif_invocation): Add param "builder". Use it to potentially populate the "workingDirectory" property with the result of pwd (§3.20.19). (sarif_builder::sarif_builder): Pass *this to m_invocation_obj's ctor. gcc/testsuite/ChangeLog: * c-c++-common/diagnostic-format-sarif-file-1.c: Verify that we have a "workingDirectory" property. Signed-off-by: David Malcolm --- gcc/diagnostic-format-sarif.cc | 15 ++++++++++----- .../c-c++-common/diagnostic-format-sarif-file-1.c | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 847e1eb9bdfc..9be84fb268a5 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -125,7 +125,7 @@ class sarif_tool_component : public sarif_object {}; class sarif_invocation : public sarif_object { public: - sarif_invocation (); + sarif_invocation (sarif_builder &builder); void add_notification_for_ice (diagnostic_context &context, const diagnostic_info &diagnostic, @@ -378,6 +378,9 @@ public: std::unique_ptr maybe_make_artifact_content_object (const char *filename) const; + std::unique_ptr + make_artifact_location_object (const char *filename); + private: std::unique_ptr make_result_object (diagnostic_context &context, @@ -404,8 +407,6 @@ private: std::unique_ptr make_artifact_location_object (location_t loc); std::unique_ptr - make_artifact_location_object (const char *filename); - std::unique_ptr make_artifact_location_object_for_pwd () const; std::unique_ptr maybe_make_region_object (location_t loc, @@ -512,10 +513,14 @@ sarif_object::get_or_create_properties () /* class sarif_invocation : public sarif_object. */ -sarif_invocation::sarif_invocation () +sarif_invocation::sarif_invocation (sarif_builder &builder) : m_notifications_arr (::make_unique ()), m_success (true) { + // "workingDirectory" property (SARIF v2.1.0 section 3.20.19) + if (const char *pwd = getpwd ()) + set ("workingDirectory", + builder.make_artifact_location_object (pwd)); } /* Handle an internal compiler error DIAGNOSTIC occurring on CONTEXT. @@ -747,7 +752,7 @@ sarif_builder::sarif_builder (diagnostic_context &context, const char *main_input_filename_, bool formatted) : m_context (context), - m_invocation_obj (::make_unique ()), + m_invocation_obj (::make_unique (*this)), m_results_array (new json::array ()), m_cur_group_result (nullptr), m_seen_any_relative_paths (false), diff --git a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c index 50375465483d..0a3778323792 100644 --- a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c +++ b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c @@ -32,6 +32,7 @@ { dg-final { scan-sarif-file "\"informationUri\": \"" } } { dg-final { scan-sarif-file "\"invocations\": \\\[" } } + { dg-final { scan-sarif-file {"workingDirectory": } } } { dg-final { scan-sarif-file "\"toolExecutionNotifications\": \\\[\\\]" } } { dg-final { scan-sarif-file "\"executionSuccessful\": true" } } From patchwork Wed Jul 24 22:18:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964567 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=OvfMETR3; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpRF2rS9z1yY9 for ; Thu, 25 Jul 2024 08:22:17 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9DD57385DDDF for ; Wed, 24 Jul 2024 22:22:15 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id A884C385B510 for ; Wed, 24 Jul 2024 22:18:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A884C385B510 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A884C385B510 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859540; cv=none; b=BSaItqufqmJi1m55fBVLsHXmRNvHPa73xTKVtz3MoST5QhpYsjdVIwpAPb+UqvZC4VUa5V0NK5MeaJ98LI0+Kmt8G9iVBEQ0riAhrM259Y64ZwIA2tJhpRbNTWLv/WYmXb/v7NQOclBA9tu7ptShVVqhyjo1HHIQHWAzVgI453Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859540; c=relaxed/simple; bh=IvToUSoFPNZ75O2f2QKQOJHe69NlNngGWpoQ2lEqhmU=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=F7k8Ay9lSaKas5r0EsK2+uWeFa5o0haJvl1p+dg6IJ6FQPOUpsaO9DKr3I/wVT+90J56XY6bOizNIrdCM979SgUMBGJvGmCKFzozgDg445yjd1Ur7O6glTzOVwL6zaLriaS7cWqQhqYb6l7oavAGfT7vetpRRAS+PZwv1zbhwzI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859536; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=x3Ml3vDx8sR8WJ8UlopWaXag6CXAyilstz5lQ1P7L7A=; b=OvfMETR3ju5ua7KKQxaiVS+QIk6gxW3jmakIvVXqMotHL8yQ9A9Alt0da0u31rAqsj5AEf zfhHfoOh/BlbWX+REpoFo4BdK65cdBjqvtf61YbqxlbKmXAhLOuQ97qHr/qT73LaPiMfDK 40uSTOLzJ2QQ4w44Z4TjZ9LdB9QIDGs= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-231-Fc9MrKMSNEORcnVAwQgsgQ-1; Wed, 24 Jul 2024 18:18:55 -0400 X-MC-Unique: Fc9MrKMSNEORcnVAwQgsgQ-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2376B1955D44 for ; Wed, 24 Jul 2024 22:18:54 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 47D9A1955F40; Wed, 24 Jul 2024 22:18:53 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 12/16] =?utf-8?q?diagnostics=3A_SARIF_output=3A_add_=22argum?= =?utf-8?q?ents=22_property_=28=C2=A73=2E20=2E2=29?= Date: Wed, 24 Jul 2024 18:18:20 -0400 Message-Id: <20240724221824.585054-13-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org gcc/ChangeLog: * diagnostic-format-sarif.cc (sarif_invocation::sarif_invocation): Add "original_argv" param and use it to populate "arguments" property (§3.20.2). (sarif_builder::sarif_builder): Pass argv to m_invocation_obj's ctor. * diagnostic.cc (diagnostic_context::initialize): Initialize m_original_argv. (diagnostic_context::finish): Clean up m_original_argv. (diagnostic_context::set_original_argv): New. * diagnostic.h: Include "unique-argv.h". (diagnostic_context::set_original_argv): New decl. (diagnostic_context::get_original_argv): New decl. (diagnostic_context::m_original_argv): New field. * toplev.cc: Include "unique-argv.h". (general_init): Add "original_argv" param and move it to global_dc. (toplev::main): Stash a copy of the original argv before expansion, and pass it to general_init for use by SARIF output. * unique-argv.h: New file. gcc/jit/ChangeLog: * jit-playback.cc (jit::playback_context::compile) Add a trailing null to argvec. gcc/testsuite/ChangeLog: * c-c++-common/diagnostic-format-sarif-file-1.c: Verify that we have an "arguments" property (§3.20.2). Signed-off-by: David Malcolm --- gcc/diagnostic-format-sarif.cc | 25 +++++-- gcc/diagnostic.cc | 17 +++++ gcc/diagnostic.h | 10 +++ gcc/jit/jit-playback.cc | 6 +- .../diagnostic-format-sarif-file-1.c | 5 ++ gcc/toplev.cc | 13 +++- gcc/unique-argv.h | 67 +++++++++++++++++++ 7 files changed, 132 insertions(+), 11 deletions(-) create mode 100644 gcc/unique-argv.h diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 9be84fb268a5..6c7216651627 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -125,7 +125,8 @@ class sarif_tool_component : public sarif_object {}; class sarif_invocation : public sarif_object { public: - sarif_invocation (sarif_builder &builder); + sarif_invocation (sarif_builder &builder, + const char * const *original_argv); void add_notification_for_ice (diagnostic_context &context, const diagnostic_info &diagnostic, @@ -329,10 +330,8 @@ public: - GCC supports one-deep nesting of diagnostics (via auto_diagnostic_group), but we only capture location and message information from such nested diagnostics (e.g. we ignore fix-it hints on them) - - doesn't yet capture command-line arguments: would be run.invocations - property (SARIF v2.1.0 section 3.14.11), as invocation objects - (SARIF v2.1.0 section 3.20), but we'd want to capture the arguments to - toplev::main, and the response files. + - although we capture command-line arguments (section 3.20.2), we don't + yet capture response files. - doesn't capture secondary locations within a rich_location (perhaps we should use the "relatedLocations" property: SARIF v2.1.0 section 3.27.22) @@ -513,10 +512,20 @@ sarif_object::get_or_create_properties () /* class sarif_invocation : public sarif_object. */ -sarif_invocation::sarif_invocation (sarif_builder &builder) +sarif_invocation::sarif_invocation (sarif_builder &builder, + const char * const *original_argv) : m_notifications_arr (::make_unique ()), m_success (true) { + // "arguments" property (SARIF v2.1.0 section 3.20.2) + if (original_argv) + { + auto arguments_arr = ::make_unique (); + for (size_t i = 0; original_argv[i]; ++i) + arguments_arr->append_string (original_argv[i]); + set ("arguments", std::move (arguments_arr)); + } + // "workingDirectory" property (SARIF v2.1.0 section 3.20.19) if (const char *pwd = getpwd ()) set ("workingDirectory", @@ -752,7 +761,9 @@ sarif_builder::sarif_builder (diagnostic_context &context, const char *main_input_filename_, bool formatted) : m_context (context), - m_invocation_obj (::make_unique (*this)), + m_invocation_obj + (::make_unique (*this, + context.get_original_argv ())), m_results_array (new json::array ()), m_cur_group_result (nullptr), m_seen_any_relative_paths (false), diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index aa8afd521fa2..c70c394f7ccd 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -261,6 +261,7 @@ diagnostic_context::initialize (int n_opts) m_includes_seen = nullptr; m_client_data_hooks = nullptr; m_diagrams.m_theme = nullptr; + m_original_argv = nullptr; enum diagnostic_text_art_charset text_art_charset = DIAGNOSTICS_TEXT_ART_CHARSET_EMOJI; @@ -385,6 +386,9 @@ diagnostic_context::finish () delete m_urlifier; m_urlifier = nullptr; + + freeargv (m_original_argv); + m_original_argv = nullptr; } void @@ -403,6 +407,19 @@ diagnostic_context::set_client_data_hooks (diagnostic_client_data_hooks *hooks) m_client_data_hooks = hooks; } +void +diagnostic_context::set_original_argv (unique_argv original_argv) +{ + /* Ideally we'd use a unique_argv for m_original_argv, but + diagnostic_context doesn't yet have a ctor/dtor pair. */ + + // Ensure any old value is freed + freeargv (m_original_argv); + + // Take ownership of the new value + m_original_argv = original_argv.release (); +} + void diagnostic_context:: set_option_hooks (diagnostic_option_enabled_cb option_enabled_cb, diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index 84044b90dfcd..1d83879c50ef 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_DIAGNOSTIC_H #define GCC_DIAGNOSTIC_H +#include "unique-argv.h" #include "rich-location.h" #include "pretty-print.h" #include "diagnostic-core.h" @@ -391,6 +392,12 @@ public: void finish (); + void set_original_argv (unique_argv original_argv); + const char * const *get_original_argv () + { + return const_cast (m_original_argv); + } + void set_set_locations_callback (set_locations_callback_t cb) { m_set_locations_cb = cb; @@ -813,6 +820,9 @@ private: text_art::theme *m_theme; } m_diagrams; + + /* Owned by the context. */ + char **m_original_argv; }; inline void diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc index 1b5445d61013..501d5700873e 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -2568,7 +2568,11 @@ compile () if (get_logger ()) for (unsigned i = 0; i < fake_args.length (); i++) get_logger ()->log ("argv[%i]: %s", i, fake_args[i]); - toplev.main (fake_args.length (), + + /* Add a trailing null to argvec; this is not counted in argc. */ + fake_args.safe_push (nullptr); + toplev.main (/* The trailing null is not counted in argv. */ + fake_args.length () - 1, const_cast (fake_args.address ())); exit_scope ("toplev::main"); diff --git a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c index 0a3778323792..c9ad0d238195 100644 --- a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c +++ b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c @@ -32,6 +32,11 @@ { dg-final { scan-sarif-file "\"informationUri\": \"" } } { dg-final { scan-sarif-file "\"invocations\": \\\[" } } + 3.20: "invocation" object: + + 3.20.2 invocation "arguments" property: + { dg-final { scan-sarif-file {"arguments": \[} } } + { dg-final { scan-sarif-file {"workingDirectory": } } } { dg-final { scan-sarif-file "\"toolExecutionNotifications\": \\\[\\\]" } } { dg-final { scan-sarif-file "\"executionSuccessful\": true" } } diff --git a/gcc/toplev.cc b/gcc/toplev.cc index d9e8b34ae7ca..7f19d5c52bd9 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -93,6 +93,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-param-manipulation.h" #include "dbgcnt.h" #include "gcc-urlifier.h" +#include "unique-argv.h" #include "selftest.h" @@ -100,7 +101,7 @@ along with GCC; see the file COPYING3. If not see #include #endif -static void general_init (const char *, bool); +static void general_init (const char *, bool, unique_argv original_argv); static void backend_init (void); static int lang_dependent_init (const char *); static void init_asm_output (const char *); @@ -1000,7 +1001,7 @@ internal_error_function (diagnostic_context *, const char *, va_list *) options are parsed. Signal handlers, internationalization etc. ARGV0 is main's argv[0]. */ static void -general_init (const char *argv0, bool init_signals) +general_init (const char *argv0, bool init_signals, unique_argv original_argv) { const char *p; @@ -1028,6 +1029,8 @@ general_init (const char *argv0, bool init_signals) override it later. */ tree_diagnostics_defaults (global_dc); + global_dc->set_original_argv (std::move (original_argv)); + global_dc->m_source_printing.enabled = global_options_init.x_flag_diagnostics_show_caret; global_dc->m_source_printing.show_event_links_p @@ -2241,10 +2244,14 @@ toplev::main (int argc, char **argv) Increase stack size limits if possible. */ stack_limit_increase (64 * 1024 * 1024); + /* Stash a copy of the original argv before expansion + for use by SARIF output. */ + unique_argv original_argv (dupargv (argv)); + expandargv (&argc, &argv); /* Initialization of GCC's environment, and diagnostics. */ - general_init (argv[0], m_init_signals); + general_init (argv[0], m_init_signals, std::move (original_argv)); /* One-off initialization of options that does not need to be repeated when options are added for particular functions. */ diff --git a/gcc/unique-argv.h b/gcc/unique-argv.h new file mode 100644 index 000000000000..41cabac6b762 --- /dev/null +++ b/gcc/unique-argv.h @@ -0,0 +1,67 @@ +/* C++11 wrapper around libiberty's argv.c + Copyright (C) 2024 Free Software Foundation, Inc. + Contributed by David Malcolm + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_UNIQUE_ARGV_H +#define GCC_UNIQUE_ARGV_H + +/* C++11 wrapper around libiberty's argv.c, with + ownership of the underlying array and strings. */ + +struct unique_argv +{ + /* Take ownership of argv. */ + unique_argv (char **argv) + : m_argv (argv) + { + } + + ~unique_argv () + { + freeargv (m_argv); + } + + unique_argv (const unique_argv &other) = delete; + unique_argv &operator= (const unique_argv &other) = delete; + + unique_argv (unique_argv &&other) + : m_argv (other.m_argv) + { + other.m_argv = nullptr; + } + + unique_argv &operator= (unique_argv &&other) + { + freeargv (m_argv); + m_argv = other.m_argv; + other.m_argv = nullptr; + return *this; + } + + char **release () + { + char **result = m_argv; + m_argv = nullptr; + return result; + } + + char **m_argv; +}; + +#endif /* ! GCC_UNIQUE_ARGV_H */ From patchwork Wed Jul 24 22:18:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964565 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Ow7kiPl5; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpQj1k90z1yY9 for ; Thu, 25 Jul 2024 08:21:49 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6F67B385E827 for ; Wed, 24 Jul 2024 22:21:47 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id DC445385DDCE for ; Wed, 24 Jul 2024 22:18:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DC445385DDCE Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DC445385DDCE Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859539; cv=none; b=xT+jkMsbQq5nHHg3ERKCKlx61IcTN/xZ5Xzu8Gd8Hl4Iq01+lvj0KqRf6CEn2FEFxDLz4me/o0Nvn8kuQ7xCtA76ab9udnxes0FowQ3E6GfwNAoolfXOlzevteMxSBSL6EwNgkh5ZTzHJYpANkiq+jcCfYBOSF6IT6xit8jA2UA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859539; c=relaxed/simple; bh=E64S6ske+XAgR6wETVcvVuhch9Fh8E6n8SoO0spzbvI=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=YP4QlHyGy788sQBKgYKZ4DCJRC/RLVyogddndt2ZAMOvbP19larJXpRNRPTZWMO3zpn4qQgT+ae9xJG741Nj3frp09staGjN7ZQUSGWjb5a3/c5pfhSEoVHTViw5YzAwx8ZD7SoFk9ZaNeck5SK2I8FI8x+03RdLpSCPU2W+Bp4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859537; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qzD0Ty4/o2bcCZ4djr2pVpEle92km/K5m9zQq3n3ato=; b=Ow7kiPl52MJC28aqa3LFHt1LPQqX/h8yp6QADKXC2j4zyZYSAdCLzM4sjqYzvakrhviGOy ZsKDbw1XVjQzXvtg/1AtIjyICdcLWojjQxGDu1l78qdc13uCJlYLtSVbcX7O2cSWXryWVE /v84MlMW02i6Akgk84ELTyUOA1fFhxU= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-665-5RhZhZarPYKYoxCCfrhwYg-1; Wed, 24 Jul 2024 18:18:56 -0400 X-MC-Unique: 5RhZhZarPYKYoxCCfrhwYg-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9436119560BA for ; Wed, 24 Jul 2024 22:18:55 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 90C051955F40; Wed, 24 Jul 2024 22:18:54 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 13/16] =?utf-8?b?ZGlhZ25vc3RpY3M6IFNBUklGIG91dHB1dDogYWRk?= =?utf-8?b?ICJ7c3RhcnQsIGVuZH1UaW1lVXRjIiBwcm9wZXJ0aWVzICjCp8KnMy4yMC43LTgp?= Date: Wed, 24 Jul 2024 18:18:21 -0400 Message-Id: <20240724221824.585054-14-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org gcc/ChangeLog: * diagnostic-format-sarif.cc (make_date_time_string_for_current_time): New. (sarif_invocation::sarif_invocation): Set "startTimeUtc" property (§3.20.7). (sarif_invocation::prepare_to_flush): Set "endTimeUtc" property (§3.20.8). gcc/testsuite/ChangeLog: * c-c++-common/diagnostic-format-sarif-file-1.c: Verify that we have "startTimeUtc" and "endTimeUtc" properties of the correct form. Signed-off-by: David Malcolm --- gcc/diagnostic-format-sarif.cc | 28 +++++++++++++++++++ .../diagnostic-format-sarif-file-1.c | 5 ++++ 2 files changed, 33 insertions(+) diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 6c7216651627..775d01f75744 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -119,6 +119,26 @@ class sarif_tool : public sarif_object {}; class sarif_tool_component : public sarif_object {}; +/* Make a JSON string for the current date and time. + See SARIF v2.1.0 section 3.9 "Date/time properties". + Given that we don't run at the very beginning/end of the + process, it doesn't make sense to be more accurate than + the current second. */ + +static std::unique_ptr +make_date_time_string_for_current_time () +{ + time_t t = time (nullptr); + struct tm *tm = gmtime (&t); + char buf[256]; + snprintf (buf, sizeof (buf) - 1, + ("%04i-%02i-%02iT" + "%02i:%02i:%02iZ"), + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + return ::make_unique (buf); +} + /* Subclass of sarif_object for SARIF "invocation" objects (SARIF v2.1.0 section 3.20). */ @@ -530,6 +550,10 @@ sarif_invocation::sarif_invocation (sarif_builder &builder, if (const char *pwd = getpwd ()) set ("workingDirectory", builder.make_artifact_location_object (pwd)); + + // "startTimeUtc" property (SARIF v2.1.0 section 3.20.7) + set ("startTimeUtc", + make_date_time_string_for_current_time ()); } /* Handle an internal compiler error DIAGNOSTIC occurring on CONTEXT. @@ -559,6 +583,10 @@ sarif_invocation::prepare_to_flush (diagnostic_context &context) this object (SARIF v2.1.0 section 3.8) e.g. for recording time vars. */ if (auto client_data_hooks = context.get_client_data_hooks ()) client_data_hooks->add_sarif_invocation_properties (*this); + + // "endTimeUtc" property (SARIF v2.1.0 section 3.20.8); + set ("endTimeUtc", + make_date_time_string_for_current_time ()); } /* class sarif_artifact : public sarif_object. */ diff --git a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c index c9ad0d238195..fdf602eaae7b 100644 --- a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c +++ b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c @@ -37,6 +37,11 @@ 3.20.2 invocation "arguments" property: { dg-final { scan-sarif-file {"arguments": \[} } } + Expect "startTimeUtc" and "endTimeUtc" properties of the form + "nnnn-nn-nnTnn:nn:nnZ" (3.20.7 and 3.20.8): + { dg-final { scan-sarif-file {"startTimeUtc": "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]Z"} } } + { dg-final { scan-sarif-file {"endTimeUtc": "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]Z"} } } + { dg-final { scan-sarif-file {"workingDirectory": } } } { dg-final { scan-sarif-file "\"toolExecutionNotifications\": \\\[\\\]" } } { dg-final { scan-sarif-file "\"executionSuccessful\": true" } } From patchwork Wed Jul 24 22:18:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964568 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QrSKH0dL; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpRv4n86z1yY9 for ; Thu, 25 Jul 2024 08:22:51 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DE878385DDDD for ; Wed, 24 Jul 2024 22:22:49 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 9036F385C6C6 for ; Wed, 24 Jul 2024 22:18:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9036F385C6C6 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9036F385C6C6 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859541; cv=none; b=rvh719epKLuSMdhm0EtEuz79mRKC0oyiz7VcbgP4r/7b4lbVQCqdp95Onx9oP/POettiWfYqxzkRVkvnndOhiO8Qnlp+2FA4KyVctvKcVZAx1pJ8ylGFWQ2rax8o0WaOR26v5GaqVnGOpWzL6xLixtSxVeqRjUDcCGWfpWLrIww= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859541; c=relaxed/simple; bh=eoAQziLB1NyiU6myxLLtdi48CTcFIXXmpEHe7d2Mh8k=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=r93FfHUvVSROB/aNqIRRQaQHUf+eY4gsZlEqv/yspazySmaNcuk8c1emss6QxWU1mO6oNhx7tSpGAJf2702pzuPfrxUaZc1JsbFDC1TR76RUBfxXz+A356EwhmT2XKIw/LvkaErf6LJ/TIepxaGYiI2bkhy7SFvV/URyMda53l4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859539; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JkE39pLWXgS3YJZi+cnnDYoNt9SwktQIVZR8WUAFub0=; b=QrSKH0dLPOE3E2p4eQEYIhoAIFOYXTjK/ij/wE9axTekyC/ywM1I4vhuC781nOmqjJxgAh 905RYCdS5Bdoj+xyLC/Kbji8aCU4lS6ah5QfOGMOZrmebo/TKEMLCv3xAWHPTnIb7YD16L RZJlF73vC0ad0rpQj3+HA67oeXxGNl4= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-584-3a-p0AYlOMCYOOph-CWPUg-1; Wed, 24 Jul 2024 18:18:57 -0400 X-MC-Unique: 3a-p0AYlOMCYOOph-CWPUg-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 073081955D45 for ; Wed, 24 Jul 2024 22:18:57 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BB0911955F40; Wed, 24 Jul 2024 22:18:55 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 14/16] =?utf-8?q?diagnostics=3A_SARIF_output=3A_add_=22annot?= =?utf-8?q?ations=22_property_=28=C2=A73=2E28=2E6=29?= Date: Wed, 24 Jul 2024 18:18:22 -0400 Message-Id: <20240724221824.585054-15-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org This patch extends our SARIF output so that if a diagnostic has any labelled source ranges, the "location" object gains an "annotations" property capturing them (§3.28.6). For example, given this textual output: ../../src/gcc/testsuite/gcc.dg/bad-binary-ops.c: In function ‘test_2’: ../../src/gcc/testsuite/gcc.dg/bad-binary-ops.c:31:11: error: invalid operands to binary + (have ‘struct s’ and ‘struct t’) 30 | return (some_function () | ~~~~~~~~~~~~~~~~ | | | struct s 31 | + some_other_function ()); | ^ ~~~~~~~~~~~~~~~~~~~~~~ | | | struct t the SARIF output gains this within the result's location[0]: "annotations": [{"startLine": 30, "startColumn": 11, "endColumn": 27, "message": {"text": "struct s"}}, {"startLine": 31, "startColumn": 13, "endColumn": 35, "message": {"text": "struct t"}}]}]}, gcc/ChangeLog: * diagnostic-format-sarif.cc (sarif_builder::make_location_object): Add "annotations" property if there are any labelled ranges (§3.28.6). (selftest::test_make_location_object): Verify annotations are added to location_obj. * json.h (json::array::size): New. (json::array::operator[]): New. * selftest-json.cc (selftest::expect_json_object_with_array_property): New. * selftest-json.h (selftest::expect_json_object_with_array_property): New decl. (EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY): New macro. gcc/testsuite/ChangeLog: * c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c: Verify that we have an "annotations" property for the labelled ranges (§3.28.6). Signed-off-by: David Malcolm --- gcc/diagnostic-format-sarif.cc | 70 ++++++++++++++++++- gcc/json.h | 3 + gcc/selftest-json.cc | 16 +++++ gcc/selftest-json.h | 14 ++++ ...diagnostic-format-sarif-file-Wbidi-chars.c | 8 +++ 5 files changed, 110 insertions(+), 1 deletion(-) diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 775d01f75744..afb29eab5839 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -345,6 +345,7 @@ public: - CWE metadata - diagnostic groups (see limitations below) - logical locations (e.g. cfun) + - labelled ranges (as annotations) Known limitations: - GCC supports one-deep nesting of diagnostics (via auto_diagnostic_group), @@ -361,7 +362,6 @@ public: ("artifact.hashes" property (SARIF v2.1.0 section 3.24.11). - doesn't capture the "analysisTarget" property (SARIF v2.1.0 section 3.27.13). - - doesn't capture labelled ranges - doesn't capture -Werror cleanly - doesn't capture inlining information (can SARIF handle this?) - doesn't capture macro expansion information (can SARIF handle this?). */ @@ -1210,6 +1210,38 @@ sarif_builder::make_location_object (const rich_location &rich_loc, /* "logicalLocations" property (SARIF v2.1.0 section 3.28.4). */ set_any_logical_locs_arr (*location_obj, logical_loc); + /* "annotations" property (SARIF v2.1.0 section 3.28.6). */ + { + /* Create annotations for any labelled ranges. */ + std::unique_ptr annotations_arr = nullptr; + for (unsigned int i = 0; i < rich_loc.get_num_locations (); i++) + { + const location_range *range = rich_loc.get_range (i); + if (const range_label *label = range->m_label) + { + label_text text = label->get_text (i); + if (text.get ()) + { + location_t range_loc = rich_loc.get_loc (i); + auto region + = maybe_make_region_object (range_loc, + rich_loc.get_column_override ()); + if (region) + { + if (!annotations_arr) + annotations_arr = ::make_unique (); + region->set + ("message", make_message_object (text.get ())); + annotations_arr->append (std::move (region)); + } + } + } + } + if (annotations_arr) + location_obj->set ("annotations", + std::move (annotations_arr)); + } + /* A flag for hinting that the diagnostic involves issues at the level of character encodings (such as homoglyphs, or misleading bidirectional control codes), and thus that it will be helpful @@ -2416,6 +2448,9 @@ test_make_location_object (const line_table_case &case_) sarif_builder builder (dc, "MAIN_INPUT_FILENAME", true); + /* These "columns" are byte offsets, whereas later on the columns + in the generated SARIF use sarif_builder::get_sarif_column and + thus respect tabs, encoding. */ const location_t foo = make_location (linemap_position_for_column (line_table, 1), linemap_position_for_column (line_table, 1), @@ -2480,6 +2515,39 @@ test_make_location_object (const line_table_case &case_) } } } + auto annotations + = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (location_obj.get (), + "annotations"); + ASSERT_EQ (annotations->size (), 3); + { + { + auto a0 = (*annotations)[0]; + ASSERT_JSON_INT_PROPERTY_EQ (a0, "startLine", 1); + ASSERT_JSON_INT_PROPERTY_EQ (a0, "startColumn", 1); + ASSERT_JSON_INT_PROPERTY_EQ (a0, "endColumn", 7); + auto message + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (a0, "message"); + ASSERT_JSON_STRING_PROPERTY_EQ (message, "text", "label0"); + } + { + auto a1 = (*annotations)[1]; + ASSERT_JSON_INT_PROPERTY_EQ (a1, "startLine", 1); + ASSERT_JSON_INT_PROPERTY_EQ (a1, "startColumn", 10); + ASSERT_JSON_INT_PROPERTY_EQ (a1, "endColumn", 15); + auto message + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (a1, "message"); + ASSERT_JSON_STRING_PROPERTY_EQ (message, "text", "label1"); + } + { + auto a2 = (*annotations)[2]; + ASSERT_JSON_INT_PROPERTY_EQ (a2, "startLine", 1); + ASSERT_JSON_INT_PROPERTY_EQ (a2, "startColumn", 16); + ASSERT_JSON_INT_PROPERTY_EQ (a2, "endColumn", 25); + auto message + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (a2, "message"); + ASSERT_JSON_STRING_PROPERTY_EQ (message, "text", "label2"); + } + } } /* Run all of the selftests within this file. */ diff --git a/gcc/json.h b/gcc/json.h index f80a5e82caf3..96721edf5365 100644 --- a/gcc/json.h +++ b/gcc/json.h @@ -170,6 +170,9 @@ class array : public value append (v.release ()); } + size_t size () const { return m_elements.length (); } + value *operator[] (size_t i) const { return m_elements[i]; } + private: auto_vec m_elements; }; diff --git a/gcc/selftest-json.cc b/gcc/selftest-json.cc index 86f27cb82999..271e9b441120 100644 --- a/gcc/selftest-json.cc +++ b/gcc/selftest-json.cc @@ -96,6 +96,22 @@ expect_json_object_with_object_property (const location &loc, return static_cast (property_value); } +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the property value is a non-null JSON array. + Return the value of the property as a json::array. + Use LOC for any failures. */ + +const json::array * +expect_json_object_with_array_property (const location &loc, + const json::value *value, + const char *property_name) +{ + const json::value *property_value + = expect_json_object_with_property (loc, value, property_name); + ASSERT_EQ_AT (loc, property_value->get_kind (), json::JSON_ARRAY); + return static_cast (property_value); +} + /* Assert that VALUE is a non-null json::object that has property PROPERTY_NAME, and that the value of that property is a non-null JSON string equalling EXPECTED_VALUE. diff --git a/gcc/selftest-json.h b/gcc/selftest-json.h index 75a20d519a4c..23b4d18951ca 100644 --- a/gcc/selftest-json.h +++ b/gcc/selftest-json.h @@ -77,6 +77,20 @@ expect_json_object_with_object_property (const location &loc, (JSON_VALUE), \ (PROPERTY_NAME)) +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the property value is a non-null JSON array. + Return the value of the property as a json::array. + Use LOC for any failures. */ + +const json::array * +expect_json_object_with_array_property (const location &loc, + const json::value *value, + const char *property_name); +#define EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY(JSON_VALUE, PROPERTY_NAME) \ + expect_json_object_with_array_property ((SELFTEST_LOCATION), \ + (JSON_VALUE), \ + (PROPERTY_NAME)) + /* Assert that VALUE is a non-null json::object that has property PROPERTY_NAME, and that the value of that property is a non-null JSON string equalling EXPECTED_VALUE. diff --git a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c index 8a287d6c8683..f6084ad04a6f 100644 --- a/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c +++ b/gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-Wbidi-chars.c @@ -29,4 +29,12 @@ int main() { { dg-final { scan-sarif-file {"rendered": } } } + Verify that we have an "annotations" property for the + labelled ranges (3.28.6). + { dg-final { scan-sarif-file {"annotations": } } } + and that the annotations capture the labels as messages, + using "." in place of awkard characters: + { dg-final { scan-sarif-file {"message": ."text": "end of bidirectional context"} } } + { dg-final { scan-sarif-file {"message": ."text": "U.202E .RIGHT-TO-LEFT OVERRIDE."} } } + { dg-final { scan-sarif-file {"message": ."text": "U.2066 .LEFT-TO-RIGHT ISOLATE."} } } */ From patchwork Wed Jul 24 22:18:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964562 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Az0A3qGb; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpPr2VMyz1yY9 for ; Thu, 25 Jul 2024 08:21:04 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 95519385DDF2 for ; Wed, 24 Jul 2024 22:21:02 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id F20EC385DC20 for ; Wed, 24 Jul 2024 22:19:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F20EC385DC20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org F20EC385DC20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859544; cv=none; b=onjWdSx/ttK/LSqiL9OVddg7aYWuB//lCq8w2jZxcXZcSCXS/crKXzr8Tr/cew67lUKpLjCn3Y0KhbODzrl6PgOFgZD2kK6X2W8YQZ8CFNpgL9O7UZ2EoqEhYXhwet1GptKl25C1Y6avq6DEy6IFHagHI6BFuP/h6HdLy9yZrkM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859544; c=relaxed/simple; bh=G++I3L5qFhjJGm+MbkPfdIKGPDS2Tam5bwUIGIcKGhg=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=luryoM/welBEx93m3PUyNZxCXWQL+bDh1ZHoC2/ldLiY5O7Ok0qQNc3b7oQYjhdMAiwVki22YxfuMcp50Lx5m6MKkLt01Y0TfJExC4FwGKJFmRPMYlYovGoUy2sRfpWcDRW9BmY//C0Aup8S8WjN3qZbyyEnUVsoxTDx8z5myq0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859541; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0xgGt2sW0CjRSno9hsAe2ombmH9PpzpyRZqmJIMkGWY=; b=Az0A3qGbpWqo7M6uKxanksx1MEwimbOCRxwtnrdMAlyoM1kjMiwEK6GOilZA5lhVKcRccQ xwnQQh1pNm1qbR4tnJTHsCjLKkHw3aNIDv4+merxz0qsmlOijaQerazeymZfTaqgkskF4D PPWQl21wJbcsWIJIZJvDsAzLJRs57vY= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-601-zy0IcEizNDyppjCjDjHeug-1; Wed, 24 Jul 2024 18:18:59 -0400 X-MC-Unique: zy0IcEizNDyppjCjDjHeug-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 275F81955F43 for ; Wed, 24 Jul 2024 22:18:58 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 24F5A1955F40; Wed, 24 Jul 2024 22:18:56 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 15/16] diagnostics: add selftests for SARIF output Date: Wed, 24 Jul 2024 18:18:23 -0400 Message-Id: <20240724221824.585054-16-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org The existing DejaGnu-based tests for our SARIF output used regexes to verify the JSON at the string level, which lets us test for the presence of properties, but doesn't check the overall structure. This patch uses the selftest framework to verify the structure of the tree of JSON values for a log containing one diagnostic. No functional change intended. gcc/ChangeLog: * diagnostic-format-sarif.cc (sarif_builder::flush_to_object): New, using code moved from... (sarif_builder::end_group): ...here. (class selftest::test_sarif_diagnostic_context): New. (selftest::test_simple_log): New. (selftest::diagnostic_format_sarif_cc_tests): Call it. * json.h (json::object::is_empty): New. * selftest-diagnostic.cc (test_diagnostic_context::report): New. * selftest-diagnostic.h (test_diagnostic_context::report): New decl. * selftest-json.cc (selftest::assert_json_string_eq): New. (selftest::expect_json_object_with_string_property): New. (selftest::assert_json_string_property_eq): New. * selftest-json.h (selftest::assert_json_string_eq): New decl. (ASSERT_JSON_STRING_EQ): New macro. (selftest::expect_json_object_with_string_property): New decl. (EXPECT_JSON_OBJECT_WITH_STRING_PROPERTY): New macro. Signed-off-by: David Malcolm --- gcc/diagnostic-format-sarif.cc | 185 ++++++++++++++++++++++++++++++++- gcc/json.h | 2 + gcc/selftest-diagnostic.cc | 14 +++ gcc/selftest-diagnostic.h | 10 ++ gcc/selftest-json.cc | 34 +++++- gcc/selftest-json.h | 27 +++++ 6 files changed, 264 insertions(+), 8 deletions(-) diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index afb29eab5839..816f3210036e 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -380,6 +380,7 @@ public: const diagnostic_diagram &diagram); void end_group (); + std::unique_ptr flush_to_object (); void flush_to_file (FILE *outf); std::unique_ptr @@ -860,6 +861,20 @@ sarif_builder::end_group () m_cur_group_result = nullptr; } +/* Create a top-level object, and add it to all the results + (and other entities) we've seen so far, moving ownership + to the object. */ + +std::unique_ptr +sarif_builder::flush_to_object () +{ + m_invocation_obj->prepare_to_flush (m_context); + std::unique_ptr top + = make_top_level_object (std::move (m_invocation_obj), + std::move (m_results_array)); + return top; +} + /* Create a top-level object, and add it to all the results (and other entities) we've seen so far. @@ -868,12 +883,8 @@ sarif_builder::end_group () void sarif_builder::flush_to_file (FILE *outf) { - m_invocation_obj->prepare_to_flush (m_context); - std::unique_ptr top - = make_top_level_object (std::move (m_invocation_obj), - std::move (m_results_array)); + std::unique_ptr top = flush_to_object (); top->dump (outf, m_formatted); - m_invocation_obj = nullptr; fprintf (outf, "\n"); } @@ -2434,6 +2445,54 @@ diagnostic_output_format_init_sarif_stream (diagnostic_context &context, namespace selftest { +/* A subclass of sarif_output_format for writing selftests. + The JSON output is cached internally, rather than written + out to a file. */ + +class test_sarif_diagnostic_context : public test_diagnostic_context +{ +public: + test_sarif_diagnostic_context () + { + diagnostic_output_format_init_sarif (*this); + + m_format = new buffered_output_format (*this, + "MAIN_INPUT_FILENAME", + true); + set_output_format (m_format); // give ownership; + } + + std::unique_ptr flush_to_object () + { + return m_format->flush_to_object (); + } + +private: + class buffered_output_format : public sarif_output_format + { + public: + buffered_output_format (diagnostic_context &context, + const char *main_input_filename_, + bool formatted) + : sarif_output_format (context, main_input_filename_, formatted) + { + } + bool machine_readable_stderr_p () const final override + { + return false; + } + std::unique_ptr flush_to_object () + { + return m_builder.flush_to_object (); + } + }; + + buffered_output_format *m_format; // borrowed +}; + +/* Test making a sarif_location for a complex rich_location + with labels and escape-on-output. */ + static void test_make_location_object (const line_table_case &case_) { @@ -2550,12 +2609,128 @@ test_make_location_object (const line_table_case &case_) } } +/* Test of reporting a diagnostic to a diagnostic_context and + examining the generated sarif_log. + Verify various basic properties. */ + +static void +test_simple_log () +{ + test_sarif_diagnostic_context dc; + + rich_location richloc (line_table, UNKNOWN_LOCATION); + dc.report (DK_ERROR, richloc, nullptr, 0, "this is a test: %i", 42); + + auto log_ptr = dc.flush_to_object (); + + // 3.13 sarifLog: + auto log = log_ptr.get (); + ASSERT_JSON_STRING_PROPERTY_EQ (log, "$schema", SARIF_SCHEMA); // 3.13.3 + ASSERT_JSON_STRING_PROPERTY_EQ (log, "version", SARIF_VERSION); // 3.13.2 + + auto runs = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (log, "runs"); // 3.13.4 + ASSERT_EQ (runs->size (), 1); + + // 3.14 "run" object: + auto run = (*runs)[0]; + + { + // 3.14.6: + auto tool = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (run, "tool"); + + EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (tool, "driver"); // 3.18.2 + } + + { + // 3.14.11 + auto invocations + = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (run, "invocations"); + ASSERT_EQ (invocations->size (), 1); + + { + // 3.20 "invocation" object: + auto invocation = (*invocations)[0]; + + // 3.20.3 arguments property + + // 3.20.7 startTimeUtc property + EXPECT_JSON_OBJECT_WITH_STRING_PROPERTY (invocation, "startTimeUtc"); + + // 3.20.8 endTimeUtc property + EXPECT_JSON_OBJECT_WITH_STRING_PROPERTY (invocation, "endTimeUtc"); + + // 3.20.19 workingDirectory property + { + auto wd_obj + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (invocation, + "workingDirectory"); + EXPECT_JSON_OBJECT_WITH_STRING_PROPERTY (wd_obj, "uri"); + } + + // 3.20.21 toolExecutionNotifications property + auto notifications + = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY + (invocation, "toolExecutionNotifications"); + ASSERT_EQ (notifications->size (), 0); + } + } + + { + // 3.14.15: + auto artifacts = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (run, "artifacts"); + ASSERT_EQ (artifacts->size (), 1); + + { + // 3.24 "artifact" object: + auto artifact = (*artifacts)[0]; + + // 3.24.2: + auto location + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (artifact, "location"); + ASSERT_JSON_STRING_PROPERTY_EQ (location, "uri", "MAIN_INPUT_FILENAME"); + + // 3.24.6: + auto roles = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (artifact, "roles"); + ASSERT_EQ (roles->size (), 1); + { + auto role = (*roles)[0]; + ASSERT_JSON_STRING_EQ (role, "analysisTarget"); + } + } + } + + { + // 3.14.23: + auto results = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (run, "results"); + ASSERT_EQ (results->size (), 1); + + { + // 3.27 "result" object: + auto result = (*results)[0]; + ASSERT_JSON_STRING_PROPERTY_EQ (result, "ruleId", "error"); + ASSERT_JSON_STRING_PROPERTY_EQ (result, "level", "error"); // 3.27.10 + + { + // 3.27.11: + auto message + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (result, "message"); + ASSERT_JSON_STRING_PROPERTY_EQ (message, "text", + "this is a test: 42"); + } + + // 3.27.12: + EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (result, "locations"); + } + } +} + /* Run all of the selftests within this file. */ void diagnostic_format_sarif_cc_tests () { for_each_line_table_case (test_make_location_object); + test_simple_log (); } } // namespace selftest diff --git a/gcc/json.h b/gcc/json.h index 96721edf5365..21f71fe1c4ab 100644 --- a/gcc/json.h +++ b/gcc/json.h @@ -109,6 +109,8 @@ class object : public value enum kind get_kind () const final override { return JSON_OBJECT; } void print (pretty_printer *pp, bool formatted) const final override; + bool is_empty () const { return m_map.is_empty (); } + void set (const char *key, value *v); /* Set the property KEY of this object, requiring V diff --git a/gcc/selftest-diagnostic.cc b/gcc/selftest-diagnostic.cc index 2684216a49fe..c9e9d7094bd3 100644 --- a/gcc/selftest-diagnostic.cc +++ b/gcc/selftest-diagnostic.cc @@ -60,6 +60,20 @@ test_diagnostic_context::start_span_cb (diagnostic_context *context, default_diagnostic_start_span_fn (context, exploc); } +bool +test_diagnostic_context::report (diagnostic_t kind, + rich_location &richloc, + const diagnostic_metadata *metadata, + int option, + const char * fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + bool result = diagnostic_impl (&richloc, metadata, option, fmt, &ap, kind); + va_end (ap); + return result; +} + } // namespace selftest #endif /* #if CHECKING_P */ diff --git a/gcc/selftest-diagnostic.h b/gcc/selftest-diagnostic.h index 72a65fdb977f..f899443c4961 100644 --- a/gcc/selftest-diagnostic.h +++ b/gcc/selftest-diagnostic.h @@ -40,6 +40,16 @@ class test_diagnostic_context : public diagnostic_context real filename (to avoid printing the names of tempfiles). */ static void start_span_cb (diagnostic_context *context, expanded_location exploc); + + /* Report a diagnostic to this context. For a selftest, this + should only be called on a context that uses a non-standard formatter + that e.g. gathers the results in memory, rather than emits to stderr. */ + bool + report (diagnostic_t kind, + rich_location &richloc, + const diagnostic_metadata *metadata, + int option, + const char * fmt, ...) ATTRIBUTE_GCC_DIAG(6,7); }; } // namespace selftest diff --git a/gcc/selftest-json.cc b/gcc/selftest-json.cc index 271e9b441120..4f52a87538ae 100644 --- a/gcc/selftest-json.cc +++ b/gcc/selftest-json.cc @@ -33,6 +33,20 @@ along with GCC; see the file COPYING3. If not see namespace selftest { +/* Assert that VALUE is a non-null json::string + equalling EXPECTED_VALUE. + Use LOC for any failures. */ + +void +assert_json_string_eq (const location &loc, + const json::value *value, + const char *expected_value) +{ + ASSERT_EQ_AT (loc, value->get_kind (), json::JSON_STRING); + const json::string *str = static_cast (value); + ASSERT_STREQ_AT (loc, expected_value, str->get_string ()); +} + /* Assert that VALUE is a non-null json::object, returning it as such, failing at LOC if this isn't the case. */ @@ -112,6 +126,22 @@ expect_json_object_with_array_property (const location &loc, return static_cast (property_value); } +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the property value is a non-null JSON string. + Return the value of the property as a json::string. + Use LOC for any failures. */ + +const json::string * +expect_json_object_with_string_property (const location &loc, + const json::value *value, + const char *property_name) +{ + const json::value *property_value + = expect_json_object_with_property (loc, value, property_name); + ASSERT_EQ_AT (loc, property_value->get_kind (), json::JSON_STRING); + return static_cast (property_value); +} + /* Assert that VALUE is a non-null json::object that has property PROPERTY_NAME, and that the value of that property is a non-null JSON string equalling EXPECTED_VALUE. @@ -125,9 +155,7 @@ assert_json_string_property_eq (const location &loc, { const json::value *property_value = expect_json_object_with_property (loc, value, property_name); - ASSERT_EQ_AT (loc, property_value->get_kind (), json::JSON_STRING); - const json::string *str = static_cast (property_value); - ASSERT_STREQ_AT (loc, expected_value, str->get_string ()); + assert_json_string_eq (loc, property_value, expected_value); } } // namespace selftest diff --git a/gcc/selftest-json.h b/gcc/selftest-json.h index 23b4d18951ca..80527d702813 100644 --- a/gcc/selftest-json.h +++ b/gcc/selftest-json.h @@ -30,6 +30,19 @@ along with GCC; see the file COPYING3. If not see namespace selftest { +/* Assert that VALUE is a non-null json::string + equalling EXPECTED_VALUE. + Use LOC for any failures. */ + +void +assert_json_string_eq (const location &loc, + const json::value *value, + const char *expected_value); +#define ASSERT_JSON_STRING_EQ(JSON_VALUE, EXPECTED_VALUE) \ + assert_json_string_eq ((SELFTEST_LOCATION), \ + (JSON_VALUE), \ + (EXPECTED_VALUE)) + /* Assert that VALUE is a non-null json::object, returning it as such, failing at LOC if this isn't the case. */ @@ -91,6 +104,20 @@ expect_json_object_with_array_property (const location &loc, (JSON_VALUE), \ (PROPERTY_NAME)) +/* Assert that VALUE is a non-null json::object that has property + PROPERTY_NAME, and that the property value is a non-null JSON string. + Return the value of the property as a json::string. + Use LOC for any failures. */ + +const json::string * +expect_json_object_with_string_property (const location &loc, + const json::value *value, + const char *property_name); +#define EXPECT_JSON_OBJECT_WITH_STRING_PROPERTY(JSON_VALUE, PROPERTY_NAME) \ + expect_json_object_with_string_property ((SELFTEST_LOCATION), \ + (JSON_VALUE), \ + (PROPERTY_NAME)) + /* Assert that VALUE is a non-null json::object that has property PROPERTY_NAME, and that the value of that property is a non-null JSON string equalling EXPECTED_VALUE. From patchwork Wed Jul 24 22:18:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1964569 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=EUqCrZqO; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WTpSG0YPBz1yY9 for ; Thu, 25 Jul 2024 08:23:10 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5EBE0385B82F for ; Wed, 24 Jul 2024 22:23:08 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 67403385DDFF for ; Wed, 24 Jul 2024 22:19:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 67403385DDFF Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 67403385DDFF Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859545; cv=none; b=HHR1OgHzFXzO01TtGMKQ7gLvVEbc4OwvoXIFUkNwkc0jE/Zz995xDWS+us6ZBu2KFW/Zcpely7hpfmkZo1zWxAdnuDzB9do0E30Ip/7XIOj21X+nNLwwepFpQN+dWL6KEBNel8t3IAZFBSjx0lEcpDgDg0dK4TOVE9Ws1Q7+D0U= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1721859545; c=relaxed/simple; bh=aBWF++M/mwtFrmm3y4c1wZEZMKs195NgpU/q/KRCzFY=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=BbOKHOD3oMIk4Wt3Z3lBPe8ykWFXbKpyBBNe0nE7BmnB/gLUiZD2Ai0UVCmQDM43SWJkQ1NFYY/gvPu4SIZ/izap9KmsKQqZ9zdXN9Ji1ziuPGhVtzUU+EoNy99UFXM0w5VuNJ+fyM7o4e0UkgfzPKOvSSEmKyhZ76EZgDakdWQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721859542; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=q6alxi2ySFFVQKd3QsAYH4iNJZynxdIK0J80qLyPh4c=; b=EUqCrZqOpV+LdpARQU+ONs4fys2Dr+GFpPtliaeeUz7Q1YtK/rZip6ZEZPhOe/UHi0Qcum 8TMpSkt2vcKouLB8zcCrJAxI9IRHH7Vo5YpS4DItkRvSp7EsUePk0tZbWd7KwGYvMp5JiF vBaJBfWTkFqIjw1NOZLzKRVc7UynQOs= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-85-QEZL-vtkOqK7hNNcisfaLw-1; Wed, 24 Jul 2024 18:19:00 -0400 X-MC-Unique: QEZL-vtkOqK7hNNcisfaLw-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8FCFE19560AA for ; Wed, 24 Jul 2024 22:18:59 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.183]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5C4CB1955F40; Wed, 24 Jul 2024 22:18:58 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 16/16] diagnostics: SARIF output: tweak output for UNKNOWN_LOCATION Date: Wed, 24 Jul 2024 18:18:24 -0400 Message-Id: <20240724221824.585054-17-dmalcolm@redhat.com> In-Reply-To: <20240724221824.585054-1-dmalcolm@redhat.com> References: <20240724221824.585054-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org gcc/ChangeLog: * diagnostic-format-sarif.cc (sarif_builder::make_locations_arr): Don't add entirely empty location objects, such as for UNKNOWN_LOCATION. (test_sarif_diagnostic_context::test_sarif_diagnostic_context): Add param "main_input_filename". (selftest::test_simple_log): Provide above param. Verify that "locations" is empty. (selftest::test_simple_log_2): New. (selftest::diagnostic_format_sarif_cc_tests): Call it. Signed-off-by: David Malcolm --- gcc/diagnostic-format-sarif.cc | 123 ++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 8 deletions(-) diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 816f3210036e..1fc45c9b4b39 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -1134,8 +1134,12 @@ sarif_builder::make_locations_arr (const diagnostic_info &diagnostic, if (auto client_data_hooks = m_context.get_client_data_hooks ()) logical_loc = client_data_hooks->get_current_logical_location (); - locations_arr->append - (make_location_object (*diagnostic.richloc, logical_loc, role)); + auto location_obj + = make_location_object (*diagnostic.richloc, logical_loc, role); + /* Don't add entirely empty location objects to the array. */ + if (!location_obj->is_empty ()) + locations_arr->append (std::move (location_obj)); + return locations_arr; } @@ -2452,12 +2456,12 @@ namespace selftest { class test_sarif_diagnostic_context : public test_diagnostic_context { public: - test_sarif_diagnostic_context () + test_sarif_diagnostic_context (const char *main_input_filename) { diagnostic_output_format_init_sarif (*this); m_format = new buffered_output_format (*this, - "MAIN_INPUT_FILENAME", + main_input_filename, true); set_output_format (m_format); // give ownership; } @@ -2609,14 +2613,14 @@ test_make_location_object (const line_table_case &case_) } } -/* Test of reporting a diagnostic to a diagnostic_context and - examining the generated sarif_log. +/* Test of reporting a diagnostic at UNKNOWN_LOCATION to a + diagnostic_context and examining the generated sarif_log. Verify various basic properties. */ static void test_simple_log () { - test_sarif_diagnostic_context dc; + test_sarif_diagnostic_context dc ("MAIN_INPUT_FILENAME"); rich_location richloc (line_table, UNKNOWN_LOCATION); dc.report (DK_ERROR, richloc, nullptr, 0, "this is a test: %i", 42); @@ -2719,7 +2723,109 @@ test_simple_log () } // 3.27.12: - EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (result, "locations"); + auto locations + = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (result, "locations"); + ASSERT_EQ (locations->size (), 0); + } + } +} + +/* As above, but with a "real" location_t. */ + +static void +test_simple_log_2 (const line_table_case &case_) +{ + auto_fix_quotes fix_quotes; + + const char *const content + /* 000000000111111 + 123456789012345. */ + = "unsinged int i;\n"; + diagnostic_show_locus_fixture f (case_, content); + location_t line_end = linemap_position_for_column (line_table, 31); + + /* Don't attempt to run the tests if column data might be unavailable. */ + if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS) + return; + + test_sarif_diagnostic_context dc (f.get_filename ()); + + const location_t typo_loc + = make_location (linemap_position_for_column (line_table, 1), + linemap_position_for_column (line_table, 1), + linemap_position_for_column (line_table, 8)); + + rich_location richloc (line_table, typo_loc); + dc.report (DK_ERROR, richloc, nullptr, 0, + "did you misspell %qs again?", + "unsigned"); + + auto log_ptr = dc.flush_to_object (); + + // 3.13 sarifLog: + auto log = log_ptr.get (); + + auto runs = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (log, "runs"); // 3.13.4 + ASSERT_EQ (runs->size (), 1); + + // 3.14 "run" object: + auto run = (*runs)[0]; + + { + // 3.14.23: + auto results = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (run, "results"); + ASSERT_EQ (results->size (), 1); + + { + // 3.27 "result" object: + auto result = (*results)[0]; + ASSERT_JSON_STRING_PROPERTY_EQ (result, "ruleId", "error"); + ASSERT_JSON_STRING_PROPERTY_EQ (result, "level", "error"); // 3.27.10 + + { + // 3.27.11: + auto message + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (result, "message"); + ASSERT_JSON_STRING_PROPERTY_EQ (message, "text", + "did you misspell `unsigned' again?"); + } + + // 3.27.12: + auto locations + = EXPECT_JSON_OBJECT_WITH_ARRAY_PROPERTY (result, "locations"); + ASSERT_EQ (locations->size (), 1); + + { + // 3.28 "location" object: + auto location = (*locations)[0]; + + auto physical_location + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (location, + "physicalLocation"); + { + auto region + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (physical_location, + "region"); + ASSERT_JSON_INT_PROPERTY_EQ (region, "startLine", 1); + ASSERT_JSON_INT_PROPERTY_EQ (region, "startColumn", 1); + ASSERT_JSON_INT_PROPERTY_EQ (region, "endColumn", 9); + } + { + auto context_region + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (physical_location, + "contextRegion"); + ASSERT_JSON_INT_PROPERTY_EQ (context_region, "startLine", 1); + + { + auto snippet + = EXPECT_JSON_OBJECT_WITH_OBJECT_PROPERTY (context_region, + "snippet"); + + /* We expect the snippet's "text" to be a copy of the content. */ + ASSERT_JSON_STRING_PROPERTY_EQ (snippet, "text", f.m_content); + } + } + } } } } @@ -2731,6 +2837,7 @@ diagnostic_format_sarif_cc_tests () { for_each_line_table_case (test_make_location_object); test_simple_log (); + for_each_line_table_case (test_simple_log_2); } } // namespace selftest