Hi! Before location wrappers were introduced, the potential_constant_expression_1 assumption that a VIEW_CONVERT_EXPR must have non-NULL type was right, if it is a type dependent reinterpret cast, it would be REINTERPRET_CAST_EXPR instead.
Location wrappers around decls can have NULL type, if the decl they wrap also has NULL type. Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Alternatively it could if (TREE_TYPE (t) && ... On a related note, I wonder if the return (RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR)); a few lines below is correct, VCE isn't always an lvalue, only if it is used in non-rvalue contexts. So, shouldn't it be instead: return (RECUR (from, (TREE_CODE (t) == VIEW_CONVERT_EXPR ? want_rval : rval))); Don't have a testcase where it would matter though. 2018-01-18 Jakub Jelinek <ja...@redhat.com> PR c++/83918 * constexpr.c (potential_constant_expression_1) <case VIEW_CONVERT_EXPR>: Don't check for INTEGER_CST to pointer type conversion for location wrappers. * g++.dg/cpp1z/pr83918.C: New test. --- gcc/cp/constexpr.c.jj 2018-01-17 22:00:13.624228171 +0100 +++ gcc/cp/constexpr.c 2018-01-18 10:38:07.357469094 +0100 @@ -5385,7 +5385,8 @@ potential_constant_expression_1 (tree t, may change to something more specific to type-punning (DR 1312). */ { tree from = TREE_OPERAND (t, 0); - if (POINTER_TYPE_P (TREE_TYPE (t)) + if (!location_wrapper_p (t) + && POINTER_TYPE_P (TREE_TYPE (t)) && TREE_CODE (from) == INTEGER_CST && !integer_zerop (from)) { --- gcc/testsuite/g++.dg/cpp1z/pr83918.C.jj 2018-01-18 10:46:04.405439296 +0100 +++ gcc/testsuite/g++.dg/cpp1z/pr83918.C 2018-01-18 10:45:42.934442290 +0100 @@ -0,0 +1,32 @@ +// PR c++/83918 +// { dg-do compile } +// { dg-options "-std=c++17" } + +constexpr unsigned +foo (unsigned x, unsigned y) +{ + return x > y ? x : y; +} + +template <typename, typename> struct A; +template <auto ...> struct B; +template <auto S, auto ... T, auto U, auto ... V> +struct A <B <S, T...>, B <U, V...>> +{ + enum : unsigned + { + u = foo (sizeof (S), sizeof (U)), + v = A <B <T...>, B <V...>>::w, + w = foo (u, v) + }; +}; + +template <> +struct A <B <>, B <>> +{ + enum : unsigned { w = 0 }; +}; + +constexpr static const auto v { A <B <1,2,3,4,5,6,7,8,9>, + B <9,8,7,6,5,4,3,2,1>>::w }; +static_assert (v == sizeof (int)); Jakub