aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2010-05-24 22:03:09 +0000
committerEric Botcazou <ebotcazou@adacore.com>2010-05-24 22:03:09 +0000
commit97937317465c52b3b67bb9dc3d9cfd992258b3c2 (patch)
treeb9428ab159cf1e1bea7ddc0e1161b3ea0ac1fc41
parentc59936f76d7fbbc807bb337f7fdc4f6375daed3a (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/ChangeLog5
-rw-r--r--gcc/cp/typeck.c14
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/parse/array-size2.C7
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);
}