This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Fix ICE on offsetof with reference type field (PR c++/35741)


Hi!

Since PR28573 gcc ICEs on offsetof of a member with reference type.
The problem is that convert_from_reference called by
cp_parser_postfix_dot_deref_expression etc. adds INDIRECT_REF around
the COMPONENT_REF, and since PR28573 fold_offsetof assumes and asserts
any INDIRECT_REF seen in it is the inner indirect ref of *(type *)0.
I believe such offsetof is invalid, because the struct isn't POD,
but g++ 3.2 through 4.1.x gave just a warning on this rather than
hard error.  g++ 3.2/3.3/3.4 returned the actual offsetof of the REFERENCE_TYPE
field in the struct, 4.0/4.1 always returned 0, 4.2+ ICEs on it.
The patch below restores the 3.2/3.3/3.4 behavior which makes more sense.
Alternatively just replacing the expr = TREE_OPERAND (expr, 0);
with return size_zero_node; would result in 4.0/4.1 behavior, or we can
issue hard error on it.

Ok for trunk/4.3?

2008-04-02  Jakub Jelinek  <jakub@redhat.com>

	PR c++/35741
	* semantics.c (finish_offsetof): Undo effect of convert_from_reference
	before calling fold_offsetof.

	* g++.dg/other/offsetof5.C: New test.

--- gcc/cp/semantics.c.jj	2008-03-25 23:31:25.000000000 +0100
+++ gcc/cp/semantics.c	2008-04-02 20:45:17.000000000 +0200
@@ -3039,6 +3039,8 @@ finish_offsetof (tree expr)
       error ("cannot apply %<offsetof%> to member function %qD", expr);
       return error_mark_node;
     }
+  if (TREE_CODE (expr) == INDIRECT_REF && REFERENCE_REF_P (expr))
+    expr = TREE_OPERAND (expr, 0);
   return fold_offsetof (expr, NULL_TREE);
 }
 
--- gcc/testsuite/g++.dg/other/offsetof5.C.jj	2008-04-02 20:54:13.000000000 +0200
+++ gcc/testsuite/g++.dg/other/offsetof5.C	2008-04-02 20:54:39.000000000 +0200
@@ -0,0 +1,22 @@
+// PR c++/35741
+// { dg-do compile }
+
+#include <stddef.h>
+
+struct A
+{
+  char c;
+  int &i;
+};
+
+int j = offsetof (A, i);		// { dg-warning "invalid access|offsetof" }
+
+template <typename T>
+struct S
+{
+  T h;
+  T &i;
+  static const int j = offsetof (S, i);	// { dg-warning "invalid access|offsetof" }
+};
+
+int k = S<int>::j;			// { dg-warning "instantiated from here" }

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]