Hi,

On 12/01/2012 07:13 AM, Jason Merrill wrote:
On 11/30/2012 04:05 PM, Paolo Carlini wrote:
@@ -219,10 +219,15 @@ cp_convert_to_pointer (tree type, tree expr, tsubs
-    expr = build_int_cst (type, 0);
+    expr = (TREE_SIDE_EFFECTS (expr)
+        ? build_nop (type, expr)
+        : build_int_cst (type, 0));

This seems to rely on a nop being sufficient to convert from any null pointer constant to the appropriate pointer type, which I don't think is safe if the integer is smaller than a pointer.

I'm also not sure if we want to rely on nullptr_t expressions actually having the value 0.
Thanks a lot. What about the below? I'm consistently building a COMPOUND_EXPR for the simpler plain pointers too; the hunk for pointers to member functions can be *very* simple: in fact I had already tried this solution but something else was wrong yesterday and seemed not to work, huumpf.

Tested x86_64-linux.

Thanks again,
Paolo.

////////////////////
Index: cp/cvt.c
===================================================================
--- cp/cvt.c    (revision 194020)
+++ cp/cvt.c    (working copy)
@@ -215,16 +215,14 @@ cp_convert_to_pointer (tree type, tree expr, tsubs
        return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
                                 /*c_cast_p=*/false, complain);
 
-      if (TYPE_PTRDATAMEM_P (type))
-       {
-         /* A NULL pointer-to-member is represented by -1, not by
-            zero.  */
-         expr = build_int_cst_type (type, -1);
-       }
-      else
-       expr = build_int_cst (type, 0);
+      /* A NULL pointer-to-data-member is represented by -1, not by
+        zero.  */
+      tree val = (TYPE_PTRDATAMEM_P (type)
+                 ? build_int_cst_type (type, -1)
+                 : build_int_cst (type, 0));
 
-      return expr;
+      return (TREE_SIDE_EFFECTS (expr)
+             ? build2 (COMPOUND_EXPR, type, expr, val) : val);
     }
   else if (TYPE_PTRMEM_P (type) && INTEGRAL_CODE_P (form))
     {
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 194020)
+++ cp/typeck.c (working copy)
@@ -7567,7 +7567,7 @@ build_ptrmemfunc (tree type, tree pfn, int force,
   /* Handle null pointer to member function conversions.  */
   if (null_ptr_cst_p (pfn))
     {
-      pfn = build_c_cast (input_location, type, nullptr_node);
+      pfn = build_c_cast (input_location, type, pfn);
       return build_ptrmemfunc1 (to_type,
                                integer_zero_node,
                                pfn);
Index: testsuite/g++.dg/cpp0x/lambda/lambda-nullptr.C
===================================================================
--- testsuite/g++.dg/cpp0x/lambda/lambda-nullptr.C      (revision 0)
+++ testsuite/g++.dg/cpp0x/lambda/lambda-nullptr.C      (working copy)
@@ -0,0 +1,47 @@
+// PR c++/54170
+// { dg-do run { target c++11 } }
+
+#include <cassert> 
+
+struct A;
+typedef A* ptr;
+typedef int (A::*pmf) (int);
+typedef int (A::*pdm);
+
+int total;
+
+void add(int n)
+{
+  total += n;
+}
+
+template <typename RType, typename Callable>
+RType Call(Callable native_func, int arg)
+{
+  return native_func(arg);
+}
+
+template <typename RType>
+RType do_test(int delta)
+{
+  return Call<RType>([=](int delta) { add(delta); return nullptr; }, delta);
+}
+
+template <typename RType>
+void test()
+{
+  total = 0;
+  assert (!do_test<RType>(5));
+  assert (total == 5);
+  assert (!do_test<RType>(20));
+  assert (total == 25);
+  assert (!do_test<RType>(-256));
+  assert (total == -231);
+}
+
+int main()
+{
+  test<ptr>();
+  test<pdm>();
+  test<pmf>();
+}

Reply via email to