From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6319 invoked by alias); 22 Nov 2004 20:40:43 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 6284 invoked from network); 22 Nov 2004 20:40:38 -0000 Received: from unknown (HELO mail-out4.apple.com) (17.254.13.23) by sourceware.org with SMTP; 22 Nov 2004 20:40:38 -0000 Received: from mailgate1.apple.com (a17-128-100-225.apple.com [17.128.100.225]) by mail-out4.apple.com (8.12.11/8.12.11) with ESMTP id iAMKlQET009055 for ; Mon, 22 Nov 2004 12:47:26 -0800 (PST) Received: from relay3.apple.com (relay3.apple.com) by mailgate1.apple.com (Content Technologies SMTPRS 4.3.14) with ESMTP id ; Mon, 22 Nov 2004 12:41:21 -0800 Received: from [17.201.24.57] (polskifiat.apple.com [17.201.24.57]) by relay3.apple.com (8.12.11/8.12.11) with ESMTP id iAMKeYJ4003974; Mon, 22 Nov 2004 12:40:35 -0800 (PST) In-Reply-To: <90DC5074-3A96-11D9-9070-000D9330C50E@apple.com> References: <4D2CF60C-3919-11D9-8BD2-000A95BCF344@apple.com> <20041117212847.A26376@synopsys.com> <6F5FC748-7BBD-44B9-8DDC-246949F16102@apple.com> <20041118102741.A8347@synopsys.com> <77E8D36A-C0C2-4B03-964C-BEE0FE7BBBC3@apple.com> <98C86CD4-39E2-11D9-B2D5-000A95BCF344@apple.com> <20041119170011.A30410@synopsys.com> <9E6AD708-3A93-11D9-9070-000D9330C50E@apple.com> <20041119174042.A1311@synopsys.com> <90DC5074-3A96-11D9-9070-000D9330C50E@apple.com> Mime-Version: 1.0 (Apple Message framework v619) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: <9CD04F70-3CC6-11D9-B847-000D9330C50E@apple.com> Content-Transfer-Encoding: 7bit Cc: Steve Naroff , Michael Matz , Matt Austern , Joe Buck , Andrew Pinski , Mike Stump From: Ziemowit Laski Subject: generalized lvalues -- patch outline Date: Mon, 22 Nov 2004 20:54:00 -0000 To: Ziemowit Laski , gcc mailing list X-SW-Source: 2004-11/txt/msg00755.txt.bz2 On 19 Nov 2004, at 17.50, Ziemowit Laski wrote: > To put it another way, I'm only concerned with cases where the > compiler currently complains > about assigning to a non-lvalue, and the non-lvalue in question is a > cast of an lvalue. Indeed, I now appear to have a mainline mod for C and C++ which allows assignment to lvalue casts for pointer types. What follows is a high-level synopsis of what I did; if there is interest, I can whip up a full-fledged patch, complete with docs. Please let me know. Thanks, --Zem ------ The lvalue cast assignment/increment/decrement can be enabled with the -flvalue-cast-assign flag (which is off by default). The active ingredient of the C patch is: Index: gcc/c-typeck.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v retrieving revision 1.400 diff -u -3 -p -r1.400 c-typeck.c --- gcc/c-typeck.c 20 Nov 2004 20:31:43 -0000 1.400 +++ gcc/c-typeck.c 22 Nov 2004 20:32:00 -0000 @@ -2724,6 +2724,16 @@ lvalue_or_else (tree ref, enum lvalue_us { int win = lvalue_p (ref); + /* If -flvalue-cast-assignment is specified, we shall allow assignments + (including increment/decrement) to casts of lvalues, as long as + both the lvalue and the cast are pointers. */ + if (!win && flag_lvalue_cast_assign + && TREE_CODE (ref) == NOP_EXPR + && (use == lv_assign || use == lv_increment || use == lv_decrement) + && TREE_CODE (TREE_TYPE (ref)) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == POINTER_TYPE) + win = lvalue_p (TREE_OPERAND (ref, 0)); + if (!win) { switch (use) and will allow code as follows: Index: gcc/testsuite/gcc.dg/lvalue-cast-1.c =================================================================== RCS file: gcc/testsuite/gcc.dg/lvalue-cast-1.c diff -N gcc/testsuite/gcc.dg/lvalue-cast-1.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/testsuite/gcc.dg/lvalue-cast-1.c 22 Nov 2004 20:32:50 -0000 @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-flvalue-cast-assign" } */ + +int foo(void) { + + char *p; + long l; + short s; + + (long *)p = &l; /* ok */ + ((long *)p)++; /* ok */ + (short)l = 2; /* { dg-error "non-lvalue" } */ + (long)s = 3; /* { dg-error "non-lvalue" } */ + + return 0; +} Note that we're still erroring out on the non-pointer types, though that too can be changed. FWIW, Microsoft's C compiler also allows the '(short)l = 2' (though not the '(long)s = 3'). The C++ side of things is very similar: Index: gcc/cp/tree.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v retrieving revision 1.419 diff -u -3 -p -r1.419 tree.c --- gcc/cp/tree.c 12 Nov 2004 21:47:09 -0000 1.419 +++ gcc/cp/tree.c 22 Nov 2004 20:34:50 -0000 @@ -223,6 +223,17 @@ lvalue_or_else (tree ref, const char* st { if (!lvalue_p (ref)) { + /* If -flvalue-cast-assignment is specified, we shall allow assignments + (including increment/decrement) to casts of lvalues, as long as + both the lvalue and the cast are pointers. */ + if (flag_lvalue_cast_assign + && TREE_CODE (ref) == NOP_EXPR + && string && string[0] == 'a' + && TREE_CODE (TREE_TYPE (ref)) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == POINTER_TYPE + && lvalue_p (TREE_OPERAND (ref, 0))) + return 1; + error ("non-lvalue in %s", string); return 0; } although we clearly could use an 'enum lvalue_use' here as well. At any rate, this patch causes the following to compile and run successfully: Index: gcc/testsuite/g++.dg/ext/lvalue-cast-1.cpp =================================================================== RCS file: gcc/testsuite/g++.dg/ext/lvalue-cast-1.cpp diff -N gcc/testsuite/g++.dg/ext/lvalue-cast-1.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/testsuite/g++.dg/ext/lvalue-cast-1.cpp 22 Nov 2004 20:36:43 -0000 @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-flvalue-cast-assign" } */ + +#include +#define CHECK_IF(expr) if (!(expr)) abort () + +static int global; + +void f(int &) { global = 35; } +void f(const int &) { global = 78; } + +long long_arr[2]; + +int main(void) { + + char *p; + + (long *)p = long_arr; + ((long *)p)++; + *(long *)p = -1; + *p = -2; + CHECK_IF(p[-1] == 0 && p[0] == -2 && p[1] == -1); + + long x = 0; + f((int)x); + CHECK_IF(global == 78); + + return 0; +} The rest of the patch (not shown) deals with defining/handling of the -flvalue-cast-assign flag.