From patchwork Thu Oct 11 12:52:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 982459 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-487322-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="B4ijWIHF"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42W9qZ4bfJz9s7h for ; Thu, 11 Oct 2018 23:52:57 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=X4bBh6NZjWJT6u5a+4HOQNe8BuVB2 hUyF7s7pDoIe4+pEUYDjdHuP9AmxpYQb5gbNmHap3bby/4K0pwppSbMhl3bDNK+x 9ebo5CVdv2rBBiLYDBJ5MrBFvAboaig6PKY42A3foKnsiCpoYCRjgSXogVGY0EtH 98q0c+LZHjEqx0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=FWTYNzqy+pMfeyHQfyFaomlSy1g=; b=B4i jWIHFS8Ro3Oxxd5nzBzS7Y438OwNZvo3KRiZID+rt19zrjqcWYMfiQo2RXI6hjbk FXZL4RTH8Ex6li8gZic2G1l5EMFiBLP9KH910MqeGbvHRk9R0fzloM7RU2jqAONT gLePqfCdjOhRrba1Rj1CE7CGb94oJpkRR0guvgFI= Received: (qmail 7679 invoked by alias); 11 Oct 2018 12:52:49 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 7664 invoked by uid 89); 11 Oct 2018 12:52:49 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=decl_initial, DECL_INITIAL X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 11 Oct 2018 12:52:43 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5DF653091D4E for ; Thu, 11 Oct 2018 12:52:42 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-117-222.ams2.redhat.com [10.36.117.222]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F3AEE84538; Thu, 11 Oct 2018 12:52:40 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id w9BCqcQG023235; Thu, 11 Oct 2018 14:52:39 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id w9BCqbrB023234; Thu, 11 Oct 2018 14:52:37 +0200 Date: Thu, 11 Oct 2018 14:52:37 +0200 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [C++ PATCH] Fix -Wreturn-local-addr handling of structured bindings (PR c++/87582) Message-ID: <20181011125237.GZ11625@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.9.2 (2017-12-15) X-IsSubscribed: yes Hi! Except for std::tuple* structured bindings, the VAR_DECLs we create for the identifiers aren't actually variables, but placeholders with DECL_VALUE_EXPR. If the structured binding is not a reference, it is still an automatic variable and so -Wreturn-local-addr should warn on those, but if it is a reference, then it depends if it references an automatic variable or something else. The following patch handles it by recursing for references on the initializer of the structured binding. Note we don't just emit incorrect warning without this patch, but the caller replaces return something; with return (something, 0); if maybe_warn_about_returning_address_of_local returns true, so it is also invalid at runtime. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and release branches? 2018-10-11 Jakub Jelinek PR c++/87582 * typeck.c (maybe_warn_about_returning_address_of_local): If whats_returned is a structured binding identifier and the structured binding is a reference, recurse on its initializer. * g++.dg/cpp1z/decomp48.C: New test. Jakub --- gcc/cp/typeck.c.jj 2018-09-13 09:27:31.547765011 +0200 +++ gcc/cp/typeck.c 2018-10-11 10:06:36.820295475 +0200 @@ -9096,6 +9096,22 @@ maybe_warn_about_returning_address_of_lo && !(TREE_STATIC (whats_returned) || TREE_PUBLIC (whats_returned))) { + if (VAR_P (whats_returned) + && DECL_DECOMPOSITION_P (whats_returned) + && DECL_DECOMP_BASE (whats_returned) + && DECL_HAS_VALUE_EXPR_P (whats_returned)) + { + /* When returning address of a structured binding, if the structured + binding is not a reference, continue normally, if it is a + reference, recurse on the initializer of the structured + binding. */ + tree base = DECL_DECOMP_BASE (whats_returned); + if (TYPE_REF_P (TREE_TYPE (base))) + { + tree init = DECL_INITIAL (base); + return maybe_warn_about_returning_address_of_local (init); + } + } bool w = false; auto_diagnostic_group d; if (TYPE_REF_P (valtype)) --- gcc/testsuite/g++.dg/cpp1z/decomp48.C.jj 2018-10-11 10:30:09.255651339 +0200 +++ gcc/testsuite/g++.dg/cpp1z/decomp48.C 2018-10-11 11:00:23.210283412 +0200 @@ -0,0 +1,134 @@ +// PR c++/87582 +// { dg-do run { target c++11 } } +// { dg-options "-Wreturn-local-addr" } + +struct S { int s, t; }; +S v {1, 2}; +int a[3] = {1, 2, 3}; + +int & +f1 () +{ + auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-bogus "reference to local variable '.' returned" } +} + +int & +f2 () +{ + S v {1, 2}; + auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 'v' returned" } +} + +int & +f3 () +{ + auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-bogus "reference to local variable '.' returned" } +} + +int & +f4 () +{ + int a[3] = {1, 2, 3}; + auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 'a' returned" } +} + +int & +f5 () +{ + auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 's' returned" } +} + +int & +f6 () +{ + S v {1, 2}; + auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 's' returned" } +} + +int & +f7 () +{ + auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 's' returned" } +} + +int & +f8 () +{ + int a[3] = {1, 2, 3}; + auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return s; // { dg-warning "reference to local variable 's' returned" } +} + +int * +f9 () +{ + auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-bogus "address of local variable '.' returned" } +} + +int * +f10 () +{ + S v {1, 2}; + auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 'v' returned" } +} + +int * +f11 () +{ + auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-bogus "address of local variable '.' returned" } +} + +int * +f12 () +{ + int a[3] = {1, 2, 3}; + auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 'a' returned" } +} + +int * +f13 () +{ + auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 's' returned" } +} + +int * +f14 () +{ + S v {1, 2}; + auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 's' returned" } +} + +int * +f15 () +{ + auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 's' returned" } +} + +int * +f16 () +{ + int a[3] = {1, 2, 3}; + auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + return &s; // { dg-warning "address of local variable 's' returned" } +} + +int +main () +{ + if (&f1 () != &v.s || &f3 () != &a[0] || f9 () != &v.s || f11 () != &a[0]) + __builtin_abort (); +}