Hi,

with the recent fix for c++/57092, we don't ICE anymore on the various testcases part of c++/52282, but we still have problems. An issue I can see - maybe we already discussed it a bit in the past - is that of NOP_EXPRs which I don't fully understand: anyway, with the attached patchlet, the original testcase passes and adding the STRIP_NOPS seems to me rather natural in the light of many other existing uses right before handling ADDR_EXPRs. The patchlet passes testing and helps a lot for c++/52892 too (all the first testcases pass besides the last one, which however appears to point to a rather unrelated issue, at least judging by the error message). Does the additional STRIP_NOPS make sense to you?

Then, to the second, big testcase attached to c++/52282: with the STRIP_NOPS in place, we make good progress on it, but we still have errors for the following 4 tests which don't seem just matter of easy to strip NOPs:

static_assert((c.*W_<int(C::*)()const, &C::c1>::value)() == 10, "oops"); // incorrect evaluation static_assert((c.*X_<int(C::*)()const, &C::c1>::value)() == 10, "oops"); // incorrect evaluation static_assert((c.*Y_<int(C::*)()const, &C::c1>::value)() == 10, "oops"); // incorrect evaluation static_assert((c.*Z_<int(C::*)()const, &C::c1>::value)() == 10, "oops"); // incorrect evaluation

For the first one, for example, we have:

52282_1.C:65:1: error: non-constant condition for static assertion
static_assert((c.*W_<int(C::*)()const, &C::c1>::value)() == 10, "oops"); // incorrect evaluation
^
52282_1.C:65:56: error: expression ā€˜0u’ does not designate a constexpr function static_assert((c.*W_<int(C::*)()const, &C::c1>::value)() == 10, "oops"); // incorrect evaluation
^
Note the bizarre '0u', which characterizes all the remaining failures.

I'm also adding below the condition tree for the failure above, with the EQ_EXPR which is remaining unfolded. Please help ;)

Thanks!
Paolo.

//////////////////

<eq_expr 0x7ffff68bdeb0
type <boolean_type 0x7ffff6730b28 bool public unsigned QI
size <integer_cst 0x7ffff6715f80 constant 8>
unit size <integer_cst 0x7ffff6715fa0 constant 1>
align 8 symtab 0 alias set -1 canonical type 0x7ffff6730b28 precision 1 min <integer_cst 0x7ffff6733340 0> max <integer_cst 0x7ffff6733380 1>>
side-effects
arg 0 <call_expr 0x7ffff68b6150
type <integer_type 0x7ffff67305e8 int public type_6 SI
size <integer_cst 0x7ffff6733140 constant 32>
unit size <integer_cst 0x7ffff6733160 constant 4>
align 32 symtab 0 alias set -1 canonical type 0x7ffff67305e8 precision 32 min <integer_cst 0x7ffff67330e0 -2147483648> max <integer_cst 0x7ffff6733100 2147483647>
pointer_to_this <pointer_type 0x7ffff67382a0>>
side-effects
fn <nop_expr 0x7ffff68c00c0 type <pointer_type 0x7ffff68b7000>

arg 0 <component_ref 0x7ffff68b2780 type <pointer_type 0x7ffff68bf2a0>
arg 0 <var_decl 0x7ffff68aeb48 value> arg 1 <field_decl 0x7ffff68aec78 __pfn>
52282_1.C:65:56>>
arg 0 <pointer_plus_expr 0x7ffff68bde88 type <pointer_type 0x7ffff68b0690>

arg 0 <addr_expr 0x7ffff68c0020 type <pointer_type 0x7ffff68b0690>
readonly constant arg 0 <var_decl 0x7ffff68ae2f8 c>>
arg 1 <nop_expr 0x7ffff68c0080 type <integer_type 0x7ffff6730000 sizetype>

arg 0 <component_ref 0x7ffff68b27b0 type <integer_type 0x7ffff68bf498 long int> arg 0 <var_decl 0x7ffff68aeb48 value> arg 1 <field_decl 0x7ffff68aed10 __delta>
52282_1.C:65:56>>>
52282_1.C:65:56>
arg 1 <integer_cst 0x7ffff686f7c0 type <integer_type 0x7ffff67305e8 int> constant 10>
52282_1.C:65:58>


Index: cp/semantics.c
===================================================================
--- cp/semantics.c      (revision 198488)
+++ cp/semantics.c      (working copy)
@@ -6754,6 +6754,7 @@ cxx_eval_call_expression (const constexpr_call *ol
       /* Might be a constexpr function pointer.  */
       fun = cxx_eval_constant_expression (old_call, fun, allow_non_constant,
                                          /*addr*/false, non_constant_p, 
overflow_p);
+      STRIP_NOPS (fun);
       if (TREE_CODE (fun) == ADDR_EXPR)
        fun = TREE_OPERAND (fun, 0);
     }
Index: testsuite/g++.dg/cpp0x/constexpr-52282.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-52282.C    (revision 0)
+++ testsuite/g++.dg/cpp0x/constexpr-52282.C    (working copy)
@@ -0,0 +1,29 @@
+// PR c++/52282
+// { dg-do compile { target c++11 } }
+
+template <typename T, T V>
+struct A
+    {
+    static constexpr T a() { return V; }
+    };
+template <typename T, T V>
+struct B
+    {
+    typedef T type;
+    static constexpr type b() { return V; }
+    };
+template <typename T, T V>
+struct C
+    {
+    static constexpr decltype(V) c() { return V; }
+    };
+static_assert(A<int, 10>::a() == 10, "oops");
+static_assert(B<int, 10>::b() == 10, "oops");
+static_assert(C<int, 10>::c() == 10, "oops");
+struct D
+    {
+    static constexpr int d() { return 10; }
+    };
+static_assert((A<int(*)(), &D::d>::a())() == 10, "oops");
+static_assert((B<int(*)(), &D::d>::b())() == 10, "oops"); // error
+static_assert((C<int(*)(), &D::d>::c())() == 10, "oops");

Reply via email to