From patchwork Fri Jan 29 16:21:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bin Cheng X-Patchwork-Id: 575688 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 87233140B9C for ; Sat, 30 Jan 2016 03:21:38 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=c521LN7y; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; q=dns; s=default; b=sY+zZ0VAXH9kT66C0veKpCw/NzmdMuBF4smFjX14YCn06uWu5h 0n7IwmlI/8EcYi2pmExiEIsdbZQJAEMT0CQbEBj2ARy4TXoyGYUQituEJlrsCb4a C4cl2xJJccUaFNF8BAMaH9M7YqlJjsu82enmagwqWva+4HQxkcoNzUcvE= 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 :to:cc:subject:date:message-id:mime-version:content-type; s= default; bh=4qP9sgTEQNa0Twh47S7m/TEhwnA=; b=c521LN7ysDzFuMp01Dc5 zSgGO8RyRbfv+CNDR4X6hRBCg4vGa/PDpZPIwBwok98992J7NKC0fWsQ5ynPRjcD T1BVrvaCAAlW+M3JaSEX6He9yxrslP6w+ExIYSCkkNR1tcdsQVIcNfLhgghZnrDg bnIa95rpq4F0q7hltquC1E4= Received: (qmail 87377 invoked by alias); 29 Jan 2016 16:21:31 -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 87329 invoked by uid 89); 29 Jan 2016 16:21:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=109, 7, 1097, stripped, 8337 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 29 Jan 2016 16:21:27 +0000 Received: from emea01-am1-obe.outbound.protection.outlook.com (mail-am1lrp0020.outbound.protection.outlook.com [213.199.154.20]) (Using TLS) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-32-5Fk05vG6S6WrStFIl43hpQ-1; Fri, 29 Jan 2016 16:21:20 +0000 Received: from HE1PR08MB0507.eurprd08.prod.outlook.com (10.161.120.154) by HE1PR08MB0506.eurprd08.prod.outlook.com (10.161.120.153) with Microsoft SMTP Server (TLS) id 15.1.390.13; Fri, 29 Jan 2016 16:21:16 +0000 Received: from HE1PR08MB0507.eurprd08.prod.outlook.com ([10.161.120.154]) by HE1PR08MB0507.eurprd08.prod.outlook.com ([10.161.120.154]) with mapi id 15.01.0390.016; Fri, 29 Jan 2016 16:21:16 +0000 From: Bin Cheng To: "gcc-patches@gcc.gnu.org" CC: nd Subject: [PATCH PR67921]Convert pointer expr to proper type before negating it Date: Fri, 29 Jan 2016 16:21:16 +0000 Message-ID: x-microsoft-exchange-diagnostics: 1; HE1PR08MB0506; 5:NhBZM5o7xw3FHTTVYP4XO4gZq9BrT8mvPPQvslDP59fgCLX3p5IrdA/LwaBWMBdDPt8gdDn4rLDrgo/KdbimlrtD2e+Y0GUoi+OLwBVfhklh4iN6v1CO4oDogRXkWQvFvo8ja72Sc/SuO40eN9I/9g==; 24:xZOKn+JCj0lEkiHt9AyOL7KG/Smv97/WZNqguPNY+uqvD/lYZSJ3P+Zhw4GsXWzzjWX2z3g5KKUOkWUBW0wYjUIirCqoBIxSIIa+zEv9ZcU=; 20:VKgR1i5yiaAJwGgycaZNaEh4DeWPzDaALr3LMlVjYLnPpUrzNspVRNBh8dYxlOc99RzcxDz+v79BmXZYrzZ32QO2oRjsQNMT8mYbOndZ0JJEh7XUuRyCVqZI+jV31MTgBGMAhu5xKXCFTfP/pWBMkGJYP2/ESL2DCRJ1HAQFqK4= x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HE1PR08MB0506; x-ms-office365-filtering-correlation-id: 76eaeac7-2faf-4da9-e5a2-08d328c836ac nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(102415267)(102615245)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046); SRVR:HE1PR08MB0506; BCL:0; PCL:0; RULEID:; SRVR:HE1PR08MB0506; x-forefront-prvs: 083691450C x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(6009001)(377424004)(11100500001)(66066001)(2501003)(5008740100001)(33656002)(3470700001)(3846002)(4326007)(6116002)(1220700001)(102836003)(1096002)(5003600100002)(3660700001)(92566002)(40100003)(586003)(3280700002)(74316001)(122556002)(2906002)(76576001)(110136002)(19580395003)(19580405001)(450100001)(99936001)(2351001)(5001960100002)(5002640100001)(87936001)(10400500002)(77096005)(54356999)(2900100001)(189998001)(86362001)(229853001)(5004730100002)(50986999)(106116001); DIR:OUT; SFP:1101; SCL:1; SRVR:HE1PR08MB0506; H:HE1PR08MB0507.eurprd08.prod.outlook.com; FPR:; SPF:None; MLV:sfv; LANG:en; spamdiagnosticoutput: 1:23 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-originalarrivaltime: 29 Jan 2016 16:21:16.1024 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR08MB0506 X-MC-Unique: 5Fk05vG6S6WrStFIl43hpQ-1 X-IsSubscribed: yes Hi, Function fold_binary_loc calls split_tree to split a tree into constant, literal and variable parts. Function split_tree deals with minus_expr by negating different parts into NEXGATE_EXPR. Since tree exprs fed to split_tree are with NOP conversions stripped, this could result in illegal expr for pointer expressions. Given below example as described by PR67921: op0: (4 - (sizetype) &c) code: MINUS_EXPR op1: (sizetype)b fold_binary_loc calls split_tree for both op0 and op1 and gets below from the function calls (it also flips the code): op0: 4, -(sizetype)&c code: PLUS_EXPR op1: -b Here we generate NEGATIVE_EXPR of pointer variable (b) which is illegal. If "-b" can not be canceled by following call to associate_trees, it will be passed along in IR resulting in ICE somewhere. This patch fixes it by converting pointer expression to proper type before negating it. Note the proper type is the outer type stripped in fold_binary_loc before calling split_tree. I also included a test which is heavily reduced from the original ffmpeg code in the original PR. Considering it's stage4, I restricted the patch to the smallest change. As a matter of fact, we may need to do the same thing for signed int types because -TYPE_MIN is undefined. Unfortunately, I failed to create a test in this case. Bootstrap and test on x64_64, is it OK? 2016-01-27 Bin Cheng PR tree-optimization/67921 * fold-const.c (split_tree): New parameters. Convert pointer type variable part to proper type before negating. (fold_binary_loc): Pass new arguments to split_tree. gcc/testsuite/ChangeLog 2016-01-27 Bin Cheng PR tree-optimization/67921 * c-c++-common/ubsan/pr67921.c: New test. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index bece8d7..e34bc81 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -109,7 +109,8 @@ enum comparison_code { static bool negate_expr_p (tree); static tree negate_expr (tree); -static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int); +static tree split_tree (location_t, tree, tree, enum tree_code, + tree *, tree *, tree *, int); static tree associate_trees (location_t, tree, tree, enum tree_code, tree); static enum comparison_code comparison_to_compcode (enum tree_code); static enum tree_code compcode_to_comparison (enum comparison_code); @@ -767,7 +768,10 @@ negate_expr (tree t) literal for which we use *MINUS_LITP instead. If NEGATE_P is true, we are negating all of IN, again except a literal - for which we use *MINUS_LITP instead. + for which we use *MINUS_LITP instead. If a variable part is of pointer + type, it is negated after converting to TYPE. This prevents us from + generating illegal MINUS pointer expression. LOC is the location of + the converted variable part. If IN is itself a literal or constant, return it as appropriate. @@ -775,8 +779,8 @@ negate_expr (tree t) same type as IN, but they will have the same signedness and mode. */ static tree -split_tree (tree in, enum tree_code code, tree *conp, tree *litp, - tree *minus_litp, int negate_p) +split_tree (location_t loc, tree in, tree type, enum tree_code code, + tree *conp, tree *litp, tree *minus_litp, int negate_p) { tree var = 0; @@ -833,7 +837,12 @@ split_tree (tree in, enum tree_code code, tree *conp, tree *litp, if (neg_conp_p) *conp = negate_expr (*conp); if (neg_var_p) - var = negate_expr (var); + { + /* Convert to TYPE before negating a pointer type expr. */ + if (var && POINTER_TYPE_P (TREE_TYPE (var))) + var = fold_convert_loc (loc, type, var); + var = negate_expr (var); + } } else if (TREE_CODE (in) == BIT_NOT_EXPR && code == PLUS_EXPR) @@ -854,6 +863,9 @@ split_tree (tree in, enum tree_code code, tree *conp, tree *litp, else if (*minus_litp) *litp = *minus_litp, *minus_litp = 0; *conp = negate_expr (*conp); + /* Convert to TYPE before negating a pointer type expr. */ + if (var && POINTER_TYPE_P (TREE_TYPE (var))) + var = fold_convert_loc (loc, type, var); var = negate_expr (var); } @@ -9621,9 +9633,10 @@ fold_binary_loc (location_t loc, then the result with variables. This increases the chances of literals being recombined later and of generating relocatable expressions for the sum of a constant and literal. */ - var0 = split_tree (arg0, code, &con0, &lit0, &minus_lit0, 0); - var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1, - code == MINUS_EXPR); + var0 = split_tree (loc, arg0, type, code, + &con0, &lit0, &minus_lit0, 0); + var1 = split_tree (loc, arg1, type, code, + &con1, &lit1, &minus_lit1, code == MINUS_EXPR); /* Recombine MINUS_EXPR operands by using PLUS_EXPR. */ if (code == MINUS_EXPR) diff --git a/gcc/testsuite/c-c++-common/ubsan/pr67921.c b/gcc/testsuite/c-c++-common/ubsan/pr67921.c new file mode 100644 index 0000000..728ff93 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/pr67921.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=undefined" } */ + +struct s +{ + int n; + int arr[][6]; +}; +void bar (int); +void foo (struct s *ptr) +{ + int i; + for (; i < 2; i++) + for (; ptr->n;) + { + int *a = ptr->arr[i]; + int b[66]; + int j = 0; + + for (; j < 56; j++) + bar (a[j] - b[j]); + } +}