From patchwork Wed Feb 10 17:16:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1439143 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=Q8TwmJdA; dkim-atps=neutral Received: from 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 RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DbRJ61Nx5z9sBJ for ; Thu, 11 Feb 2021 04:16:37 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 30E94398E468; Wed, 10 Feb 2021 17:16:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 30E94398E468 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1612977394; bh=Jv3ysMj9lHB97tr6YmWAWTivgqUkEVcghPRea3e/m5M=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Q8TwmJdAawEhpdaLUlGb8JOwKYSONen3HdN4QdgtqvyYu8rlOLAVCQiO5gOrsNTz4 EF9jfplSa6NYywxnXKCazHjJ7WwD/9IQiKQ4QUw8pT84Epaz94R4fCTmixseSHBgHI QOUeS+o9Cwz/Oop99oWvuIBgPGzANpd7vlpCm+Dw= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qk1-x735.google.com (mail-qk1-x735.google.com [IPv6:2607:f8b0:4864:20::735]) by sourceware.org (Postfix) with ESMTPS id 0F6763971416 for ; Wed, 10 Feb 2021 17:16:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 0F6763971416 Received: by mail-qk1-x735.google.com with SMTP id u20so2382933qku.7 for ; Wed, 10 Feb 2021 09:16:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language; bh=Jv3ysMj9lHB97tr6YmWAWTivgqUkEVcghPRea3e/m5M=; b=uV2F73h2u0S2OfCbbOTd1dfICGCTOrZk3jc39aWeitcPFT+SqAsJDlodGSPU/4S8gC jlT49LanHzrnOS69wNCXLXgPTSjAkecgwHSmJ4Fqz/gq0lJDClT9vjiBITT7HBakDSUi ko4YKPKuzCutxWEUXqkn4/i+ImpnwP3vbI9uSECbFtx4y0BuqtQHwmimiGL+G39FcTky Z9Rm+W2e61xjvCGkw7ggaD5sh+Wa6nDvaA01ZAU74f5ihlPCJez44Vcq+BYbJRpifQC9 PhkHC3PkL2maokFzP5W2GMng9HtCjjcoZekh+pIO1dfS4tyJLa82GWsyjQ+hvy9VlH1O PdLA== X-Gm-Message-State: AOAM533RPmdGcg83OSblHCZdieDlT8dMgCWb7Uyf1zzmIFK6LXTQMDDl GWYNgiCtbTvEymhV3OHup5U= X-Google-Smtp-Source: ABdhPJy2dr4KKacEMQW+TayB7+SBBZORmGNJXRGKAmKR1mxSTuO/UGIOd8RhL4xcRZnuF0gyewXzCg== X-Received: by 2002:a37:8381:: with SMTP id f123mr4383581qkd.417.1612977390661; Wed, 10 Feb 2021 09:16:30 -0800 (PST) Received: from [192.168.0.41] (184-96-239-30.hlrn.qwest.net. [184.96.239.30]) by smtp.gmail.com with ESMTPSA id c63sm1905353qkf.8.2021.02.10.09.16.29 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 10 Feb 2021 09:16:29 -0800 (PST) To: gcc-patches , Richard Biener Subject: [PATCH] plug memory leaks in warn_parm_array_mismatch (PR 99055) Message-ID: Date: Wed, 10 Feb 2021 10:16:28 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Martin Sebor via Gcc-patches From: Martin Sebor Reply-To: Martin Sebor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The attached patch replaces calls to print_generic_expr_to_str() with a helper function that returns a std::string and releases the caller from the responsibility to explicitly free memory. With the patch installed, Valgrind shows more leaks in this code that I'm not sure what to do about: 1) A tree built by build_type_attribute_qual_variant() called from attr_access::array_as_string() to build a temporary type only for the purposes of formatting it. 2) A tree (an attribute list) built by tree_cons() called from build_attr_access_from_parms() that's used only for the duration of the caller. Do these temporary trees need to be released somehow or are the leaks expected? Martin Leak 1: ==7112== 56 bytes in 1 blocks are still reachable in loss record 73 of 691 ==7112== at 0x483AB1A: calloc (vg_replace_malloc.c:762) ==7112== by 0x294ED71: xcalloc (xmalloc.c:162) ==7112== by 0xB8B21D: alloc_page(unsigned int) (ggc-page.c:918) ==7112== by 0xB8BAD1: ggc_internal_alloc(unsigned long, void (*)(void*), unsigned long, unsigned long) (ggc-page.c:1294) ==7112== by 0x9E1F33: ggc_internal_alloc(unsigned long) (ggc.h:130) ==7112== by 0x198AB1A: ggc_alloc_tree_node_stat(unsigned long) (ggc.h:309) ==7112== by 0x193BD18: copy_node(tree_node*) (tree.c:1223) ==7112== by 0x1953BDD: build_distinct_type_copy(tree_node*) (tree.c:6730) ==7112== by 0x9A1379: build_type_attribute_qual_variant(tree_node*, tree_node*, int) (attribs.c:1161) ==7112== by 0x9A483D: attr_access::array_as_string[abi:cxx11](tree_node*) const (attribs.c:2332) ==7112== by 0xB7C5A7: warn_parm_array_mismatch(unsigned int, tree_node*, tree_node*) (c-warn.c:3449) ==7112== by 0xA3EB57: c_parser_declaration_or_fndef(c_parser*, bool, bool, bool, bool, bool, tree_node**, vec, bool, tree_node*, oacc_routine_data*, bool*) (c-parser.c:2342) Leak 2: ==7112== 64 bytes in 1 blocks are still reachable in loss record 150 of 691 ==7112== at 0x483AB1A: calloc (vg_replace_malloc.c:762) ==7112== by 0x294ED71: xcalloc (xmalloc.c:162) ==7112== by 0xB8B21D: alloc_page(unsigned int) (ggc-page.c:918) ==7112== by 0xB8BAD1: ggc_internal_alloc(unsigned long, void (*)(void*), unsigned long, unsigned long) (ggc-page.c:1294) ==7112== by 0x9E1F33: ggc_internal_alloc(unsigned long) (ggc.h:130) ==7112== by 0x198AB1A: ggc_alloc_tree_node_stat(unsigned long) (ggc.h:309) ==7112== by 0x19433E6: tree_cons(tree_node*, tree_node*, tree_node*) (tree.c:3331) ==7112== by 0xB67188: build_attr_access_from_parms(tree_node*, bool) (c-attribs.c:5060) ==7112== by 0xB7C008: warn_parm_array_mismatch(unsigned int, tree_node*, tree_node*) (c-warn.c:3364) ==7112== by 0xA3EB57: c_parser_declaration_or_fndef(c_parser*, bool, bool, bool, bool, bool, tree_node**, vec, bool, tree_node*, oacc_routine_data*, bool*) (c-parser.c:2342) ==7112== by 0xA3D5A9: c_parser_external_declaration(c_parser*) (c-parser.c:1777) ==7112== by 0xA3D06A: c_parser_translation_unit(c_parser*) (c-parser.c:1650) PR c/99055 - memory leak in warn_parm_array_mismatch gcc/c-family/ChangeLog: PR c/99055 * c-warn.c (generic_expr_as_string): New function. (warn_parm_array_mismatch): Replace calls to print_generic_expr_to_str with generic_expr_as_string. gcc/ChangeLog: * tree-pretty-print.c (print_generic_expr_to_str): Update comment. diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index e6e28d9b139..8cbc598bf6f 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -3319,6 +3319,20 @@ warn_parm_ptrarray_mismatch (location_t origloc, tree curparms, tree newparms) } } +/* Same as print_generic_expr_to_str but returning std::string to keep + callers from having to free memory. */ + +static std::string +generic_expr_as_string (tree expr, const char *dflt = "") +{ + if (!expr) + return dflt; + + pretty_printer pp; + dump_generic_node (&pp, expr, 0, TDF_VOPS | TDF_MEMSYMS, false); + return std::string (pp_formatted_text (&pp)); +} + /* Detect and diagnose a mismatch between an attribute access specification on the original declaration of FNDECL and that on the parameters NEWPARMS from its refeclaration. ORIGLOC is the location of the first declaration @@ -3585,10 +3599,8 @@ warn_parm_array_mismatch (location_t origloc, tree fndecl, tree newparms) the same. */ continue; - const char* const newbndstr = - newbnd ? print_generic_expr_to_str (newbnd) : "*"; - const char* const curbndstr = - curbnd ? print_generic_expr_to_str (curbnd) : "*"; + std::string newbndstr = generic_expr_as_string (newbnd, "*"); + std::string curbndstr = generic_expr_as_string (curbnd, "*"); if (!newpos != !curpos || (newpos && !tree_int_cst_equal (newpos, curpos))) @@ -3619,7 +3631,7 @@ warn_parm_array_mismatch (location_t origloc, tree fndecl, tree newparms) "argument %u of type %s declared " "with mismatched bound %<%s%>", parmpos + 1, newparmstr.c_str (), - newbndstr); + newbndstr.c_str ()); if (warned) { @@ -3633,8 +3645,9 @@ warn_parm_array_mismatch (location_t origloc, tree fndecl, tree newparms) curparmstr.c_str (), plus_one (curpos)); } else - inform (&richloc, "previously declared as %s with bound " - "%<%s%>", curparmstr.c_str (), curbndstr); + inform (&richloc, + "previously declared as %s with bound %<%s%>", + curparmstr.c_str (), curbndstr.c_str ()); continue; } @@ -3651,9 +3664,10 @@ warn_parm_array_mismatch (location_t origloc, tree fndecl, tree newparms) if (warning_at (newloc, OPT_Wvla_parameter, "argument %u of type %s declared with " "mismatched bound %<%s%>", - parmpos + 1, newparmstr.c_str (), newbndstr)) + parmpos + 1, newparmstr.c_str (), + newbndstr.c_str ())) inform (origloc, "previously declared as %s with bound %qs", - curparmstr.c_str (), curbndstr); + curparmstr.c_str (), curbndstr.c_str ()); continue; } } diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index aabe6bb23b9..986f75d1d5f 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -169,7 +169,8 @@ print_generic_expr (FILE *file, tree t, dump_flags_t flags) pp_flush (tree_pp); } -/* Print a single expression T to string, and return it. */ +/* Print a single expression T to string, and return it. The caller + must free the returned memory. */ char * print_generic_expr_to_str (tree t)