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 build_offset_ref_call_from_tree in templates (PR c++/33616)


Hi!

We issue incorrect diagnostics on the following testcase.
The problem seems to be that when parsing template
build_offset_ref_call_from_tree calls build_unary_op (ADDR_EXPR, object, 0)
on tree which contains some value dependent templatish tree codes
(ARROW_EXPR in this case), which e.g. lvalue_p doesn't handle and thus
will think it is not an lvalue.  Fixed just by swapping this call with
the following build_non_dependent_expr call, so build_unary_op (ADDR_EXPR,
object, 0) already sees non-dependent tree and thus accepts it might be
an lvalue.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2007-10-30  Jakub Jelinek  <jakub@redhat.com>

	PR c++/33616
	* decl2.c (build_offset_ref_call_from_tree): Call
	build_non_dependent_expr on object prior to building ADDR_EXPR from it
	if FN is DOTSTAR_EXPR.

	* g++.dg/template/ptrmem18.C: New test.

--- gcc/cp/decl2.c.jj	2007-10-28 19:34:13.000000000 +0100
+++ gcc/cp/decl2.c	2007-10-30 12:52:35.000000000 +0100
@@ -3499,9 +3499,9 @@ build_offset_ref_call_from_tree (tree fn
 	 parameter.  That must be done before the FN is transformed
 	 because we depend on the form of FN.  */
       args = build_non_dependent_args (args);
+      object = build_non_dependent_expr (object);
       if (TREE_CODE (fn) == DOTSTAR_EXPR)
 	object = build_unary_op (ADDR_EXPR, object, 0);
-      object = build_non_dependent_expr (object);
       args = tree_cons (NULL_TREE, object, args);
       /* Now that the arguments are done, transform FN.  */
       fn = build_non_dependent_expr (fn);
--- gcc/testsuite/g++.dg/template/ptrmem18.C.jj	2007-10-30 13:14:19.000000000 +0100
+++ gcc/testsuite/g++.dg/template/ptrmem18.C	2007-10-30 13:13:44.000000000 +0100
@@ -0,0 +1,49 @@
+// PR c++/33616
+// { dg-do run }
+// { dg-options "-O2" }
+
+extern "C" void abort ();
+
+struct S {
+  int c;
+  S () : c (0) {}
+  virtual void f1 () { c += 1; }
+  virtual void f2 () { c += 16; }
+};
+
+struct T {
+  S s;
+};
+
+typedef void (S::*Q) ();
+
+template <Q P>
+void test1 (T *t)
+{
+  (t->s.*P)();
+}
+
+template <Q P>
+void test2 (T *t)
+{
+  S &s = t->s;
+  (s.*P)();
+}
+
+int
+main ()
+{
+  T t;
+  test1 <&S::f1> (&t);
+  if (t.s.c != 1)
+    abort ();
+  test1 <&S::f2> (&t);
+  if (t.s.c != 17)
+    abort ();
+  test2 <&S::f1> (&t);
+  if (t.s.c != 18)
+    abort ();
+  test2 <&S::f2> (&t);
+  if (t.s.c != 34)
+    abort ();
+}

	Jakub


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