]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR middle-end/44100
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 May 2010 22:03:09 +0000 (22:03 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 May 2010 22:03:09 +0000 (22:03 +0000)
* 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
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/array-size2.C

index 74cb21357359afcfb480192d62a2e3a7011068f0..cd86b889ca4391a079d7b99a3258b2b424316888 100644 (file)
@@ -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
index 54ccbfe49f1a96f6a0d97651cc8a36dedf58ad3b..77cf8fdd0c35ec53f6967b49cdfe9ba96b191e93 100644 (file)
@@ -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.  */
index 8fd1fd585e08208212ff9c32c4cafee5d78938d8..ddb08adfce659c64e6ca9fa6cac4a495895bc521 100644 (file)
@@ -1,3 +1,7 @@
+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
index 22a57b2dc0bcebd325f9e85fdc7d9ccebf3d3b9e..355ed6133b4586103456c94cc826ca4cb485b2fe 100644 (file)
@@ -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);
 }