From patchwork Wed Jul 25 02:07:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 948987 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-482258-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="SRGr6xdC"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="cPnIWZmi"; 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 41ZzBp6dmBz9s1R for ; Wed, 25 Jul 2018 12:07:28 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=wPEnEbEYUey/a750AY85Ygrh1MAWm0EbuncmGf6ndHylhO26apjsA UZ/HpvOMnKnhvJq6ocQGsvphKP3W0Ozn8CrpNUfLcE+4Y93jx04SR2vJ+PIFQ2v/ k5sE38wyB+1jrjJn0Blzk09XVe0DVFtXOfVJCYmpU5lxxnGI86sMaM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=U/RnUrRrfKrVYOMFi9ArBp99z4M=; b=SRGr6xdCaiw68YYE6yXg lZL7H09T7LTQ2baRqu52FbTIoAWlEKKPM+LOPu5ixMMg03JJSnlJH29ztMeBkSCQ T4NGAYRjgF4x13ML2mVefwUDq52954sm5hjsvh0GMzWwP/r9Oys7udBXrN+nzo4R 5MArZSK3FPhlx76h8c3VvJI= Received: (qmail 19083 invoked by alias); 25 Jul 2018 02:07:17 -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 19036 invoked by uid 89); 25 Jul 2018 02:07:17 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=sk:alloca_, H*MI:c241, H*M:c241, sk:Walloca X-HELO: mail-qt0-f173.google.com Received: from mail-qt0-f173.google.com (HELO mail-qt0-f173.google.com) (209.85.216.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 25 Jul 2018 02:07:15 +0000 Received: by mail-qt0-f173.google.com with SMTP id y19-v6so6218065qto.5 for ; Tue, 24 Jul 2018 19:07:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:message-id:date:user-agent:mime-version; bh=huP75hA2LDL6uOQpEsNpVBjek2RMAjvydrRR/kbOxI4=; b=cPnIWZmikGAvjL0rTPpk3GlZfgXFNXBV5pS+kwuMMaESovUqZsKyHXjiRfbJ1e6Vn9 3ARjqTPFjLKro/jZRqokw1aK+LAzHfAIbSueArkBgr0pThRV9yOswYXmPfBR/txKd4po vYkLURQKUhY6exw6RRE6gCgIuq8z6M2cMW7cVRPog+7qk/XVPvZOcrVGPNB8HC7YI6uk MTwayMfuV+m6FDo9FqmQkTO51GKxDaPO2cvEeeR+pLNPhz8AkqyBQ0VYehL5Z+qJj3nf IopdhqpunsVPwsV8Fs0PJa2orO9ccOsM9tE9L6evwGSeFA/rLS31och/dXBsBOcIlDGW eMIA== Received: from localhost.localdomain (97-118-124-30.hlrn.qwest.net. [97.118.124.30]) by smtp.gmail.com with ESMTPSA id r67-v6sm8103838qkd.10.2018.07.24.19.07.11 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Jul 2018 19:07:11 -0700 (PDT) From: Martin Sebor Subject: [PATCH] treat -Wxxx-larger-than=HWI_MAX special (PR 86631) To: Gcc Patch List Message-ID: Date: Tue, 24 Jul 2018 20:07:09 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 X-IsSubscribed: yes The very large option argument enhancement committed last week inadvertently introduced an assumption about the LP64 data model that makes the -Wxxx-larger-than options have a different effect at their default documented setting of PTRDIFF_MAX between ILP32 and LP64. As a result, the options are treated as suppressed in ILP32 while triggering the expected warnings for allocations or sizes in excess of the limit in ILP64. To remove this I considered making it possible to use symbolic constants like PTRDIFF_MAX as the option arguments so that then defaults in the .opt files could be set to that. Sadly, options in GCC are processed before the values of constants like PTRDIFF_MAX for the target are known, and deferring the handling of just the -Wxxx-larger-than= options until the constants have been computed would be too involved to make it worth the effort. To keep things simple I decided to have the code that handles each of the affected options treat the HOST_WIDE_INT_MAX default as a special request to substitute the value of PTRDIFF_MAX at the time. The attached patch implements this. Tested on x86_64-linux with -m32/-m64. Martin PR middle-end/86631 - missing -Walloc-size-larger-than on ILP32 hosts gcc/ChangeLog: PR middle-end/86631 * calls.c (alloc_max_size): Treat HOST_WIDE_INT special. * gimple-ssa-warn-alloca.c (adjusted_warn_limit): New function. (pass_walloca::gate): Use it. (alloca_call_type): Same. (pass_walloca::execute): Same. * stor-layout.c (layout_decl): Treat HOST_WIDE_INT special. gcc/testsuite/ChangeLog: PR middle-end/86631 * g++.dg/Walloca1.C: Adjust. Index: gcc/calls.c =================================================================== --- gcc/calls.c (revision 262951) +++ gcc/calls.c (working copy) @@ -1222,9 +1222,12 @@ alloc_max_size (void) if (alloc_object_size_limit) return alloc_object_size_limit; - alloc_object_size_limit - = build_int_cst (size_type_node, warn_alloc_size_limit); + HOST_WIDE_INT limit = warn_alloc_size_limit; + if (limit == HOST_WIDE_INT_MAX) + limit = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node)); + alloc_object_size_limit = build_int_cst (size_type_node, limit); + return alloc_object_size_limit; } Index: gcc/gimple-ssa-warn-alloca.c =================================================================== --- gcc/gimple-ssa-warn-alloca.c (revision 262951) +++ gcc/gimple-ssa-warn-alloca.c (working copy) @@ -38,6 +38,8 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "intl.h" +static unsigned HOST_WIDE_INT adjusted_warn_limit (bool); + const pass_data pass_data_walloca = { GIMPLE_PASS, "walloca", @@ -82,7 +84,9 @@ pass_walloca::gate (function *fun ATTRIBUTE_UNUSED // Warning is disabled when its size limit is greater than PTRDIFF_MAX // for the target maximum, which makes the limit negative since when // represented in signed HOST_WIDE_INT. - return warn_alloca_limit >= 0 || warn_vla_limit >= 0; + unsigned HOST_WIDE_INT max = tree_to_uhwi (TYPE_MAX_VALUE (ptrdiff_type_node)); + return (adjusted_warn_limit (false) <= max + || adjusted_warn_limit (true) <= max); } // Possible problematic uses of alloca. @@ -127,6 +131,30 @@ struct alloca_type_and_limit { alloca_type_and_limit (enum alloca_type type) : type(type) { } }; +/* Return the value of the argument N to -Walloca-larger-than= or + -Wvla-larger-than= adjusted for the target data model so that + when N == HOST_WIDE_INT_MAX, the adjusted value is set to + PTRDIFF_MAX on the target. This is done to prevent warnings + for unknown/unbounded allocations in the "permissive mode" + while still diagnosing excessive and necessarily invalid + allocations. */ + +static unsigned HOST_WIDE_INT +adjusted_warn_limit (bool idx) +{ + static HOST_WIDE_INT limits[2]; + if (limits[idx]) + return limits[idx]; + + limits[idx] = idx ? warn_vla_limit : warn_alloca_limit; + if (limits[idx] != HOST_WIDE_INT_MAX) + return limits[idx]; + + limits[idx] = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node)); + return limits[idx]; +} + + // NOTE: When we get better range info, this entire function becomes // irrelevant, as it should be possible to get range info for an SSA // name at any point in the program. @@ -309,11 +337,7 @@ alloca_call_type (gimple *stmt, bool is_vla, tree // Adjust warn_alloca_max_size for VLAs, by taking the underlying // type into account. - unsigned HOST_WIDE_INT max_size; - if (is_vla) - max_size = warn_vla_limit; - else - max_size = warn_alloca_limit; + unsigned HOST_WIDE_INT max_size = adjusted_warn_limit (is_vla); // Check for the obviously bounded case. if (TREE_CODE (len) == INTEGER_CST) @@ -510,6 +534,8 @@ pass_walloca::execute (function *fun) struct alloca_type_and_limit t = alloca_call_type (stmt, is_vla, &invalid_casted_type); + unsigned HOST_WIDE_INT adjusted_alloca_limit + = adjusted_warn_limit (false); // Even if we think the alloca call is OK, make sure it's not in a // loop, except for a VLA, since VLAs are guaranteed to be cleaned // up when they go out of scope, including in a loop. @@ -519,8 +545,7 @@ pass_walloca::execute (function *fun) is less than the maximum valid object size. */ const offset_int maxobjsize = wi::to_offset (max_object_size ()); - if ((unsigned HOST_WIDE_INT) warn_alloca_limit - < maxobjsize.to_uhwi ()) + if (adjusted_alloca_limit < maxobjsize.to_uhwi ()) t = alloca_type_and_limit (ALLOCA_IN_LOOP); } @@ -541,7 +566,7 @@ pass_walloca::execute (function *fun) print_decu (t.limit, buff); inform (loc, G_("limit is %wu bytes, but argument " "may be as large as %s"), - is_vla ? warn_vla_limit : warn_alloca_limit, buff); + is_vla ? warn_vla_limit : adjusted_alloca_limit, buff); } break; case ALLOCA_BOUND_DEFINITELY_LARGE: @@ -553,7 +578,7 @@ pass_walloca::execute (function *fun) { print_decu (t.limit, buff); inform (loc, G_("limit is %wu bytes, but argument is %s"), - is_vla ? warn_vla_limit : warn_alloca_limit, buff); + is_vla ? warn_vla_limit : adjusted_alloca_limit, buff); } break; case ALLOCA_BOUND_UNKNOWN: Index: gcc/stor-layout.c =================================================================== --- gcc/stor-layout.c (revision 262951) +++ gcc/stor-layout.c (working copy) @@ -761,14 +761,19 @@ layout_decl (tree decl, unsigned int known_align) { tree size = DECL_SIZE_UNIT (decl); - if (size != 0 && TREE_CODE (size) == INTEGER_CST - && compare_tree_int (size, warn_larger_than_size) > 0) + if (size != 0 && TREE_CODE (size) == INTEGER_CST) { - unsigned HOST_WIDE_INT uhwisize = tree_to_uhwi (size); + /* -Wlarger-than= argument of HOST_WIDE_INT_MAX is treated + as if PTRDIFF_MAX had been specified, with the value + being that on the target rather than the host. */ + unsigned HOST_WIDE_INT max_size = warn_larger_than_size; + if (max_size == HOST_WIDE_INT_MAX) + max_size = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node)); - warning (OPT_Wlarger_than_, "size of %q+D %wu bytes exceeds " - "maximum object size %wu", - decl, uhwisize, warn_larger_than_size); + if (compare_tree_int (size, max_size) > 0) + warning (OPT_Wlarger_than_, "size of %q+D %E bytes exceeds " + "maximum object size %wu", + decl, size, max_size); } } Index: gcc/testsuite/g++.dg/Walloca1.C =================================================================== --- gcc/testsuite/g++.dg/Walloca1.C (revision 262951) +++ gcc/testsuite/g++.dg/Walloca1.C (working copy) @@ -1,7 +1,9 @@ -/* PR middle-end/79809 */ +/* PR middle-end/79809 - ICE in alloca_call_type, at gimple-ssa-warn-alloca.c */ /* { dg-do compile } */ /* { dg-options "-Walloca-larger-than=4207115063 -Wvla-larger-than=1233877270 -O2" } */ /* { dg-require-effective-target alloca } */ int a; -char *b = static_cast(__builtin_alloca (a)); // { dg-warning "argument to .alloca. may be too large|unbounded use of" } +char *b = static_cast(__builtin_alloca (a)); + +// { dg-prune-output "argument to .alloca." }