From patchwork Wed May 11 19:22:21 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Froyd X-Patchwork-Id: 95189 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D7077B6F5A for ; Thu, 12 May 2011 08:09:39 +1000 (EST) Received: (qmail 26638 invoked by alias); 11 May 2011 19:22:57 -0000 Received: (qmail 26601 invoked by uid 22791); 11 May 2011 19:22:56 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 11 May 2011 19:22:34 +0000 Received: (qmail 27257 invoked from network); 11 May 2011 19:22:33 -0000 Received: from unknown (HELO ?192.168.1.78?) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 11 May 2011 19:22:33 -0000 Message-ID: <4DCAE1ED.6040203@codesourcery.com> Date: Wed, 11 May 2011 15:22:21 -0400 From: Nathan Froyd User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:5.0a2) Gecko/20110427 Thunderbird/3.3a4pre MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: [PATCH] fix PR middle-end/48965, CASE_CHAIN fallout X-IsSubscribed: yes 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 The comment for pointer_map_traverse says: /* Pass each pointer in PMAP to the function in FN, together with the pointer to the value and the fixed parameter DATA. If FN returns false, the iteration stops. */ However, the code in tree-cfg:edge_to_cases_cleanup does: static bool edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value, void *data ATTRIBUTE_UNUSED) { tree t, next; for (t = (tree) *value; t; t = next) { next = CASE_CHAIN (t); CASE_CHAIN (t) = NULL; } *value = NULL; return false; } ... pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL); which means that we're only cleaning up one of the case chains stored in EDGE_TO_CASES. Since it's a pointer_map, we can potentially get /* Start recording information mapping edges to case labels. */ @@ -2830,6 +2830,14 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) *walk_subtrees = 0; break; + case CASE_LABEL_EXPR: + if (CASE_CHAIN (t)) + { + error ("invalid CASE_CHAIN"); + return t; + } + break; + default: break; } different chains selected each time. Under -fcompare-debug, this leads to problems later on when we walk the function body and collect all the DECLs referenced therein; we might walk non-NULL CASE_CHAINs and reach more DECLs, depending on the memory layout. This wouldn't have shown up previously, since TREE_CHAIN was used, and we wouldn't walk TREE_CHAIN of expressions to find DECLs. The fix is simple: return true from the above function! I've added logic to verify_expr to catch this sort of thing. Tested on x86_64-unknown-linux-gnu. OK to commit? -Nathan gcc/ PR middle-end/48965 * tree-cfg.c (edge_to_cases_cleanup): Return true. (verify_expr) [CASE_LABEL_EXPR]: Add checking. diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index e1f8707..e2e84a2 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -843,7 +843,7 @@ edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value, } *value = NULL; - return false; + return true; }