re PR sanitizer/88901 (ICE when using -fsanitize=pointer-compare)
[gcc.git] / gcc / cp / constexpr.c
index 4d2ee4a28fca6a6e0a7851725a0a4d9f5dde7214..ed4bbeeb157878bd08721820fc46444dc80dca8b 100644 (file)
@@ -2,7 +2,7 @@
    constexpr functions.  These routines are used both during actual parsing
    and during the instantiation of template functions.
 
-   Copyright (C) 1998-2018 Free Software Foundation, Inc.
+   Copyright (C) 1998-2019 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ubsan.h"
 #include "gimple-fold.h"
 #include "timevar.h"
+#include "fold-const-call.h"
 
 static bool verify_constant (tree, bool, bool *, bool *);
 #define VERIFY_CONSTANT(X)                                             \
@@ -41,6 +42,9 @@ do {                                                                  \
     return t;                                                          \
  } while (0)
 
+static HOST_WIDE_INT find_array_ctor_elt (tree ary, tree dindex,
+                                         bool insert = false);
+
 /* Returns true iff FUN is an instantiation of a constexpr function
    template or a defaulted constexpr function.  */
 
@@ -60,7 +64,7 @@ literal_type_p (tree t)
 {
   if (SCALAR_TYPE_P (t)
       || VECTOR_TYPE_P (t)
-      || TREE_CODE (t) == REFERENCE_TYPE
+      || TYPE_REF_P (t)
       || (VOID_TYPE_P (t) && cxx_dialect >= cxx14))
     return true;
   if (CLASS_TYPE_P (t))
@@ -91,12 +95,16 @@ ensure_literal_type_for_constexpr_object (tree decl)
       if (CLASS_TYPE_P (stype) && !COMPLETE_TYPE_P (complete_type (stype)))
        /* Don't complain here, we'll complain about incompleteness
           when we try to initialize the variable.  */;
+      else if (type_uses_auto (type))
+       /* We don't know the actual type yet.  */;
       else if (!literal_type_p (type))
        {
          if (DECL_DECLARED_CONSTEXPR_P (decl))
            {
-             error ("the type %qT of %<constexpr%> variable %qD "
-                    "is not literal", type, decl);
+             auto_diagnostic_group d;
+             error_at (DECL_SOURCE_LOCATION (decl),
+                       "the type %qT of %<constexpr%> variable %qD "
+                       "is not literal", type, decl);
              explain_non_literal_class (type);
              decl = error_mark_node;
            }
@@ -104,14 +112,24 @@ ensure_literal_type_for_constexpr_object (tree decl)
            {
              if (!is_instantiation_of_constexpr (current_function_decl))
                {
-                 error ("variable %qD of non-literal type %qT in %<constexpr%> "
-                        "function", decl, type);
+                 auto_diagnostic_group d;
+                 error_at (DECL_SOURCE_LOCATION (decl),
+                           "variable %qD of non-literal type %qT in "
+                           "%<constexpr%> function", decl, type);
                  explain_non_literal_class (type);
                  decl = error_mark_node;
                }
              cp_function_chain->invalid_constexpr = true;
            }
        }
+      else if (DECL_DECLARED_CONSTEXPR_P (decl)
+              && variably_modified_type_p (type, NULL_TREE))
+       {
+         error_at (DECL_SOURCE_LOCATION (decl),
+                   "%<constexpr%> variable %qD has variably-modified "
+                   "type %qT", decl, type);
+         decl = error_mark_node;
+       }
     }
   return decl;
 }
@@ -191,6 +209,7 @@ is_valid_constexpr_fn (tree fun, bool complain)
            ret = false;
            if (complain)
              {
+               auto_diagnostic_group d;
                error ("invalid type for parameter %d of %<constexpr%> "
                       "function %q+#D", DECL_PARM_INDEX (parm), fun);
                explain_non_literal_class (TREE_TYPE (parm));
@@ -213,6 +232,7 @@ is_valid_constexpr_fn (tree fun, bool complain)
          ret = false;
          if (complain)
            {
+             auto_diagnostic_group d;
              error ("invalid return type %qT of %<constexpr%> function %q+D",
                     rettype, fun);
              explain_non_literal_class (rettype);
@@ -225,11 +245,15 @@ is_valid_constexpr_fn (tree fun, bool complain)
          && !CLASSTYPE_LITERAL_P (DECL_CONTEXT (fun)))
        {
          ret = false;
-         if (complain
-             && pedwarn (DECL_SOURCE_LOCATION (fun), OPT_Wpedantic,
-                         "enclosing class of %<constexpr%> non-static member "
-                         "function %q+#D is not a literal type", fun))
-           explain_non_literal_class (DECL_CONTEXT (fun));
+         if (complain)
+           {
+             auto_diagnostic_group d;
+             if (pedwarn (DECL_SOURCE_LOCATION (fun), OPT_Wpedantic,
+                            "enclosing class of %<constexpr%> non-static"
+                            " member function %q+#D is not a literal type",
+                            fun))
+               explain_non_literal_class (DECL_CONTEXT (fun));
+           }
        }
     }
   else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun)))
@@ -650,7 +674,7 @@ get_function_named_in_call (tree t)
    return value if suitable, error_mark_node for a statement not allowed in
    a constexpr function, or NULL_TREE if no return value was found.  */
 
-static tree
+tree
 constexpr_fn_retval (tree body)
 {
   switch (TREE_CODE (body))
@@ -704,7 +728,7 @@ constexpr_fn_retval (tree body)
        {
          tree fun = get_function_named_in_call (body);
          if (fun != NULL_TREE
-             && DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE)
+             && fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE))
            return NULL_TREE;
        }
       /* Fallthru.  */
@@ -783,7 +807,7 @@ cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
          tree ftype;
          if (TREE_CODE (field) != FIELD_DECL)
            continue;
-         if (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))
+         if (DECL_UNNAMED_BIT_FIELD (field))
            continue;
          if (DECL_ARTIFICIAL (field))
            continue;
@@ -808,6 +832,7 @@ cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
            }
          if (!complain)
            return true;
+         auto_diagnostic_group d;
          error ("member %qD must be initialized by mem-initializer "
                 "in %<constexpr%> constructor", field);
          inform (DECL_SOURCE_LOCATION (field), "declared here");
@@ -952,6 +977,8 @@ struct GTY((for_user)) constexpr_call {
   /* The hash of this call; we remember it here to avoid having to
      recalculate it when expanding the hash table.  */
   hashval_t hash;
+  /* Whether __builtin_is_constant_evaluated() should evaluate to true.  */
+  bool manifestly_const_eval;
 };
 
 struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call>
@@ -998,6 +1025,8 @@ struct constexpr_ctx {
   /* Whether we are strictly conforming to constant expression rules or
      trying harder to get a constant value.  */
   bool strict;
+  /* Whether __builtin_is_constant_evaluated () should be true.  */
+  bool manifestly_const_eval;
 };
 
 /* A table of all constexpr calls that have been evaluated by the
@@ -1026,18 +1055,22 @@ constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
   tree lhs_bindings;
   tree rhs_bindings;
   if (lhs == rhs)
-    return 1;
+    return true;
+  if (lhs->hash != rhs->hash)
+    return false;
+  if (lhs->manifestly_const_eval != rhs->manifestly_const_eval)
+    return false;
   if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
-    return 0;
+    return false;
   lhs_bindings = lhs->bindings;
   rhs_bindings = rhs->bindings;
   while (lhs_bindings != NULL && rhs_bindings != NULL)
     {
       tree lhs_arg = TREE_VALUE (lhs_bindings);
       tree rhs_arg = TREE_VALUE (rhs_bindings);
-      gcc_assert (TREE_TYPE (lhs_arg) == TREE_TYPE (rhs_arg));
+      gcc_assert (same_type_p (TREE_TYPE (lhs_arg), TREE_TYPE (rhs_arg)));
       if (!cp_tree_equal (lhs_arg, rhs_arg))
-        return 0;
+        return false;
       lhs_bindings = TREE_CHAIN (lhs_bindings);
       rhs_bindings = TREE_CHAIN (rhs_bindings);
     }
@@ -1160,9 +1193,12 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
   int i;
 
   /* Don't fold __builtin_constant_p within a constexpr function.  */
-  bool bi_const_p = (DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P);
+  bool bi_const_p = DECL_IS_BUILTIN_CONSTANT_P (fun);
 
+  /* If we aren't requiring a constant expression, defer __builtin_constant_p
+     in a constexpr function until we have values for the parameters.  */
   if (bi_const_p
+      && !ctx->manifestly_const_eval
       && current_function_decl
       && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
     {
@@ -1170,19 +1206,41 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
       return t;
     }
 
+  /* For __builtin_is_constant_evaluated, defer it if not
+     ctx->manifestly_const_eval, otherwise fold it to true.  */
+  if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+                        BUILT_IN_FRONTEND))
+    {
+      if (!ctx->manifestly_const_eval)
+       {
+         *non_constant_p = true;
+         return t;
+       }
+      return boolean_true_node;
+    }
+
   /* Be permissive for arguments to built-ins; __builtin_constant_p should
      return constant false for a non-constant argument.  */
   constexpr_ctx new_ctx = *ctx;
   new_ctx.quiet = true;
-  bool dummy1 = false, dummy2 = false;
   for (i = 0; i < nargs; ++i)
     {
-      args[i] = cxx_eval_constant_expression (&new_ctx, CALL_EXPR_ARG (t, i),
-                                             false, &dummy1, &dummy2);
+      args[i] = CALL_EXPR_ARG (t, i);
+      /* If builtin_valid_in_constant_expr_p is true,
+        potential_constant_expression_1 has not recursed into the arguments
+        of the builtin, verify it here.  */
+      if (!builtin_valid_in_constant_expr_p (fun)
+         || potential_constant_expression (args[i]))
+       {
+         bool dummy1 = false, dummy2 = false;
+         args[i] = cxx_eval_constant_expression (&new_ctx, args[i], false,
+                                                 &dummy1, &dummy2);
+       }
+
       if (bi_const_p)
-       /* For __built_in_constant_p, fold all expressions with constant values
+       /* For __builtin_constant_p, fold all expressions with constant values
           even if they aren't C++ constant-expressions.  */
-       args[i] = cp_fully_fold (args[i]);
+       args[i] = cp_fold_rvalue (args[i]);
     }
 
   bool save_ffbcp = force_folding_builtin_constant_p;
@@ -1197,7 +1255,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
          /* Do not allow__builtin_unreachable in constexpr function.
             The __builtin_unreachable call with BUILTINS_LOCATION
             comes from cp_maybe_instrument_return.  */
-         if (DECL_FUNCTION_CODE (fun) == BUILT_IN_UNREACHABLE
+         if (fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE)
              && EXPR_LOCATION (t) == BUILTINS_LOCATION)
            error ("%<constexpr%> call flows off the end of the function");
          else
@@ -1229,11 +1287,13 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
 static tree
 adjust_temp_type (tree type, tree temp)
 {
-  if (TREE_TYPE (temp) == type)
+  if (same_type_p (TREE_TYPE (temp), type))
     return temp;
   /* Avoid wrapping an aggregate value in a NOP_EXPR.  */
   if (TREE_CODE (temp) == CONSTRUCTOR)
     return build_constructor (type, CONSTRUCTOR_ELTS (temp));
+  if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
+    return build0 (EMPTY_CLASS_EXPR, type);
   gcc_assert (scalarish_type_p (type));
   return cp_fold_convert (type, temp);
 }
@@ -1304,9 +1364,11 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
 
       if (!*non_constant_p)
        {
+         /* Don't share a CONSTRUCTOR that might be changed.  */
+         arg = unshare_constructor (arg);
          /* Make sure the binding has the same type as the parm.  But
             only for constant args.  */
-         if (TREE_CODE (type) != REFERENCE_TYPE)
+         if (!TYPE_REF_P (type))
            arg = adjust_temp_type (type, arg);
          if (!TREE_CONSTANT (arg))
            *non_constant_args = true;
@@ -1388,9 +1450,23 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
       return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
                                           false, non_constant_p, overflow_p);
 
+    case IFN_VEC_CONVERT:
+      {
+       tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
+                                                false, non_constant_p,
+                                                overflow_p);
+       if (TREE_CODE (arg) == VECTOR_CST)
+         return fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg);
+       else
+         {
+           *non_constant_p = true;
+           return t;
+         }
+      }
+
     default:
       if (!ctx->quiet)
-       error_at (EXPR_LOC_OR_LOC (t, input_location),
+       error_at (cp_expr_loc_or_loc (t, input_location),
                  "call to internal function %qE", t);
       *non_constant_p = true;
       return t;
@@ -1405,7 +1481,7 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
 
   if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
     {
-      location_t loc = EXPR_LOC_OR_LOC (t, input_location);
+      location_t loc = cp_expr_loc_or_loc (t, input_location);
       tree type = TREE_TYPE (TREE_TYPE (t));
       tree result = fold_binary_loc (loc, opcode, type,
                                     fold_convert_loc (loc, type, arg0),
@@ -1423,14 +1499,14 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
   return t;
 }
 
-/* Clean CONSTRUCTOR_NO_IMPLICIT_ZERO from CTOR and its sub-aggregates.  */
+/* Clean CONSTRUCTOR_NO_CLEARING from CTOR and its sub-aggregates.  */
 
 static void
 clear_no_implicit_zero (tree ctor)
 {
-  if (CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor))
+  if (CONSTRUCTOR_NO_CLEARING (ctor))
     {
-      CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor) = false;
+      CONSTRUCTOR_NO_CLEARING (ctor) = false;
       tree elt; unsigned HOST_WIDE_INT idx;
       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), idx, elt)
        if (TREE_CODE (elt) == CONSTRUCTOR)
@@ -1447,9 +1523,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
                          bool lval,
                          bool *non_constant_p, bool *overflow_p)
 {
-  location_t loc = EXPR_LOC_OR_LOC (t, input_location);
+  location_t loc = cp_expr_loc_or_loc (t, input_location);
   tree fun = get_function_named_in_call (t);
-  constexpr_call new_call = { NULL, NULL, NULL, 0 };
+  constexpr_call new_call
+    = { NULL, NULL, NULL, 0, ctx->manifestly_const_eval };
   bool depth_ok;
 
   if (fun == NULL_TREE)
@@ -1465,6 +1542,36 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
       STRIP_NOPS (fun);
       if (TREE_CODE (fun) == ADDR_EXPR)
        fun = TREE_OPERAND (fun, 0);
+      /* For TARGET_VTABLE_USES_DESCRIPTORS targets, there is no
+        indirection, the called expression is a pointer into the
+        virtual table which should contain FDESC_EXPR.  Extract the
+        FUNCTION_DECL from there.  */
+      else if (TARGET_VTABLE_USES_DESCRIPTORS
+              && TREE_CODE (fun) == POINTER_PLUS_EXPR
+              && TREE_CODE (TREE_OPERAND (fun, 0)) == ADDR_EXPR
+              && TREE_CODE (TREE_OPERAND (fun, 1)) == INTEGER_CST)
+       {
+         tree d = TREE_OPERAND (TREE_OPERAND (fun, 0), 0);
+         if (VAR_P (d)
+             && DECL_VTABLE_OR_VTT_P (d)
+             && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE
+             && TREE_TYPE (TREE_TYPE (d)) == vtable_entry_type
+             && DECL_INITIAL (d)
+             && TREE_CODE (DECL_INITIAL (d)) == CONSTRUCTOR)
+           {
+             tree i = int_const_binop (TRUNC_DIV_EXPR, TREE_OPERAND (fun, 1),
+                                       TYPE_SIZE_UNIT (vtable_entry_type));
+             HOST_WIDE_INT idx = find_array_ctor_elt (DECL_INITIAL (d), i);
+             if (idx >= 0)
+               {
+                 tree fdesc
+                   = (*CONSTRUCTOR_ELTS (DECL_INITIAL (d)))[idx].value;
+                 if (TREE_CODE (fdesc) == FDESC_EXPR
+                     && integer_zerop (TREE_OPERAND (fdesc, 1)))
+                   fun = TREE_OPERAND (fdesc, 0);
+               }
+           }
+       }
     }
   if (TREE_CODE (fun) != FUNCTION_DECL)
     {
@@ -1480,7 +1587,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
   if (is_ubsan_builtin_p (fun))
     return void_node;
 
-  if (is_builtin_fn (fun))
+  if (fndecl_built_in_p (fun))
     return cxx_eval_builtin_function_call (ctx, t, fun,
                                           lval, non_constant_p, overflow_p);
   if (!DECL_DECLARED_CONSTEXPR_P (fun))
@@ -1503,7 +1610,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
         If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT.  */
       new_ctx.object = AGGR_INIT_EXPR_SLOT (t);
       tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
-      CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor) = true;
+      CONSTRUCTOR_NO_CLEARING (ctor) = true;
       ctx->values->put (new_ctx.object, ctor);
       ctx = &new_ctx;
     }
@@ -1591,8 +1698,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
   constexpr_call *entry = NULL;
   if (depth_ok && !non_constant_args && ctx->strict)
     {
-      new_call.hash = iterative_hash_template_arg
-       (new_call.bindings, constexpr_fundef_hasher::hash (new_call.fundef));
+      new_call.hash = constexpr_fundef_hasher::hash (new_call.fundef);
+      new_call.hash
+       = iterative_hash_template_arg (new_call.bindings, new_call.hash);
+      new_call.hash
+       = iterative_hash_object (ctx->manifestly_const_eval, new_call.hash);
 
       /* If we have seen this call before, we are done.  */
       maybe_initialize_constexpr_call_table ();
@@ -1623,7 +1733,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
     {
       if (!ctx->quiet)
        error ("%<constexpr%> evaluation depth exceeds maximum of %d (use "
-              "-fconstexpr-depth= to increase the maximum)",
+              "%<-fconstexpr-depth=%> to increase the maximum)",
               max_constexpr_depth);
       *non_constant_p = true;
       result = error_mark_node;
@@ -1753,6 +1863,9 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 bool
 reduced_constant_expression_p (tree t)
 {
+  if (t == NULL_TREE)
+    return false;
+
   switch (TREE_CODE (t))
     {
     case PTRMEM_CST:
@@ -1762,15 +1875,20 @@ reduced_constant_expression_p (tree t)
     case CONSTRUCTOR:
       /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR.  */
       tree idx, val, field; unsigned HOST_WIDE_INT i;
-      if (CONSTRUCTOR_NO_IMPLICIT_ZERO (t))
-       field = next_initializable_field (TYPE_FIELDS (TREE_TYPE (t)));
+      if (CONSTRUCTOR_NO_CLEARING (t))
+       {
+         if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+           /* An initialized vector would have a VECTOR_CST.  */
+           return false;
+         else
+           field = next_initializable_field (TYPE_FIELDS (TREE_TYPE (t)));
+       }
       else
        field = NULL_TREE;
       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, idx, val)
        {
-         if (!val)
-           /* We're in the middle of initializing this element.  */
-           return false;
+         /* If VAL is null, we're in the middle of initializing this
+            element.  */
          if (!reduced_constant_expression_p (val))
            return false;
          if (field)
@@ -1782,9 +1900,9 @@ reduced_constant_expression_p (tree t)
        }
       if (field)
        return false;
-      else if (CONSTRUCTOR_NO_IMPLICIT_ZERO (t))
+      else if (CONSTRUCTOR_NO_CLEARING (t))
        /* All the fields are initialized.  */
-       CONSTRUCTOR_NO_IMPLICIT_ZERO (t) = false;
+       CONSTRUCTOR_NO_CLEARING (t) = false;
       return true;
 
     default:
@@ -1794,8 +1912,8 @@ reduced_constant_expression_p (tree t)
 }
 
 /* Some expressions may have constant operands but are not constant
-   themselves, such as 1/0.  Call this function (or rather, the macro
-   following it) to check for that condition.
+   themselves, such as 1/0.  Call this function to check for that
+   condition.
 
    We only call this in places that require an arithmetic constant, not in
    places where we might have a non-constant expression that can be a
@@ -1866,9 +1984,14 @@ cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
      if E1 has a signed type and non-negative value, and E1x2^E2 is
      representable in the corresponding unsigned type of the result type,
      then that value, converted to the result type, is the resulting value;
-     otherwise, the behavior is undefined.  */
-  if (code == LSHIFT_EXPR && !TYPE_UNSIGNED (lhstype)
-      && (cxx_dialect >= cxx11))
+     otherwise, the behavior is undefined.
+     For C++2a:
+     The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo
+     2^N, where N is the range exponent of the type of the result.  */
+  if (code == LSHIFT_EXPR
+      && !TYPE_UNSIGNED (lhstype)
+      && cxx_dialect >= cxx11
+      && cxx_dialect < cxx2a)
     {
       if (tree_int_cst_sgn (lhs) == -1)
        {
@@ -2021,8 +2144,22 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
 
       if (TREE_CODE (lhs) == PTRMEM_CST
          && TREE_CODE (rhs) == PTRMEM_CST)
-       r = constant_boolean_node (cp_tree_equal (lhs, rhs) == is_code_eq,
-                                  type);
+       {
+         tree lmem = PTRMEM_CST_MEMBER (lhs);
+         tree rmem = PTRMEM_CST_MEMBER (rhs);
+         bool eq;
+         if (TREE_CODE (lmem) == TREE_CODE (rmem)
+             && TREE_CODE (lmem) == FIELD_DECL
+             && TREE_CODE (DECL_CONTEXT (lmem)) == UNION_TYPE
+             && same_type_p (DECL_CONTEXT (lmem),
+                             DECL_CONTEXT (rmem)))
+           /* If both refer to (possibly different) members of the same union
+              (12.3), they compare equal. */
+           eq = true;
+         else
+           eq = cp_tree_equal (lhs, rhs);
+         r = constant_boolean_node (eq == is_code_eq, type);
+       }
       else if ((TREE_CODE (lhs) == PTRMEM_CST
                || TREE_CODE (rhs) == PTRMEM_CST)
               && (null_member_pointer_value_p (lhs)
@@ -2038,6 +2175,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
     {
       if (!ctx->quiet)
        error ("arithmetic involving a null pointer in %qE", lhs);
+      *non_constant_p = true;
       return t;
     }
   else if (code == POINTER_PLUS_EXPR)
@@ -2058,7 +2196,7 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
     *non_constant_p = true;
   /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
      a local array in a constexpr function.  */
-  bool ptr = POINTER_TYPE_P (TREE_TYPE (lhs));
+  bool ptr = INDIRECT_TYPE_P (TREE_TYPE (lhs));
   if (!ptr)
     VERIFY_CONSTANT (r);
   return r;
@@ -2161,7 +2299,7 @@ array_index_cmp (tree key, tree index)
    if none.  If INSERT is true, insert a matching element rather than fail.  */
 
 static HOST_WIDE_INT
-find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
+find_array_ctor_elt (tree ary, tree dindex, bool insert)
 {
   if (tree_int_cst_sgn (dindex) < 0)
     return -1;
@@ -2177,9 +2315,9 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
      that the same is true of the other elements and index directly.  */
   if (end > 0)
     {
-      tree cindex = (*elts)[end-1].index;
+      tree cindex = (*elts)[end - 1].index;
       if (TREE_CODE (cindex) == INTEGER_CST
-         && compare_tree_int (cindex, end-1) == 0)
+         && compare_tree_int (cindex, end - 1) == 0)
        {
          if (i < end)
            return i;
@@ -2208,6 +2346,8 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
              constructor_elt e;
              tree lo = TREE_OPERAND (idx, 0);
              tree hi = TREE_OPERAND (idx, 1);
+             tree value = elt.value;
+             dindex = fold_convert (sizetype, dindex);
              if (tree_int_cst_lt (lo, dindex))
                {
                  /* There are still some lower elts; shorten the range.  */
@@ -2221,7 +2361,7 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
                  /* Append the element we want to insert.  */
                  ++middle;
                  e.index = dindex;
-                 e.value = unshare_constructor (elt.value);
+                 e.value = unshare_constructor (value);
                  vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
                }
              else
@@ -2237,8 +2377,8 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
                    e.index = hi;
                  else
                    e.index = build2 (RANGE_EXPR, sizetype, new_lo, hi);
-                 e.value = unshare_constructor (elt.value);
-                 vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle+1, e);
+                 e.value = unshare_constructor (value);
+                 vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
                }
            }
          return middle;
@@ -2270,16 +2410,49 @@ diag_array_subscript (const constexpr_ctx *ctx, tree array, tree index)
       tree sidx = fold_convert (ssizetype, index);
       if (DECL_P (array))
        {
-         error ("array subscript value %qE is outside the bounds "
-                "of array %qD of type %qT", sidx, array, arraytype);
+         if (TYPE_DOMAIN (arraytype))
+           error ("array subscript value %qE is outside the bounds "
+                  "of array %qD of type %qT", sidx, array, arraytype);
+         else
+           error ("non-zero array subscript %qE is used with array %qD of "
+                  "type %qT with unknown bounds", sidx, array, arraytype);
          inform (DECL_SOURCE_LOCATION (array), "declared here");
        }
-      else
+      else if (TYPE_DOMAIN (arraytype))
        error ("array subscript value %qE is outside the bounds "
               "of array type %qT", sidx, arraytype);
+      else
+       error ("non-zero array subscript %qE is used with array of type %qT "
+              "with unknown bounds", sidx, arraytype);
     }
 }
 
+/* Return the number of elements for TYPE (which is an ARRAY_TYPE or
+   a VECTOR_TYPE).  */
+
+static tree
+get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
+                          bool *non_constant_p, bool *overflow_p)
+{
+  tree nelts;
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      if (TYPE_DOMAIN (type))
+       nelts = array_type_nelts_top (type);
+      else
+       nelts = size_zero_node;
+    }
+  else if (VECTOR_TYPE_P (type))
+    nelts = size_int (TYPE_VECTOR_SUBPARTS (type));
+  else
+    gcc_unreachable ();
+
+  /* For VLAs, the number of elements won't be an integer constant.  */
+  nelts = cxx_eval_constant_expression (ctx, nelts, false,
+                                       non_constant_p, overflow_p);
+  return nelts;
+}
+
 /* Extract element INDEX consisting of CHARS_PER_ELT chars from
    STRING_CST STRING.  */
 
@@ -2359,17 +2532,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
        }
     }
 
-  tree nelts;
-  if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
-    nelts = array_type_nelts_top (TREE_TYPE (ary));
-  else if (VECTOR_TYPE_P (TREE_TYPE (ary)))
-    nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary)));
-  else
-    gcc_unreachable ();
-
-  /* For VLAs, the number of elements won't be an integer constant.  */
-  nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
-                                       overflow_p);
+  tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p,
+                                         overflow_p);
   VERIFY_CONSTANT (nelts);
   if ((lval
        ? !tree_int_cst_le (index, nelts)
@@ -2417,7 +2581,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
   /* Not found.  */
 
   if (TREE_CODE (ary) == CONSTRUCTOR
-      && CONSTRUCTOR_NO_IMPLICIT_ZERO (ary))
+      && CONSTRUCTOR_NO_CLEARING (ary))
     {
       /* 'ary' is part of the aggregate initializer we're currently
         building; if there's no initializer for this element yet,
@@ -2451,10 +2615,14 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
   tree whole = cxx_eval_constant_expression (ctx, orig_whole,
                                             lval,
                                             non_constant_p, overflow_p);
-  if (TREE_CODE (whole) == INDIRECT_REF
-      && integer_zerop (TREE_OPERAND (whole, 0))
-      && !ctx->quiet)
-    error ("dereferencing a null pointer in %qE", orig_whole);
+  if (INDIRECT_REF_P (whole)
+      && integer_zerop (TREE_OPERAND (whole, 0)))
+    {
+      if (!ctx->quiet)
+       error ("dereferencing a null pointer in %qE", orig_whole);
+      *non_constant_p = true;
+      return t;
+    }
 
   if (TREE_CODE (whole) == PTRMEM_CST)
     whole = cplus_expand_constant (whole);
@@ -2512,7 +2680,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
 
   gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole)));
 
-  if (CONSTRUCTOR_NO_IMPLICIT_ZERO (whole))
+  if (CONSTRUCTOR_NO_CLEARING (whole))
     {
       /* 'whole' is part of the aggregate initializer we're currently
         building; if there's no initializer for this member yet, that's an
@@ -2679,8 +2847,10 @@ initialized_type (tree t)
 {
   if (TYPE_P (t))
     return t;
-  tree type = cv_unqualified (TREE_TYPE (t));
-  if (TREE_CODE (t) == CALL_EXPR || TREE_CODE (t) == AGGR_INIT_EXPR)
+  tree type = TREE_TYPE (t);
+  if (!VOID_TYPE_P (type))
+    /* No need to look deeper.  */;
+  else if (TREE_CODE (t) == CALL_EXPR)
     {
       /* A constructor call has void type, so we need to look deeper.  */
       tree fn = get_function_named_in_call (t);
@@ -2688,7 +2858,9 @@ initialized_type (tree t)
          && DECL_CXX_CONSTRUCTOR_P (fn))
        type = DECL_CONTEXT (fn);
     }
-  return type;
+  else if (TREE_CODE (t) == AGGR_INIT_EXPR)
+    type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t));
+  return cv_unqualified (type);
 }
 
 /* We're about to initialize element INDEX of an array or class from VALUE.
@@ -2718,7 +2890,7 @@ init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
   if (ctx->object)
     new_ctx.object = build_ctor_subob_ref (index, type, ctx->object);
   tree elt = build_constructor (type, NULL);
-  CONSTRUCTOR_NO_IMPLICIT_ZERO (elt) = true;
+  CONSTRUCTOR_NO_CLEARING (elt) = true;
   new_ctx.ctor = elt;
 
   if (TREE_CODE (value) == TARGET_EXPR)
@@ -2830,21 +3002,27 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
          gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index))));
          changed = true;
        }
-      else if (new_ctx.ctor != ctx->ctor)
+      else
        {
-         /* We appended this element above; update the value.  */
-         gcc_assert ((*p)->last().index == index);
-         (*p)->last().value = elt;
+         if (new_ctx.ctor != ctx->ctor)
+           {
+             /* We appended this element above; update the value.  */
+             gcc_assert ((*p)->last().index == index);
+             (*p)->last().value = elt;
+           }
+         else
+           CONSTRUCTOR_APPEND_ELT (*p, index, elt);
+         /* Adding or replacing an element might change the ctor's flags.  */
+         TREE_CONSTANT (ctx->ctor) = constant_p;
+         TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p;
        }
-      else
-       CONSTRUCTOR_APPEND_ELT (*p, index, elt);
     }
   if (*non_constant_p || !changed)
     return t;
   t = ctx->ctor;
   /* We're done building this CONSTRUCTOR, so now we can interpret an
      element without an explicit initializer as value-initialized.  */
-  CONSTRUCTOR_NO_IMPLICIT_ZERO (t) = false;
+  CONSTRUCTOR_NO_CLEARING (t) = false;
   TREE_CONSTANT (t) = constant_p;
   TREE_SIDE_EFFECTS (t) = side_effects_p;
   if (VECTOR_TYPE_P (type))
@@ -2870,12 +3048,11 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
                     bool *non_constant_p, bool *overflow_p)
 {
   tree elttype = TREE_TYPE (atype);
-  unsigned HOST_WIDE_INT max = tree_to_uhwi (array_type_nelts_top (atype));
   verify_ctor_sanity (ctx, atype);
   vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
-  vec_alloc (*p, max + 1);
   bool pre_init = false;
   unsigned HOST_WIDE_INT i;
+  tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
 
   /* For the default constructor, build up a call to the default
      constructor of the element type.  We only need to handle class types
@@ -2886,7 +3063,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
     /* We only do this at the lowest level.  */;
   else if (value_init)
     {
-      init = build_value_init (elttype, tf_warning_or_error);
+      init = build_value_init (elttype, complain);
       pre_init = true;
     }
   else if (!init)
@@ -2894,12 +3071,15 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
       vec<tree, va_gc> *argvec = make_tree_vector ();
       init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
                                        &argvec, elttype, LOOKUP_NORMAL,
-                                       tf_warning_or_error);
+                                       complain);
       release_tree_vector (argvec);
-      init = build_aggr_init_expr (TREE_TYPE (init), init);
+      init = build_aggr_init_expr (elttype, init);
       pre_init = true;
     }
 
+  tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p,
+                                         overflow_p);
+  unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts);
   for (i = 0; i < max; ++i)
     {
       tree idx = build_int_cst (size_type_node, i);
@@ -2918,8 +3098,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
              reuse = i == 0;
            }
          else
-           eltinit = cp_build_array_ref (input_location, init, idx,
-                                         tf_warning_or_error);
+           eltinit = cp_build_array_ref (input_location, init, idx, complain);
          eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit, value_init,
                                         lval,
                                         non_constant_p, overflow_p);
@@ -2928,6 +3107,9 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
        {
          /* Initializing an element using value or default initialization
             we just pre-built above.  */
+         if (init == void_node)
+           /* Trivial default-init, don't do anything to the CONSTRUCTOR.  */
+           return ctx->ctor;
          eltinit = cxx_eval_constant_expression (&new_ctx, init, lval,
                                                  non_constant_p, overflow_p);
          reuse = i == 0;
@@ -2937,14 +3119,12 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
          /* Copying an element.  */
          gcc_assert (same_type_ignoring_top_level_qualifiers_p
                      (atype, TREE_TYPE (init)));
-         eltinit = cp_build_array_ref (input_location, init, idx,
-                                       tf_warning_or_error);
+         eltinit = cp_build_array_ref (input_location, init, idx, complain);
          if (!lvalue_p (init))
            eltinit = move (eltinit);
-         eltinit = force_rvalue (eltinit, tf_warning_or_error);
-         eltinit = (cxx_eval_constant_expression
-                    (&new_ctx, eltinit, lval,
-                     non_constant_p, overflow_p));
+         eltinit = force_rvalue (eltinit, complain);
+         eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
+                                                 non_constant_p, overflow_p);
        }
       if (*non_constant_p && !ctx->quiet)
        break;
@@ -2957,28 +3137,30 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
       else
        CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit);
       /* Reuse the result of cxx_eval_constant_expression call
-         from the first iteration to all others if it is a constant
-         initializer that doesn't require relocations.  */
+        from the first iteration to all others if it is a constant
+        initializer that doesn't require relocations.  */
       if (reuse
          && max > 1
-         && (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit))
-             == null_pointer_node))
+         && (eltinit == NULL_TREE
+             || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit))
+                 == null_pointer_node)))
        {
          if (new_ctx.ctor != ctx->ctor)
            eltinit = new_ctx.ctor;
-         for (i = 1; i < max; ++i)
-           {
-             idx = build_int_cst (size_type_node, i);
-             CONSTRUCTOR_APPEND_ELT (*p, idx, unshare_constructor (eltinit));
-           }
+         tree range = build2 (RANGE_EXPR, size_type_node,
+                              build_int_cst (size_type_node, 1),
+                              build_int_cst (size_type_node, max - 1));
+         CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit));
          break;
        }
+      else if (i == 0)
+       vec_safe_reserve (*p, max);
     }
 
   if (!*non_constant_p)
     {
       init = ctx->ctor;
-      CONSTRUCTOR_NO_IMPLICIT_ZERO (init) = false;
+      CONSTRUCTOR_NO_CLEARING (init) = false;
     }
   return init;
 }
@@ -2999,6 +3181,23 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
     return r;
 }
 
+/* Like same_type_ignoring_top_level_qualifiers_p, but also handle the case
+   where the desired type is an array of unknown bounds because the variable
+   has had its bounds deduced since the wrapping expression was created.  */
+
+static bool
+same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2)
+{
+  while (TREE_CODE (type1) == ARRAY_TYPE
+        && TREE_CODE (type2) == ARRAY_TYPE
+        && (!TYPE_DOMAIN (type1) || !TYPE_DOMAIN (type2)))
+    {
+      type1 = TREE_TYPE (type1);
+      type2 = TREE_TYPE (type2);
+    }
+  return same_type_ignoring_top_level_qualifiers_p (type1, type2);
+}
+
 /* A less strict version of fold_indirect_ref_1, which requires cv-quals to
    match.  We want to be less strict for simple *& folding; if we have a
    non-const temporary that we access through a const pointer, that should
@@ -3013,12 +3212,13 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
 static tree
 cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
 {
-  tree sub, subtype;
+  tree sub = op0;
+  tree subtype;
+  poly_uint64 const_op01;
 
-  sub = op0;
   STRIP_NOPS (sub);
   subtype = TREE_TYPE (sub);
-  if (!POINTER_TYPE_P (subtype))
+  if (!INDIRECT_TYPE_P (subtype))
     return NULL_TREE;
 
   if (TREE_CODE (sub) == ADDR_EXPR)
@@ -3030,15 +3230,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
       if (TREE_CODE (op) == CONST_DECL)
        return DECL_INITIAL (op);
       /* *&p => p;  make sure to handle *&"str"[cst] here.  */
-      if (same_type_ignoring_top_level_qualifiers_p (optype, type)
-         /* Also handle the case where the desired type is an array of unknown
-            bounds because the variable has had its bounds deduced since the
-            ADDR_EXPR was created.  */
-         || (TREE_CODE (type) == ARRAY_TYPE
-             && TREE_CODE (optype) == ARRAY_TYPE
-             && TYPE_DOMAIN (type) == NULL_TREE
-             && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (optype),
-                                                           TREE_TYPE (type))))
+      if (same_type_ignoring_tlq_and_bounds_p (optype, type))
        {
          tree fop = fold_read_from_constant_string (op);
          if (fop)
@@ -3070,7 +3262,8 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
        {
          tree part_width = TYPE_SIZE (type);
          tree index = bitsize_int (0);
-         return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index);
+         return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width,
+                                 index);
        }
       /* Also handle conversion to an empty base class, which
         is represented with a NOP_EXPR.  */
@@ -3095,7 +3288,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
        }
     }
   else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
-          && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
+          && poly_int_tree_p (TREE_OPERAND (sub, 1), &const_op01))
     {
       tree op00 = TREE_OPERAND (sub, 0);
       tree op01 = TREE_OPERAND (sub, 1);
@@ -3109,29 +3302,37 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
 
          /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
          if (VECTOR_TYPE_P (op00type)
-             && (same_type_ignoring_top_level_qualifiers_p
-                 (type, TREE_TYPE (op00type))))
+             && same_type_ignoring_top_level_qualifiers_p
+                                               (type, TREE_TYPE (op00type))
+             /* POINTER_PLUS_EXPR second operand is sizetype, unsigned,
+                but we want to treat offsets with MSB set as negative.
+                For the code below negative offsets are invalid and
+                TYPE_SIZE of the element is something unsigned, so
+                check whether op01 fits into poly_int64, which implies
+                it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and
+                then just use poly_uint64 because we want to treat the
+                value as unsigned.  */
+             && tree_fits_poly_int64_p (op01))
            {
-             HOST_WIDE_INT offset = tree_to_shwi (op01);
              tree part_width = TYPE_SIZE (type);
-             unsigned HOST_WIDE_INT part_widthi = tree_to_shwi (part_width)/BITS_PER_UNIT;
-             unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
-             tree index = bitsize_int (indexi);
-
-             if (known_lt (offset / part_widthi,
-                           TYPE_VECTOR_SUBPARTS (op00type)))
-               return fold_build3_loc (loc,
-                                       BIT_FIELD_REF, type, op00,
-                                       part_width, index);
-
+             poly_uint64 max_offset
+               = (tree_to_uhwi (part_width) / BITS_PER_UNIT
+                  * TYPE_VECTOR_SUBPARTS (op00type));
+             if (known_lt (const_op01, max_offset))
+               {
+                 tree index = bitsize_int (const_op01 * BITS_PER_UNIT);
+                 return fold_build3_loc (loc,
+                                         BIT_FIELD_REF, type, op00,
+                                         part_width, index);
+               }
            }
          /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
          else if (TREE_CODE (op00type) == COMPLEX_TYPE
                   && (same_type_ignoring_top_level_qualifiers_p
                       (type, TREE_TYPE (op00type))))
            {
-             tree size = TYPE_SIZE_UNIT (type);
-             if (tree_int_cst_equal (size, op01))
+             if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)),
+                           const_op01))
                return fold_build1_loc (loc, IMAGPART_EXPR, type, op00);
            }
          /* ((foo *)&fooarray)[1] => fooarray[1] */
@@ -3143,11 +3344,17 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
              tree min_val = size_zero_node;
              if (type_domain && TYPE_MIN_VALUE (type_domain))
                min_val = TYPE_MIN_VALUE (type_domain);
-             op01 = size_binop_loc (loc, EXACT_DIV_EXPR, op01,
-                                    TYPE_SIZE_UNIT (type));
-             op01 = size_binop_loc (loc, PLUS_EXPR, op01, min_val);
-             return build4_loc (loc, ARRAY_REF, type, op00, op01,
-                                NULL_TREE, NULL_TREE);
+             offset_int off = wi::to_offset (op01);
+             offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type));
+             offset_int remainder;
+             off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder);
+             if (remainder == 0 && TREE_CODE (min_val) == INTEGER_CST)
+               {
+                 off = off + wi::to_offset (min_val);
+                 op01 = wide_int_to_tree (sizetype, off);
+                 return build4_loc (loc, ARRAY_REF, type, op00, op01,
+                                    NULL_TREE, NULL_TREE);
+               }
            }
          /* Also handle conversion to an empty base class, which
             is represented with a NOP_EXPR.  */
@@ -3180,7 +3387,8 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
     {
       tree type_domain;
       tree min_val = size_zero_node;
-      tree newsub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL);
+      tree newsub
+       = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL);
       if (newsub)
        sub = newsub;
       else
@@ -3313,7 +3521,7 @@ non_const_var_error (tree r)
       else
        gcc_unreachable ();
     }
-  else if (TREE_CODE (type) == REFERENCE_TYPE)
+  else if (TYPE_REF_P (type))
     inform (DECL_SOURCE_LOCATION (r),
            "%qD was not initialized with a constant "
            "expression", r);
@@ -3438,14 +3646,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
        case ARRAY_REF:
          tree nelts, ary;
          ary = TREE_OPERAND (probe, 0);
-         if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
-           nelts = array_type_nelts_top (TREE_TYPE (ary));
-         else if (VECTOR_TYPE_P (TREE_TYPE (ary)))
-           nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary)));
-         else
-           gcc_unreachable ();
-         nelts = cxx_eval_constant_expression (ctx, nelts, false,
-                                               non_constant_p, overflow_p);
+         nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary),
+                                            non_constant_p, overflow_p);
          VERIFY_CONSTANT (nelts);
          gcc_assert (TREE_CODE (nelts) == INTEGER_CST
                      && TREE_CODE (TREE_OPERAND (probe, 1)) == INTEGER_CST);
@@ -3531,7 +3733,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
       if (*valp == NULL_TREE)
        {
          *valp = build_constructor (type, NULL);
-         CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp) = no_zero_init;
+         CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
        }
       else if (TREE_CODE (*valp) == STRING_CST)
        {
@@ -3564,7 +3766,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
 
       /* If the value of object is already zero-initialized, any new ctors for
         subobjects will also be zero-initialized.  */
-      no_zero_init = CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp);
+      no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
 
       vec_safe_push (ctors, *valp);
 
@@ -3634,7 +3836,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
       if (*valp == NULL_TREE)
        {
          *valp = build_constructor (type, NULL);
-         CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp) = no_zero_init;
+         CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
        }
       else if (TREE_CODE (*valp) == PTRMEM_CST)
        *valp = cplus_expand_constant (*valp);
@@ -3657,8 +3859,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
       CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
       TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
       TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
-      CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp)
-       = CONSTRUCTOR_NO_IMPLICIT_ZERO (init);
+      CONSTRUCTOR_NO_CLEARING (*valp)
+       = CONSTRUCTOR_NO_CLEARING (init);
     }
   else
     *valp = init;
@@ -3710,14 +3912,14 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
                                    non_constant_p, overflow_p);
   /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
      a local array in a constexpr function.  */
-  bool ptr = POINTER_TYPE_P (TREE_TYPE (val));
+  bool ptr = INDIRECT_TYPE_P (TREE_TYPE (val));
   if (!ptr)
     VERIFY_CONSTANT (val);
 
   /* The modified value.  */
   bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
   tree mod;
-  if (POINTER_TYPE_P (type))
+  if (INDIRECT_TYPE_P (type))
     {
       /* The middle end requires pointers to use POINTER_PLUS_EXPR.  */
       offset = convert_to_ptrofftype (offset);
@@ -3767,6 +3969,7 @@ breaks (tree *jump_target)
   return *jump_target
     && ((TREE_CODE (*jump_target) == LABEL_DECL
         && LABEL_DECL_BREAK (*jump_target))
+       || TREE_CODE (*jump_target) == BREAK_STMT
        || TREE_CODE (*jump_target) == EXIT_EXPR);
 }
 
@@ -3774,8 +3977,10 @@ static bool
 continues (tree *jump_target)
 {
   return *jump_target
-    && TREE_CODE (*jump_target) == LABEL_DECL
-    && LABEL_DECL_CONTINUE (*jump_target);
+    && ((TREE_CODE (*jump_target) == LABEL_DECL
+        && LABEL_DECL_CONTINUE (*jump_target))
+       || TREE_CODE (*jump_target) == CONTINUE_STMT);
+
 }
 
 static bool
@@ -3853,6 +4058,16 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
   for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
     {
       tree stmt = tsi_stmt (i);
+      /* We've found a continue, so skip everything until we reach
+        the label its jumping to.  */
+      if (continues (jump_target))
+       {
+         if (label_matches (ctx, jump_target, stmt))
+           /* Found it.  */
+           *jump_target = NULL_TREE;
+         else
+           continue;
+       }
       if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
        continue;
       r = cxx_eval_constant_expression (ctx, stmt, false,
@@ -3893,7 +4108,7 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
       if (++count >= constexpr_loop_limit)
        {
          if (!ctx->quiet)
-           error_at (EXPR_LOC_OR_LOC (t, input_location),
+           error_at (cp_expr_loc_or_loc (t, input_location),
                      "%<constexpr%> loop iteration count exceeds limit of %d "
                      "(use -fconstexpr-loop-limit= to increase the limit)",
                      constexpr_loop_limit);
@@ -3987,7 +4202,7 @@ static tree
 cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
                              bool lval,
                              bool *non_constant_p, bool *overflow_p,
-                             tree *jump_target)
+                             tree *jump_target /* = NULL */)
 {
   constexpr_ctx new_ctx;
   tree r = t;
@@ -4013,7 +4228,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
          return NULL_TREE;
        }
     }
-  if (t == error_mark_node)
+  if (error_operand_p (t))
     {
       *non_constant_p = true;
       return t;
@@ -4029,7 +4244,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
        }
 
       if (TREE_CODE (t) == INTEGER_CST
-         && TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
+         && TYPE_PTR_P (TREE_TYPE (t))
          && !integer_zerop (t))
        {
          if (!ctx->quiet)
@@ -4050,7 +4265,15 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       /* We ask for an rvalue for the RESULT_DECL when indirecting
         through an invisible reference, or in named return value
         optimization.  */
-      return (*ctx->values->get (t));
+      if (tree *p = ctx->values->get (t))
+       return *p;
+      else
+       {
+         if (!ctx->quiet)
+           error ("%qE is not a constant expression", t);
+         *non_constant_p = true;
+       }
+      break;
 
     case VAR_DECL:
       if (DECL_HAS_VALUE_EXPR_P (t))
@@ -4062,7 +4285,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
         CONST_DECL for aggregate constants.  */
       if (lval)
        return t;
+      /* is_really_empty_class doesn't take into account _vptr, so initializing
+        otherwise empty class with { } would overwrite the initializer that
+        initialize_vtable created for us.  */
       if (COMPLETE_TYPE_P (TREE_TYPE (t))
+         && !TYPE_POLYMORPHIC_P (TREE_TYPE (t))
          && is_really_empty_class (TREE_TYPE (t)))
        {
          /* If the class is empty, we aren't actually loading anything.  */
@@ -4102,13 +4329,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       return t;
 
     case PARM_DECL:
-      if (lval && TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
+      if (lval && !TYPE_REF_P (TREE_TYPE (t)))
        /* glvalue use.  */;
       else if (tree *p = ctx->values->get (r))
        r = *p;
       else if (lval)
        /* Defer in case this is only used for its type.  */;
-      else if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
+      else if (TYPE_REF_P (TREE_TYPE (t)))
        /* Defer, there's no lvalue->rvalue conversion.  */;
       else if (COMPLETE_TYPE_P (TREE_TYPE (t))
               && is_really_empty_class (TREE_TYPE (t)))
@@ -4140,7 +4367,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
            new_ctx = *ctx;
            new_ctx.object = r;
            new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL);
-           CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = true;
+           CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
            new_ctx.values->put (r, new_ctx.ctor);
            ctx = &new_ctx;
          }
@@ -4166,6 +4393,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
        {
          if (!ctx->quiet)
            {
+             auto_diagnostic_group d;
              error ("temporary of non-literal type %qT in a "
                     "constant expression", TREE_TYPE (t));
              explain_non_literal_class (TREE_TYPE (t));
@@ -4180,7 +4408,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
             strips the TARGET_EXPR before we get here.  */
          new_ctx = *ctx;
          new_ctx.ctor = build_constructor (TREE_TYPE (t), NULL);
-         CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = true;
+         CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
          new_ctx.object = TARGET_EXPR_SLOT (t);
          ctx->values->put (new_ctx.object, new_ctx.ctor);
          ctx = &new_ctx;
@@ -4220,7 +4448,16 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
        r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
                                          lval,
                                          non_constant_p, overflow_p);
-      *jump_target = t;
+      if (jump_target)
+       *jump_target = t;
+      else
+       {
+         /* Can happen with ({ return true; }) && false; passed to
+            maybe_constant_value.  There is nothing to jump over in this
+            case, and the bug will be diagnosed later.  */
+         gcc_assert (ctx->quiet);
+         *non_constant_p = true;
+       }
       break;
 
     case SAVE_EXPR:
@@ -4307,6 +4544,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case FLOAT_EXPR:
     case NEGATE_EXPR:
     case ABS_EXPR:
+    case ABSU_EXPR:
     case BIT_NOT_EXPR:
     case TRUTH_NOT_EXPR:
     case FIXED_CONVERT_EXPR:
@@ -4461,15 +4699,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       break;
 
     case CONSTRUCTOR:
-      if (TREE_CONSTANT (t))
+      if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
        {
          /* Don't re-process a constant CONSTRUCTOR, but do fold it to
             VECTOR_CST if applicable.  */
-         /* FIXME after GCC 6 branches, make the verify unconditional.  */
-         if (CHECKING_P)
-           verify_constructor_flags (t);
-         else
-           recompute_constructor_flags (t);
+         verify_constructor_flags (t);
          if (TREE_CONSTANT (t))
            return fold (t);
        }
@@ -4487,15 +4721,23 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
                             non_constant_p, overflow_p);
       break;
 
-    case FMA_EXPR:
     case VEC_PERM_EXPR:
       r = cxx_eval_trinary_expression (ctx, t, lval,
                                       non_constant_p, overflow_p);
       break;
 
+    case NOP_EXPR:
+      if (REINTERPRET_CAST_P (t))
+       {
+         if (!ctx->quiet)
+           error_at (cp_expr_loc_or_loc (t, input_location),
+                     "a reinterpret_cast is not a constant expression");
+         *non_constant_p = true;
+         return t;
+       }
+      /* FALLTHROUGH.  */
     case CONVERT_EXPR:
     case VIEW_CONVERT_EXPR:
-    case NOP_EXPR:
     case UNARY_PLUS_EXPR:
       {
        tree oldop = TREE_OPERAND (t, 0);
@@ -4509,42 +4751,35 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
        if (TREE_CODE (op) == PTRMEM_CST
            && !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;
-             }
+           if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (op))
+               && !can_convert_qual (type, op))
+             op = cplus_expand_constant (op);
+           return cp_fold_convert (type, op);
          }
 
-       if (POINTER_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
+       if (INDIRECT_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
          {
            if (integer_zerop (op))
              {
-               if (TREE_CODE (type) == REFERENCE_TYPE)
+               if (TYPE_REF_P (type))
                  {
                    if (!ctx->quiet)
-                     error_at (EXPR_LOC_OR_LOC (t, input_location),
+                     error_at (cp_expr_loc_or_loc (t, input_location),
                                "dereferencing a null pointer");
                    *non_constant_p = true;
                    return t;
                  }
-               else if (TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
+               else if (TYPE_PTR_P (TREE_TYPE (op)))
                  {
                    tree from = TREE_TYPE (op);
 
                    if (!can_convert (type, from, tf_none))
                      {
                        if (!ctx->quiet)
-                         error_at (EXPR_LOC_OR_LOC (t, input_location),
+                         error_at (cp_expr_loc_or_loc (t, input_location),
                                    "conversion of %qT null pointer to %qT "
                                    "is not a constant expression",
                                    from, type);
@@ -4559,7 +4794,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
                     reinterpret_cast<void*>(sizeof 0)
                */
                if (!ctx->quiet)
-                 error_at (EXPR_LOC_OR_LOC (t, input_location),
+                 error_at (cp_expr_loc_or_loc (t, input_location),
                            "%<reinterpret_cast<%T>(%E)%> is not "
                            "a constant expression",
                            type, op);
@@ -4567,14 +4802,21 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
                return t;
              }
          }
+
        if (op == oldop && tcode != UNARY_PLUS_EXPR)
          /* We didn't fold at the top so we could check for ptr-int
             conversion.  */
          return fold (t);
-       if (tcode == UNARY_PLUS_EXPR)
+
+       /* Handle an array's bounds having been deduced after we built
+          the wrapping expression.  */
+       if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))
+         r = op;
+       else if (tcode == UNARY_PLUS_EXPR)
          r = fold_convert (TREE_TYPE (t), op);
        else
          r = fold_build1 (tcode, type, op);
+
        /* Conversion of an out-of-range value has implementation-defined
           behavior; the language considers it different from arithmetic
           overflow, which is undefined.  */
@@ -4616,16 +4858,47 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case MODOP_EXPR:
       /* GCC internal stuff.  */
     case VA_ARG_EXPR:
-    case OBJ_TYPE_REF:
     case NON_DEPENDENT_EXPR:
     case BASELINK:
     case OFFSET_REF:
       if (!ctx->quiet)
-        error_at (EXPR_LOC_OR_LOC (t, input_location),
+        error_at (cp_expr_loc_or_loc (t, input_location),
                  "expression %qE is not a constant expression", t);
       *non_constant_p = true;
       break;
 
+    case OBJ_TYPE_REF:
+      {
+       /* Virtual function call.  Let the constexpr machinery figure out
+          the dynamic type.  */
+       int token = tree_to_shwi (OBJ_TYPE_REF_TOKEN (t));
+       tree obj = OBJ_TYPE_REF_OBJECT (t);
+       obj = cxx_eval_constant_expression (ctx, obj, lval, non_constant_p,
+                                           overflow_p);
+       /* We expect something in the form of &x.D.2103.D.2094; get x. */
+       if (TREE_CODE (obj) != ADDR_EXPR
+           || !DECL_P (get_base_address (TREE_OPERAND (obj, 0))))
+         {
+           if (!ctx->quiet)
+             error_at (cp_expr_loc_or_loc (t, input_location),
+                       "expression %qE is not a constant expression", t);
+           *non_constant_p = true;
+           return t;
+         }
+       obj = TREE_OPERAND (obj, 0);
+       while (TREE_CODE (obj) == COMPONENT_REF
+              && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1)))
+         obj = TREE_OPERAND (obj, 0);
+       tree objtype = TREE_TYPE (obj);
+       /* Find the function decl in the virtual functions list.  TOKEN is
+          the DECL_VINDEX that says which function we're looking for.  */
+       tree virtuals = BINFO_VIRTUALS (TYPE_BINFO (objtype));
+       if (TARGET_VTABLE_USES_DESCRIPTORS)
+         token /= MAX (TARGET_VTABLE_USES_DESCRIPTORS, 1);
+       r = TREE_VALUE (chain_index (token, virtuals));
+       break;
+      }
+
     case PLACEHOLDER_EXPR:
       /* Use of the value or address of the current object.  */
       if (tree ctor = lookup_placeholder (ctx, lval, TREE_TYPE (t)))
@@ -4692,6 +4965,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
                                        jump_target);
       break;
 
+    case USING_STMT:
+      r = void_node;
+      break;
+
     default:
       if (STATEMENT_CODE_P (TREE_CODE (t)))
        {
@@ -4718,9 +4995,59 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     return r;
 }
 
+/* P0859: A function is needed for constant evaluation if it is a constexpr
+   function that is named by an expression ([basic.def.odr]) that is
+   potentially constant evaluated.
+
+   So we need to instantiate any constexpr functions mentioned by the
+   expression even if the definition isn't needed for evaluating the
+   expression.  */
+
+static tree
+instantiate_cx_fn_r (tree *tp, int *walk_subtrees, void */*data*/)
+{
+  if (TREE_CODE (*tp) == FUNCTION_DECL
+      && DECL_DECLARED_CONSTEXPR_P (*tp)
+      && !DECL_INITIAL (*tp)
+      && !trivial_fn_p (*tp)
+      && DECL_TEMPLOID_INSTANTIATION (*tp))
+    {
+      ++function_depth;
+      instantiate_decl (*tp, /*defer_ok*/false, /*expl_inst*/false);
+      --function_depth;
+    }
+  else if (TREE_CODE (*tp) == CALL_EXPR
+          || TREE_CODE (*tp) == AGGR_INIT_EXPR)
+    {
+      if (EXPR_HAS_LOCATION (*tp))
+       input_location = EXPR_LOCATION (*tp);
+    }
+
+  if (!EXPR_P (*tp))
+    *walk_subtrees = 0;
+
+  return NULL_TREE;
+}
+static void
+instantiate_constexpr_fns (tree t)
+{
+  location_t loc = input_location;
+  cp_walk_tree_without_duplicates (&t, instantiate_cx_fn_r, NULL);
+  input_location = loc;
+}
+
+/* ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
+   STRICT has the same sense as for constant_value_1: true if we only allow
+   conforming C++ constant expressions, or false if we want a constant value
+   even if it doesn't conform.
+   MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
+   per P0595 even when ALLOW_NON_CONSTANT is true.  */
+
 static tree
 cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
-                                 bool strict = true, tree object = NULL_TREE)
+                                 bool strict = true,
+                                 bool manifestly_const_eval = false,
+                                 tree object = NULL_TREE)
 {
   auto_timevar time (TV_CONSTEXPR);
 
@@ -4729,7 +5056,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
   hash_map<tree,tree> map;
 
   constexpr_ctx ctx = { NULL, &map, NULL, NULL, NULL, NULL,
-                       allow_non_constant, strict };
+                       allow_non_constant, strict,
+                       manifestly_const_eval || !allow_non_constant };
 
   tree type = initialized_type (t);
   tree r = t;
@@ -4743,7 +5071,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
         for C++11 constexpr constructors that refer to the object being
         initialized.  */
       ctx.ctor = build_constructor (type, NULL);
-      CONSTRUCTOR_NO_IMPLICIT_ZERO (ctx.ctor) = true;
+      CONSTRUCTOR_NO_CLEARING (ctx.ctor) = true;
       if (!object)
        {
          if (TREE_CODE (t) == TARGET_EXPR)
@@ -4763,6 +5091,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
        r = TARGET_EXPR_INITIAL (r);
     }
 
+  instantiate_constexpr_fns (r);
   r = cxx_eval_constant_expression (&ctx, r,
                                    false, &non_constant_p, &overflow_p);
 
@@ -4781,7 +5110,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
     }
 
   if (TREE_CODE (r) == CONSTRUCTOR
-      && CONSTRUCTOR_NO_IMPLICIT_ZERO (r))
+      && CONSTRUCTOR_NO_CLEARING (r))
     {
       if (!allow_non_constant)
        error ("%qE is not a constant expression because it refers to "
@@ -4817,8 +5146,18 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
     return error_mark_node;
   else if (non_constant_p && TREE_CONSTANT (r))
     {
-      /* This isn't actually constant, so unset TREE_CONSTANT.  */
-      if (EXPR_P (r))
+      /* If __builtin_is_constant_evaluated () was evaluated to true
+        and the result is not a valid constant expression, we need to
+        punt.  */
+      if (manifestly_const_eval)
+       return cxx_eval_outermost_constant_expr (t, true, strict,
+                                                false, object);
+      /* This isn't actually constant, so unset TREE_CONSTANT.
+        Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires
+        it to be set if it is invariant address, even when it is not
+        a valid C++ constant expression.  Wrap it with a NOP_EXPR
+        instead.  */
+      if (EXPR_P (r) && TREE_CODE (r) != ADDR_EXPR)
        r = copy_node (r);
       else if (TREE_CODE (r) == CONSTRUCTOR)
        r = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (r), r);
@@ -4826,7 +5165,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
        r = build_nop (TREE_TYPE (r), r);
       TREE_CONSTANT (r) = false;
     }
-  else if (non_constant_p || r == t)
+  else if (non_constant_p)
     return t;
 
   if (should_unshare)
@@ -4834,18 +5173,18 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
 
   if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
     {
+      r = adjust_temp_type (type, r);
       if (TREE_CODE (t) == TARGET_EXPR
          && TARGET_EXPR_INITIAL (t) == r)
        return t;
-      else
+      else if (TREE_CODE (t) != CONSTRUCTOR)
        {
          r = get_target_expr (r);
          TREE_CONSTANT (r) = true;
-         return r;
        }
     }
-  else
-    return r;
+
+  return r;
 }
 
 /* Returns true if T is a valid subexpression of a constant expression,
@@ -4858,8 +5197,10 @@ is_sub_constant_expr (tree t)
   bool overflow_p = false;
   hash_map <tree, tree> map;
 
-  constexpr_ctx ctx = { NULL, &map, NULL, NULL, NULL, NULL, true, true };
+  constexpr_ctx ctx
+    = { NULL, &map, NULL, NULL, NULL, NULL, true, true, false };
 
+  instantiate_constexpr_fns (t);
   cxx_eval_constant_expression (&ctx, t, false, &non_constant_p,
                                &overflow_p);
   return !non_constant_p && !overflow_p;
@@ -4872,7 +5213,7 @@ is_sub_constant_expr (tree t)
 tree
 cxx_constant_value (tree t, tree decl)
 {
-  return cxx_eval_outermost_constant_expr (t, false, true, decl);
+  return cxx_eval_outermost_constant_expr (t, false, true, true, decl);
 }
 
 /* Helper routine for fold_simple function.  Either return simplified
@@ -4900,6 +5241,7 @@ fold_simple_1 (tree t)
       return fold_sizeof_expr (t);
 
     case ABS_EXPR:
+    case ABSU_EXPR:
     case CONJ_EXPR:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
@@ -4950,12 +5292,14 @@ fold_simple (tree t)
 
 /* If T is a constant expression, returns its reduced value.
    Otherwise, if T does not have TREE_CONSTANT set, returns T.
-   Otherwise, returns a version of T without TREE_CONSTANT.  */
+   Otherwise, returns a version of T without TREE_CONSTANT.
+   MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated
+   as per P0595.  */
 
 static GTY((deletable)) hash_map<tree, tree> *cv_cache;
 
 tree
-maybe_constant_value (tree t, tree decl)
+maybe_constant_value (tree t, tree decl, bool manifestly_const_eval)
 {
   tree r;
 
@@ -4972,12 +5316,15 @@ maybe_constant_value (tree t, tree decl)
     /* No caching or evaluation needed.  */
     return t;
 
+  if (manifestly_const_eval)
+    return cxx_eval_outermost_constant_expr (t, true, true, true, decl);
+
   if (cv_cache == NULL)
     cv_cache = hash_map<tree, tree>::create_ggc (101);
   if (tree *cached = cv_cache->get (t))
     return *cached;
 
-  r = cxx_eval_outermost_constant_expr (t, true, true, decl);
+  r = cxx_eval_outermost_constant_expr (t, true, true, false, decl);
   gcc_checking_assert (r == t
                       || CONVERT_EXPR_P (t)
                       || TREE_CODE (t) == VIEW_CONVERT_EXPR
@@ -5008,12 +5355,22 @@ clear_cv_and_fold_caches (void)
 /* Like maybe_constant_value but first fully instantiate the argument.
 
    Note: this is equivalent to instantiate_non_dependent_expr_sfinae
-   (t, tf_none) followed by maybe_constant_value but is more efficient,
-   because calls instantiation_dependent_expression_p and
-   potential_constant_expression at most once.  */
+   (t, complain) followed by maybe_constant_value but is more efficient,
+   because it calls instantiation_dependent_expression_p and
+   potential_constant_expression at most once.
+   The manifestly_const_eval argument is passed to maybe_constant_value.
+
+   Callers should generally pass their active complain, or if they are in a
+   non-template, diagnosing context, they can use the default of
+   tf_warning_or_error.  Callers that might be within a template context, don't
+   have a complain parameter, and aren't going to remember the result for long
+   (e.g. null_ptr_cst_p), can pass tf_none and deal with error_mark_node
+   appropriately.  */
 
 tree
-fold_non_dependent_expr (tree t)
+fold_non_dependent_expr (tree t,
+                        tsubst_flags_t complain /* = tf_warning_or_error */,
+                        bool manifestly_const_eval /* = false */)
 {
   if (t == NULL_TREE)
     return NULL_TREE;
@@ -5030,7 +5387,7 @@ fold_non_dependent_expr (tree t)
       if (is_nondependent_constant_expression (t))
        {
          processing_template_decl_sentinel s;
-         t = instantiate_non_dependent_expr_internal (t, tf_none);
+         t = instantiate_non_dependent_expr_internal (t, complain);
 
          if (type_unknown_p (t)
              || BRACE_ENCLOSED_INITIALIZER_P (t))
@@ -5043,7 +5400,9 @@ fold_non_dependent_expr (tree t)
              return t;
            }
 
-         tree r = cxx_eval_outermost_constant_expr (t, true, true, NULL_TREE);
+         tree r = cxx_eval_outermost_constant_expr (t, true, true,
+                                                    manifestly_const_eval,
+                                                    NULL_TREE);
          /* cp_tree_equal looks through NOPs, so allow them.  */
          gcc_checking_assert (r == t
                               || CONVERT_EXPR_P (t)
@@ -5060,14 +5419,18 @@ fold_non_dependent_expr (tree t)
       return t;
     }
 
-  return maybe_constant_value (t);
+  return maybe_constant_value (t, NULL_TREE, manifestly_const_eval);
 }
 
 /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
-   than wrapped in a TARGET_EXPR.  */
+   than wrapped in a TARGET_EXPR.
+   ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
+   MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
+   per P0595 even when ALLOW_NON_CONSTANT is true.  */
 
-tree
-maybe_constant_init (tree t, tree decl)
+static tree
+maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
+                      bool manifestly_const_eval)
 {
   if (!t)
     return t;
@@ -5082,10 +5445,12 @@ maybe_constant_init (tree t, tree decl)
     t = TARGET_EXPR_INITIAL (t);
   if (!is_nondependent_static_init_expression (t))
     /* Don't try to evaluate it.  */;
-  else if (CONSTANT_CLASS_P (t))
+  else if (CONSTANT_CLASS_P (t) && allow_non_constant)
     /* No evaluation needed.  */;
   else
-    t = cxx_eval_outermost_constant_expr (t, true, false, decl);
+    t = cxx_eval_outermost_constant_expr (t, allow_non_constant,
+                                         /*strict*/false,
+                                         manifestly_const_eval, decl);
   if (TREE_CODE (t) == TARGET_EXPR)
     {
       tree init = TARGET_EXPR_INITIAL (t);
@@ -5095,6 +5460,22 @@ maybe_constant_init (tree t, tree decl)
   return t;
 }
 
+/* Wrapper for maybe_constant_init_1 which permits non constants.  */
+
+tree
+maybe_constant_init (tree t, tree decl, bool manifestly_const_eval)
+{
+  return maybe_constant_init_1 (t, decl, true, manifestly_const_eval);
+}
+
+/* Wrapper for maybe_constant_init_1 which does not permit non constants.  */
+
+tree
+cxx_constant_init (tree t, tree decl)
+{
+  return maybe_constant_init_1 (t, decl, false, true);
+}
+
 #if 0
 /* FIXME see ADDR_EXPR section in potential_constant_expression_1.  */
 /* Return true if the object referred to by REF has automatic or thread
@@ -5142,10 +5523,10 @@ check_automatic_or_tls (tree ref)
 
 static bool
 potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
-                                tsubst_flags_t flags)
+                                tsubst_flags_t flags, tree *jump_target)
 {
 #define RECUR(T,RV) \
-  potential_constant_expression_1 ((T), (RV), strict, now, flags)
+  potential_constant_expression_1 ((T), (RV), strict, now, flags, jump_target)
 
   enum { any = false, rval = true };
   int i;
@@ -5155,11 +5536,20 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
     return false;
   if (t == NULL_TREE)
     return true;
-  location_t loc = EXPR_LOC_OR_LOC (t, input_location);
-  if (TREE_THIS_VOLATILE (t) && !DECL_P (t))
+  location_t loc = cp_expr_loc_or_loc (t, input_location);
+
+  if (*jump_target)
+    /* If we are jumping, ignore everything.  This is simpler than the
+       cxx_eval_constant_expression handling because we only need to be
+       conservatively correct, and we don't necessarily have a constant value
+       available, so we don't bother with switch tracking.  */
+    return true;
+
+  if (TREE_THIS_VOLATILE (t) && want_rval)
     {
       if (flags & tf_error)
-        error_at (loc, "expression %qE has side-effects", t);
+       error_at (loc, "lvalue-to-rvalue conversion of a volatile lvalue "
+                 "%qE with type %qT", t, TREE_TYPE (t));
       return false;
     }
   if (CONSTANT_CLASS_P (t))
@@ -5193,13 +5583,21 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
     case USING_DECL:
     case USING_STMT:
     case PLACEHOLDER_EXPR:
-    case BREAK_STMT:
-    case CONTINUE_STMT:
     case REQUIRES_EXPR:
     case STATIC_ASSERT:
     case DEBUG_BEGIN_STMT:
       return true;
 
+    case RETURN_EXPR:
+      if (!RECUR (TREE_OPERAND (t, 0), any))
+       return false;
+      /* FALLTHROUGH */
+
+    case BREAK_STMT:
+    case CONTINUE_STMT:
+      *jump_target = t;
+      return true;
+
     case PARM_DECL:
       if (now)
        {
@@ -5240,7 +5638,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
                case IFN_SUB_OVERFLOW:
                case IFN_MUL_OVERFLOW:
                case IFN_LAUNDER:
+               case IFN_VEC_CONVERT:
                  bail = false;
+                 break;
 
                default:
                  break;
@@ -5264,7 +5664,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
                if (!DECL_DECLARED_CONSTEXPR_P (fun)
                    /* Allow any built-in function; if the expansion
                       isn't constant, we'll deal with that then.  */
-                   && !is_builtin_fn (fun))
+                   && !fndecl_built_in_p (fun))
                  {
                    if (flags & tf_error)
                      {
@@ -5288,7 +5688,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
                       constexpr substitution might not use the value.  */
                    bool sub_now = false;
                    if (!potential_constant_expression_1 (x, rval, strict,
-                                                         sub_now, flags))
+                                                         sub_now, flags,
+                                                         jump_target))
                      return false;
                    i = 1;
                  }
@@ -5322,7 +5723,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
               substitution might not use the value of the argument.  */
            bool sub_now = false;
            if (!potential_constant_expression_1 (x, rv, strict,
-                                                 sub_now, flags))
+                                                 sub_now, flags, jump_target))
              return false;
           }
         return true;
@@ -5384,13 +5785,18 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
         may change to something more specific to type-punning (DR 1312).  */
       {
         tree from = TREE_OPERAND (t, 0);
-       if (POINTER_TYPE_P (TREE_TYPE (t))
-           && TREE_CODE (from) == INTEGER_CST
-           && !integer_zerop (from))
+       if (location_wrapper_p (t))
+         return (RECUR (from, want_rval));
+       if (INDIRECT_TYPE_P (TREE_TYPE (t)))
          {
-           if (flags & tf_error)
-             error_at (loc, "reinterpret_cast from integer to pointer");
-           return false;
+           STRIP_ANY_LOCATION_WRAPPER (from);
+           if (TREE_CODE (from) == INTEGER_CST
+               && !integer_zerop (from))
+             {
+               if (flags & tf_error)
+                 error_at (loc, "reinterpret_cast from integer to pointer");
+               return false;
+             }
          }
         return (RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR));
       }
@@ -5497,31 +5903,57 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
        return false;
       if (!RECUR (DO_BODY (t), any))
        return false;
+      if (breaks (jump_target) || continues (jump_target))
+       *jump_target = NULL_TREE;
       return true;
 
     case FOR_STMT:
       if (!RECUR (FOR_INIT_STMT (t), any))
        return false;
-      if (!RECUR (FOR_COND (t), rval))
+      tmp = FOR_COND (t);
+      if (!RECUR (tmp, rval))
        return false;
+      if (tmp)
+       {
+         if (!processing_template_decl)
+           tmp = cxx_eval_outermost_constant_expr (tmp, true);
+         /* If we couldn't evaluate the condition, it might not ever be
+            true.  */
+         if (!integer_onep (tmp))
+           return true;
+       }
       if (!RECUR (FOR_EXPR (t), any))
        return false;
       if (!RECUR (FOR_BODY (t), any))
        return false;
+      if (breaks (jump_target) || continues (jump_target))
+       *jump_target = NULL_TREE;
       return true;
 
     case RANGE_FOR_STMT:
+      if (!RECUR (RANGE_FOR_INIT_STMT (t), any))
+       return false;
       if (!RECUR (RANGE_FOR_EXPR (t), any))
        return false;
       if (!RECUR (RANGE_FOR_BODY (t), any))
        return false;
+      if (breaks (jump_target) || continues (jump_target))
+       *jump_target = NULL_TREE;
       return true;
 
     case WHILE_STMT:
-      if (!RECUR (WHILE_COND (t), rval))
+      tmp = WHILE_COND (t);
+      if (!RECUR (tmp, rval))
        return false;
+      if (!processing_template_decl)
+       tmp = cxx_eval_outermost_constant_expr (tmp, true);
+      /* If we couldn't evaluate the condition, it might not ever be true.  */
+      if (!integer_onep (tmp))
+       return true;
       if (!RECUR (WHILE_BODY (t), any))
        return false;
+      if (breaks (jump_target) || continues (jump_target))
+       *jump_target = NULL_TREE;
       return true;
 
     case SWITCH_STMT:
@@ -5553,6 +5985,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
     case OMP_PARALLEL:
     case OMP_TASK:
     case OMP_FOR:
+    case OMP_SIMD:
     case OMP_DISTRIBUTE:
     case OMP_TASKLOOP:
     case OMP_TEAMS:
@@ -5572,6 +6005,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
     case OMP_ATOMIC_READ:
     case OMP_ATOMIC_CAPTURE_OLD:
     case OMP_ATOMIC_CAPTURE_NEW:
+    case OMP_DEPOBJ:
     case OACC_PARALLEL:
     case OACC_KERNELS:
     case OACC_DATA:
@@ -5584,7 +6018,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
     case OACC_UPDATE:
       /* GCC internal stuff.  */
     case VA_ARG_EXPR:
-    case OBJ_TYPE_REF:
     case TRANSACTION_EXPR:
     case ASM_EXPR:
     case AT_ENCODE_EXPR:
@@ -5593,6 +6026,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
        error_at (loc, "expression %qE is not a constant expression", t);
       return false;
 
+    case OBJ_TYPE_REF:
+      if (cxx_dialect >= cxx2a)
+       /* In C++2a virtual calls can be constexpr, don't give up yet.  */
+       return true;
+      else if (flags & tf_error)
+       error_at (loc, "virtual functions cannot be constexpr before C++2a");
+      return false;
+
     case TYPEID_EXPR:
       /* -- a typeid expression whose operand is of polymorphic
             class type;  */
@@ -5643,6 +6084,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
     case FLOAT_EXPR:
     case NEGATE_EXPR:
     case ABS_EXPR:
+    case ABSU_EXPR:
     case TRUTH_NOT_EXPR:
     case FIXED_CONVERT_EXPR:
     case UNARY_PLUS_EXPR:
@@ -5668,9 +6110,28 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
                      TREE_TYPE (t));
          return false;
        }
+      /* This might be a conversion from a class to a (potentially) literal
+        type.  Let's consider it potentially constant since the conversion
+        might be a constexpr user-defined conversion.  */
+      else if (cxx_dialect >= cxx11
+              && (dependent_type_p (TREE_TYPE (t))
+                  || !COMPLETE_TYPE_P (TREE_TYPE (t))
+                  || literal_type_p (TREE_TYPE (t)))
+              && TREE_OPERAND (t, 0))
+       {
+         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
+         /* If this is a dependent type, it could end up being a class
+            with conversions.  */
+         if (type == NULL_TREE || WILDCARD_TYPE_P (type))
+           return true;
+         /* Or a non-dependent class which has conversions.  */
+         else if (CLASS_TYPE_P (type)
+                  && (TYPE_HAS_CONVERSION (type) || dependent_scope_p (type)))
+           return true;
+       }
 
       return (RECUR (TREE_OPERAND (t, 0),
-                    TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE));
+                    !TYPE_REF_P (TREE_TYPE (t))));
 
     case BIND_EXPR:
       return RECUR (BIND_EXPR_BODY (t), want_rval);
@@ -5684,7 +6145,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
     case PAREN_EXPR:
     case NON_DEPENDENT_EXPR:
       /* For convenience.  */
-    case RETURN_EXPR:
     case LOOP_EXPR:
     case EXIT_EXPR:
       return RECUR (TREE_OPERAND (t, 0), want_rval);
@@ -5726,6 +6186,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
        {
          if (flags & tf_error)
            {
+             auto_diagnostic_group d;
              error_at (loc, "temporary of non-literal type %qT in a "
                        "constant expression", TREE_TYPE (t));
              explain_non_literal_class (TREE_TYPE (t));
@@ -5863,7 +6324,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
          return false;
       return true;
 
-    case FMA_EXPR:
     case VEC_PERM_EXPR:
      for (i = 0; i < 3; ++i)
       if (!RECUR (TREE_OPERAND (t, i), true))
@@ -5894,7 +6354,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
        return RECUR (TREE_OPERAND (t, 1), want_rval);
       for (i = 1; i < 3; ++i)
        if (potential_constant_expression_1 (TREE_OPERAND (t, i),
-                                            want_rval, strict, now, tf_none))
+                                            want_rval, strict, now,
+                                            tf_none, jump_target))
          return true;
       if (flags & tf_error)
        error_at (loc, "expression %qE is not a constant expression", t);
@@ -5925,7 +6386,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
        tree *target = &TREE_OPERAND (t, 0);
        /* Gotos representing break and continue are OK.  */
        if (breaks (target) || continues (target))
-         return true;
+         {
+           *jump_target = *target;
+           return true;
+         }
        if (flags & tf_error)
          error_at (loc, "%<goto%> is not a constant expression");
        return false;
@@ -5945,6 +6409,15 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 #undef RECUR
 }
 
+bool
+potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
+                                tsubst_flags_t flags)
+{
+  tree target = NULL_TREE;
+  return potential_constant_expression_1 (t, want_rval, strict, now,
+                                         flags, &target);
+}
+
 /* The main entry point to the above.  */
 
 bool
@@ -5966,7 +6439,8 @@ potential_rvalue_constant_expression (tree t)
 bool
 require_potential_constant_expression (tree t)
 {
-  return potential_constant_expression_1 (t, false, true, false, tf_warning_or_error);
+  return potential_constant_expression_1 (t, false, true, false,
+                                         tf_warning_or_error);
 }
 
 /* Cross product of the above.  */
@@ -5974,7 +6448,17 @@ require_potential_constant_expression (tree t)
 bool
 require_potential_rvalue_constant_expression (tree t)
 {
-  return potential_constant_expression_1 (t, true, true, false, tf_warning_or_error);
+  return potential_constant_expression_1 (t, true, true, false,
+                                         tf_warning_or_error);
+}
+
+/* Like above, but don't consider PARM_DECL a potential_constant_expression.  */
+
+bool
+require_rvalue_constant_expression (tree t)
+{
+  return potential_constant_expression_1 (t, true, true, true,
+                                         tf_warning_or_error);
 }
 
 /* Like potential_constant_expression, but don't consider possible constexpr