From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3513 invoked by alias); 14 Apr 2011 15:01:43 -0000 Received: (qmail 3493 invoked by uid 22791); 14 Apr 2011 15:01:42 -0000 X-SWARE-Spam-Status: No, hits=-3.3 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 14 Apr 2011 15:01:35 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 1ECBD8738D; Thu, 14 Apr 2011 17:01:33 +0200 (CEST) Date: Thu, 14 Apr 2011 15:01:00 -0000 From: Richard Guenther To: gcc-patches@gcc.gnu.org Cc: "Joseph S. Myers" Subject: [PATCH][C] Do not expand array-refs via pointer arithmetic Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 X-SW-Source: 2011-04/txt/msg01085.txt.bz2 This patch adjusts the C frontend to retain array-refs in address-taking operations instead of expanding them via pointer arithmetic. As seen in PR48571 we can't re-construct array-refs in the middle-end, thus we should keep information as specified by the source level. For int a[10]; int *foo (int i) { return &a[i]; } int *bar (int i) { return &i[a]; } this will now emit return &a[i]; instead of return (int *) &a + (long unsigned int) ((long unsigned int) i * 4); which is also shorter. Bootstrapped and tested on x86_64-unknown-linux-gnu. Ok for trunk? Thanks, Richard. 2011-04-14 Richard Guenther * c-typeck.c (build_unary_op): Do not expand array-refs via pointer arithmetic. Only adjust qualifiers for function types. Index: gcc/c-typeck.c =================================================================== --- gcc/c-typeck.c (revision 172319) +++ gcc/c-typeck.c (working copy) @@ -3737,12 +3737,6 @@ build_unary_op (location_t location, tree op0 = TREE_OPERAND (arg, 0); if (!c_mark_addressable (op0)) return error_mark_node; - return build_binary_op (location, PLUS_EXPR, - (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE - ? array_to_pointer_conversion (location, - op0) - : op0), - TREE_OPERAND (arg, 1), 1); } /* Anything not already handled and not a true memory reference @@ -3769,10 +3763,11 @@ build_unary_op (location_t location, argtype = TREE_TYPE (arg); /* If the lvalue is const or volatile, merge that into the type - to which the address will point. This should only be needed + to which the address will point. This is only needed for function types. */ if ((DECL_P (arg) || REFERENCE_CLASS_P (arg)) - && (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))) + && (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)) + && TREE_CODE (argtype) == FUNCTION_TYPE) { int orig_quals = TYPE_QUALS (strip_array_types (argtype)); int quals = orig_quals; @@ -3782,9 +3777,6 @@ build_unary_op (location_t location, if (TREE_THIS_VOLATILE (arg)) quals |= TYPE_QUAL_VOLATILE; - gcc_assert (quals == orig_quals - || TREE_CODE (argtype) == FUNCTION_TYPE); - argtype = c_build_qualified_type (argtype, quals); }