diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2010-05-24 22:03:09 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@adacore.com> | 2010-05-24 22:03:09 +0000 |
commit | 97937317465c52b3b67bb9dc3d9cfd992258b3c2 (patch) | |
tree | b9428ab159cf1e1bea7ddc0e1161b3ea0ac1fc41 | |
parent | c59936f76d7fbbc807bb337f7fdc4f6375daed3a (diff) |
PR middle-end/44100
* typeck.c (cp_build_unary_op): Fold offsetof-like computations.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@159800 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | 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 74cb2135735..cd86b889ca4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2010-05-24 Eric Botcazou <ebotcazou@adacore.com> + + PR middle-end/44100 + * typeck.c (cp_build_unary_op): Fold offsetof-like computations. + 2010-05-24 Joseph Myers <joseph@codesourcery.com> * error.c (cp_diagnostic_starter): Update call to diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 54ccbfe49f1..77cf8fdd0c3 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 8fd1fd585e0..ddb08adfce6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2010-05-24 Eric Botcazou <ebotcazou@adacore.com> + * g++.dg/parse/array-size2.C: Remove dg-error directives. + +2010-05-24 Eric Botcazou <ebotcazou@adacore.com> + PR ada/38394 * gnat.dg/array13.ad[sb]: New test. diff --git a/gcc/testsuite/g++.dg/parse/array-size2.C b/gcc/testsuite/g++.dg/parse/array-size2.C index 22a57b2dc0b..355ed6133b4 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); } |