From 2083410b5d0455d7803eca076ac8295591045efd Mon Sep 17 00:00:00 2001 From: ebotcazou Date: Mon, 24 May 2010 22:03:09 +0000 Subject: [PATCH] PR middle-end/44100 * typeck.c (cp_build_unary_op): Fold offsetof-like computations. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159800 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/typeck.c | 14 ++++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/parse/array-size2.C | 7 ++++--- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 74cb21357359..cd86b889ca43 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2010-05-24 Eric Botcazou + + PR middle-end/44100 + * typeck.c (cp_build_unary_op): Fold offsetof-like computations. + 2010-05-24 Joseph Myers * error.c (cp_diagnostic_starter): Update call to diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 54ccbfe49f1a..77cf8fdd0c35 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5024,6 +5024,20 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, return arg; } + /* ??? Cope with user tricks that amount to offsetof. */ + if (TREE_CODE (argtype) != FUNCTION_TYPE + && TREE_CODE (argtype) != METHOD_TYPE + && argtype != unknown_type_node + && (val = get_base_address (arg)) + && TREE_CODE (val) == INDIRECT_REF + && TREE_CONSTANT (TREE_OPERAND (val, 0))) + { + tree type = build_pointer_type (argtype); + tree op0 = fold_convert (type, TREE_OPERAND (val, 0)); + tree op1 = fold_convert (sizetype, fold_offsetof (arg, val)); + return fold_build2 (POINTER_PLUS_EXPR, type, op0, op1); + } + /* Uninstantiated types are all functions. Taking the address of a function is a no-op, so just return the argument. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8fd1fd585e08..ddb08adfce65 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-05-24 Eric Botcazou + + * g++.dg/parse/array-size2.C: Remove dg-error directives. + 2010-05-24 Eric Botcazou PR ada/38394 diff --git a/gcc/testsuite/g++.dg/parse/array-size2.C b/gcc/testsuite/g++.dg/parse/array-size2.C index 22a57b2dc0bc..355ed6133b45 100644 --- a/gcc/testsuite/g++.dg/parse/array-size2.C +++ b/gcc/testsuite/g++.dg/parse/array-size2.C @@ -1,6 +1,7 @@ // PR c/25682 // { dg-do compile } -// Test whether we don't ICE on invalid array sizes. +// Test whether we don't ICE on questionable constructs where offsetof +// should have been used instead. struct S { @@ -13,7 +14,7 @@ extern void bar (char *, char *); void foo (void) { - char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "not an integral constant-expression" } - char h[(__SIZE_TYPE__) &((struct S *) 8)->b]; // { dg-error "not an integral constant-expression" } + char g[(char *) &((struct S *) 0)->b - (char *) 0]; + char h[(__SIZE_TYPE__) &((struct S *) 8)->b]; bar (g, h); } -- 2.47.2