On Wed, Apr 18, 2018 at 09:32:53PM +0200, Jakub Jelinek wrote:
> In any case, this reinterpret_cast constexpr pedantic stuff looks too
> large/risky at this point to me, I wonder if we accept-invalid even the
> simple constexpr int a = reinterpret_cast<int> (1); whether it is not ok for
> GCC8 to not error out on reinterpret_cast from PTRMEM_CSTs too, essentially
> just use Alex's patch for expr.c and the first hunk from this patch from
> constexpr.c, plus the new testcases and deal with the rest for stage1. 
> Thoughts on this?

I've tried following patch, but it regresses
+FAIL: g++.dg/conversion/ptrmem5.C  -std=c++11 (test for excess errors)
+FAIL: g++.dg/conversion/ptrmem5.C  -std=c++14 (test for excess errors)
+FAIL: g++.dg/conversion/ptrmem5.C  -std=c++98 (test for excess errors)
+FAIL: g++.dg/init/static2.C  -std=c++11 (test for excess errors)
+UNRESOLVED: g++.dg/init/static2.C  -std=c++11 compilation failed to produce 
executable
+FAIL: g++.dg/init/static2.C  -std=c++14 (test for excess errors)
+UNRESOLVED: g++.dg/init/static2.C  -std=c++14 compilation failed to produce 
executable
+FAIL: g++.dg/init/static2.C  -std=c++98 (test for excess errors)
+UNRESOLVED: g++.dg/init/static2.C  -std=c++98 compilation failed to produce 
executable
apparently a reinterpret_cast in that case is something that shouldn't be
handled by cxx_eval_constant_expression, or we ICE.  And if instead of the
constexpr.c hunk I try to add || can_convert (type, TREE_TYPE (op), tf_none)
then the testcases from the PR don't work anymore.

So I'm afraid I need to give up on this, Alex, if you have ideas what to do,
I'd appreciate if you could look at this, otherwise we'll need to defer this
P1 for next week.

--- gcc/cp/constexpr.c.jj       2018-04-13 10:33:03.078658240 +0200
+++ gcc/cp/constexpr.c  2018-04-18 15:53:07.936504106 +0200
@@ -4596,20 +4596,7 @@ cxx_eval_constant_expression (const cons
            && !TYPE_PTRMEM_P (type))
          op = cplus_expand_constant (op);
        if (TREE_CODE (op) == PTRMEM_CST && tcode == NOP_EXPR)
-         {
-           if (same_type_ignoring_top_level_qualifiers_p (type,
-                                                          TREE_TYPE (op))
-               || can_convert_qual (type, op))
-             return cp_fold_convert (type, op);
-           else
-             {
-               if (!ctx->quiet)
-                 error_at (EXPR_LOC_OR_LOC (t, input_location),
-                           "a reinterpret_cast is not a constant expression");
-               *non_constant_p = true;
-               return t;
-             }
-         }
+         return cp_fold_convert (type, op);
 
        if (POINTER_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
          {
--- gcc/cp/expr.c.jj    2018-03-09 23:22:23.682236182 +0100
+++ gcc/cp/expr.c       2018-04-18 14:24:52.692310448 +0200
@@ -50,11 +50,36 @@ cplus_expand_constant (tree cst)
            while (!same_type_p (DECL_CONTEXT (member),
                                 TYPE_PTRMEM_CLASS_TYPE (type)))
              {
+               tree t1 = TYPE_MAIN_VARIANT (DECL_CONTEXT (member));
+               tree t2 = TYPE_MAIN_VARIANT (TYPE_PTRMEM_CLASS_TYPE (type));
+
+               if (can_convert (t2, t1, 0))
+                 {
+                   base_kind kind;
+                   tree binfo = lookup_base (t1, t2, ba_unique, &kind, 0);
+                   if (binfo != error_mark_node
+                       && kind != bk_via_virtual)
+                     cst = size_binop (MINUS_EXPR, cst, BINFO_OFFSET (binfo));
+                   break;
+                 }
+
+               if (can_convert (t1, t2, 0))
+                 {
+                   base_kind kind;
+                   tree binfo = lookup_base (t2, t1, ba_unique, &kind, 0);
+                   if (binfo != error_mark_node
+                       && kind != bk_via_virtual)
+                     cst = size_binop (PLUS_EXPR, cst, BINFO_OFFSET (binfo));
+                   break;
+                 }
+
                /* The MEMBER must have been nestled within an
                   anonymous aggregate contained in TYPE.  Find the
                   anonymous aggregate.  */
                member = lookup_anon_field (TYPE_PTRMEM_CLASS_TYPE (type),
                                            DECL_CONTEXT (member));
+               if (!member)
+                 break;
                cst = size_binop (PLUS_EXPR, cst, byte_position (member));
              }
            cst = fold (build_nop (type, cst));
--- gcc/testsuite/g++.dg/cpp0x/pr85437.C.jj     2018-04-18 14:25:50.655332890 
+0200
+++ gcc/testsuite/g++.dg/cpp0x/pr85437.C        2018-04-18 14:28:34.234396893 
+0200
@@ -0,0 +1,17 @@
+// PR c++/85437
+// { dg-do compile { target c++11 } }
+
+struct A { int a; constexpr A() : a(0) {} };
+struct B : A { int x; constexpr B() : x(0) {} };
+struct X { int z; constexpr X() : z(0) {} };
+struct C : X, B {};
+constexpr int C::*cbx = &B::x;
+constexpr int B::*bx = &B::x;
+constexpr int A::*abx = static_cast<int(A::*)>(&B::x); // { dg-bogus "not a 
constant expression" }
+
+constexpr const C y;
+constexpr const B& yb = y;
+constexpr const A& ya = y;
+constexpr int const *pcbx = &(y.*cbx);
+constexpr int const *pbx = &(y.*bx);
+constexpr int const *pabx = &(ya.*abx);
--- gcc/testsuite/g++.dg/cpp0x/pr85437-2.C.jj   2018-04-18 14:25:50.654332889 
+0200
+++ gcc/testsuite/g++.dg/cpp0x/pr85437-2.C      2018-04-18 14:28:45.613401350 
+0200
@@ -0,0 +1,8 @@
+// PR c++/85437
+// { dg-do compile { target c++11 } }
+
+struct A { };
+struct B : A { int x; };
+
+constexpr int A::*abx
+= reinterpret_cast<int(A::*)>(&B::x); // { dg-error "reinterpret.*constant" "" 
{ xfail *-*-* } }
--- gcc/testsuite/g++.dg/cpp0x/pr85437-3.C.jj   2018-04-18 14:25:50.655332890 
+0200
+++ gcc/testsuite/g++.dg/cpp0x/pr85437-3.C      2018-04-18 14:29:57.691429562 
+0200
@@ -0,0 +1,8 @@
+// PR c++/85437
+// { dg-do compile { target c++11 } }
+
+struct A { int y; };
+struct B { int x; };
+struct C : A, B {};
+constexpr int C::*pci = &B::x;
+constexpr int A::*pai = static_cast<int A::*>(static_cast<int C::*>(&B::x)); 
// { dg-bogus "not a constant expression" }
--- gcc/testsuite/g++.dg/cpp0x/pr85437-4.C.jj   2018-04-18 14:29:29.028418341 
+0200
+++ gcc/testsuite/g++.dg/cpp0x/pr85437-4.C      2018-04-18 14:29:39.829422569 
+0200
@@ -0,0 +1,8 @@
+// PR c++/85437
+// { dg-do compile { target c++11 } }
+
+struct A { };
+struct B { int x; };
+struct C : A, B {};
+constexpr int C::*pci = &B::x;
+constexpr int A::*pai = static_cast<int A::*>(pci);    // { dg-bogus "not a 
constant expression" }


        Jakub

Reply via email to