From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5272 invoked by alias); 4 Aug 2016 12:58:13 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 5254 invoked by uid 89); 4 Aug 2016 12:58:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=Included, life, blessed, 50000 X-HELO: mail-wm0-f45.google.com Received: from mail-wm0-f45.google.com (HELO mail-wm0-f45.google.com) (74.125.82.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 04 Aug 2016 12:58:03 +0000 Received: by mail-wm0-f45.google.com with SMTP id o80so377297914wme.1 for ; Thu, 04 Aug 2016 05:58:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=smPFGL53yE3J+Ci1dxuPlVsWauZS2hXAsOCFDsSE4lY=; b=hxwtKs7/eGiYbO45W5gmf/9YNSgM7beH2EV2swTaWICmICS4uA9KIeM9l6t1xBLyQh cie8thhkPYWLE3RP9JTcrfPxFc/3JAYZLk16JV2t+v9yZt1WQRgcX76Isa8i92OTlPdu d8wE1LLtiwJPuw2TSK6GN+LFXEhu5LkpKecC/YuhPsNDx5uteMvDv7cCjvdsgFE6xC9D Tod+XcgVk74noGvJ5U5X6vl5Ph0ghaXOYS2Gr7eXqZjmbEzXzzQmZ5UiocpJIC6zPLv9 0F2XEkxRKLT6BLxzBzUSNM1jZoOaxf2wJ0hwyBQc6A6ztS098/9M6ENJrGXt5iz43YNK ODug== X-Gm-Message-State: AEkooutbieDci8kTZkbT00qr7AJFN+id6P8lKy4D5TI9XwloTs6wzXR7p37xqh0fMhkYG48mbCA3DMimz3eWpA== X-Received: by 10.28.9.194 with SMTP id 185mr28234715wmj.37.1470315480210; Thu, 04 Aug 2016 05:58:00 -0700 (PDT) MIME-Version: 1.0 Received: by 10.28.137.202 with HTTP; Thu, 4 Aug 2016 05:57:59 -0700 (PDT) In-Reply-To: <57A32741.7010003@redhat.com> References: <57A32741.7010003@redhat.com> From: Richard Biener Date: Thu, 04 Aug 2016 12:58:00 -0000 Message-ID: Subject: Re: protected alloca class for malloc fallback To: Aldy Hernandez Cc: gcc-patches Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2016-08/txt/msg00314.txt.bz2 On Thu, Aug 4, 2016 at 1:30 PM, Aldy Hernandez wrote: > Howdy! > > As part of my -Walloca-larger-than=life work, I've been running said pass > over gcc, binutils, and gdb, and trying to fix things along the way. > > Particularly irritating and error prone is having to free malloc'd pointers > on every function exit point. We end up with a lot of: > > foo(size_t len) > { > void *p, *m_p = NULL; > if (len < HUGE) > p = alloca(len); > else > p = m_p = malloc(len); > if (something) > goto out; > stuff(); > out: > free (m_p); > } > > ...which nobody really likes. > > I've been thinking that for GCC we could have a protected_alloca class whose > destructor frees any malloc'd memory: > > void foo() > { > char *p; > protected_alloca chunk(50000); > p = (char *) chunk.pointer(); > f(p); > } > > This would generate: > > void foo() () > { > void * _3; > > : > _3 = malloc (50000); > f (_3); > > : > free (_3); [tail call] > return; > } > > Now the problem with this is that the memory allocated by chunk is freed > when it goes out of scope, which may not be what you want. For example: > > func() > { > char *str; > { > protected_alloca chunk (99999999); > // malloc'd pointer will be freed when chunk goes out of scope. > str = (char *) chunk.pointer (); > } > use (str); // BAD! Use after free. > } But how's that an issue if the chunk is created at the exact place where there previously was an alloca? Your class also will not work when internal_alloc is not inlined and the alloca path is taken like when using non-GCC host compilers. > In the attached patch implementing this class I have provided another idiom > for avoiding this problem: > > func() > { > void *ptr; > protected_alloca chunk; > { > chunk.alloc (9999999); > str = (char *) chunk.pointer (); > } > // OK, pointer will be freed on function exit. > use (str); > } > > So I guess it's between annoying gotos and keeping track of multiple exit > points to a function previously calling alloca, or making sure the > protected_alloca object always resides in the scope where the memory is > going to be used. > > Is there a better blessed C++ way? If not, is this OK? It looks like you want to replace _all_ alloca uses? What's the point in doing this at all? Just to be able to enable the warning during bootstrap? Having the conditional malloc/alloca will also inhibit optimization like eliding the malloc or alloca calls completely. Thanks, Richard. > Included is the conversion of tree.c. More to follow once we agree on a > solution. > > Tested on x86-64 Linux. > > Aldy