OSDN Git Service

PR c++/57047
[pf3gnuchains/gcc-fork.git] / gcc / cp / semantics.c
index 84f112c..e0c1c1f 100644 (file)
@@ -4,7 +4,7 @@
    and during the instantiation of template functions.
 
    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-                2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+                2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
    Written by Mark Mitchell (mmitchell@usa.net) based on code found
    formerly in parse.y and pt.c.
 
@@ -33,7 +33,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-common.h"
 #include "c-family/c-objc.h"
 #include "tree-inline.h"
-#include "tree-mudflap.h"
 #include "intl.h"
 #include "toplev.h"
 #include "flags.h"
@@ -995,6 +994,15 @@ finish_range_for_decl (tree range_for_stmt, tree decl, tree expr)
 tree
 finish_break_stmt (void)
 {
+  /* In switch statements break is sometimes stylistically used after
+     a return statement.  This can lead to spurious warnings about
+     control reaching the end of a non-void function when it is
+     inlined.  Note that we are calling block_may_fallthru with
+     language specific tree nodes; this works because
+     block_may_fallthru returns true when given something it does not
+     understand.  */
+  if (!block_may_fallthru (cur_stmt_list))
+    return void_zero_node;
   return add_stmt (build_stmt (input_location, BREAK_STMT));
 }
 
@@ -1562,9 +1570,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
       else
        {
          /* Set the cv qualifiers.  */
-         int quals = (current_class_ref
-                      ? cp_type_quals (TREE_TYPE (current_class_ref))
-                      : TYPE_UNQUALIFIED);
+         int quals = cp_type_quals (TREE_TYPE (object));
 
          if (DECL_MUTABLE_P (decl))
            quals &= ~TYPE_QUAL_CONST;
@@ -2369,8 +2375,9 @@ finish_compound_literal (tree type, tree compound_literal,
       && check_array_initializer (NULL_TREE, type, compound_literal))
     return error_mark_node;
   compound_literal = reshape_init (type, compound_literal, complain);
-  if (cxx_dialect >= cxx0x && SCALAR_TYPE_P (type)
-      && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal))
+  if (SCALAR_TYPE_P (type)
+      && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal)
+      && (complain & tf_warning_or_error))
     check_narrowing (type, compound_literal);
   if (TREE_CODE (type) == ARRAY_TYPE
       && TYPE_DOMAIN (type) == NULL_TREE)
@@ -2506,7 +2513,7 @@ check_template_template_default_arg (tree argument)
 /* Begin a class definition, as indicated by T.  */
 
 tree
-begin_class_definition (tree t, tree attributes)
+begin_class_definition (tree t)
 {
   if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t)))
     return error_mark_node;
@@ -2563,9 +2570,6 @@ begin_class_definition (tree t, tree attributes)
   pushclass (t);
   TYPE_BEING_DEFINED (t) = 1;
 
-  cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
-  fixup_attribute_variants (t);
-
   if (flag_pack_struct)
     {
       tree v;
@@ -2658,9 +2662,15 @@ finish_member_declaration (tree decl)
        }
     }
   /* Enter the DECL into the scope of the class.  */
-  else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
-          || pushdecl_class_level (decl))
+  else if (pushdecl_class_level (decl))
     {
+      if (TREE_CODE (decl) == USING_DECL)
+       {
+         /* For now, ignore class-scope USING_DECLS, so that
+            debugging backends do not see them. */
+         DECL_IGNORED_P (decl) = 1;
+       }
+
       /* All TYPE_DECLs go at the end of TYPE_FIELDS.  Ordinary fields
         go at the beginning.  The reason is that lookup_field_1
         searches the list in order, and we want a field name to
@@ -2733,15 +2743,17 @@ finish_template_decl (tree parms)
 tree
 finish_template_type (tree name, tree args, int entering_scope)
 {
-  tree decl;
+  tree type;
 
-  decl = lookup_template_class (name, args,
+  type = lookup_template_class (name, args,
                                NULL_TREE, NULL_TREE, entering_scope,
                                tf_warning_or_error | tf_user);
-  if (decl != error_mark_node)
-    decl = TYPE_STUB_DECL (decl);
-
-  return decl;
+  if (type == error_mark_node)
+    return type;
+  else if (CLASS_TYPE_P (type) && !alias_type_or_template_p (type))
+    return TYPE_STUB_DECL (type);
+  else
+    return TYPE_NAME (type);
 }
 
 /* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER.
@@ -2790,39 +2802,44 @@ finish_base_specifier (tree base, tree access, bool virtual_p)
 tree
 baselink_for_fns (tree fns)
 {
-  tree fn;
+  tree scope;
   tree cl;
 
   if (BASELINK_P (fns) 
       || error_operand_p (fns))
     return fns;
-  
-  fn = fns;
-  if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
-    fn = TREE_OPERAND (fn, 0);
-  fn = get_first_fn (fn);
-  if (!DECL_FUNCTION_MEMBER_P (fn))
+
+  scope = ovl_scope (fns);
+  if (!CLASS_TYPE_P (scope))
     return fns;
 
-  cl = currently_open_derived_class (DECL_CONTEXT (fn));
+  cl = currently_open_derived_class (scope);
   if (!cl)
-    cl = DECL_CONTEXT (fn);
+    cl = scope;
   cl = TYPE_BINFO (cl);
   return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE);
 }
 
-/* Returns true iff DECL is an automatic variable from a function outside
+/* Returns true iff DECL is a variable from a function outside
    the current one.  */
 
 static bool
-outer_automatic_var_p (tree decl)
+outer_var_p (tree decl)
 {
   return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
          && DECL_FUNCTION_SCOPE_P (decl)
-         && !TREE_STATIC (decl)
          && DECL_CONTEXT (decl) != current_function_decl);
 }
 
+/* As above, but also checks that DECL is automatic.  */
+
+static bool
+outer_automatic_var_p (tree decl)
+{
+  return (outer_var_p (decl)
+         && !TREE_STATIC (decl));
+}
+
 /* ID_EXPRESSION is a representation of parsed, but unprocessed,
    id-expression.  (See cp_parser_id_expression for details.)  SCOPE,
    if non-NULL, is the type or namespace used to explicitly qualify
@@ -2871,6 +2888,8 @@ finish_id_expression (tree id_expression,
                      const char **error_msg,
                      location_t location)
 {
+  decl = strip_using_decl (decl);
+
   /* Initialize the output parameters.  */
   *idk = CP_ID_KIND_NONE;
   *error_msg = NULL;
@@ -2927,9 +2946,18 @@ finish_id_expression (tree id_expression,
 
       /* Disallow uses of local variables from containing functions, except
         within lambda-expressions.  */
-      if (outer_automatic_var_p (decl)
+      if (!outer_var_p (decl)
          /* It's not a use (3.2) if we're in an unevaluated context.  */
-         && !cp_unevaluated_operand)
+         || cp_unevaluated_operand)
+       /* OK.  */;
+      else if (TREE_STATIC (decl))
+       {
+         if (processing_template_decl)
+           /* For a use of an outer static var, return the identifier so
+              that we'll look it up again in the instantiation.  */
+           return id_expression;
+       }
+      else
        {
          tree context = DECL_CONTEXT (decl);
          tree containing_function = current_function_decl;
@@ -2948,7 +2976,14 @@ finish_id_expression (tree id_expression,
 
             FIXME update for final resolution of core issue 696.  */
          if (decl_constant_var_p (decl))
-           return integral_constant_value (decl);
+           {
+             if (processing_template_decl)
+               /* In a template, the constant value may not be in a usable
+                  form, so look it up again at instantiation time.  */
+               return id_expression;
+             else
+               return integral_constant_value (decl);
+           }
 
          /* If we are in a lambda function, we can move out until we hit
             1. the context,
@@ -3286,8 +3321,9 @@ finish_id_expression (tree id_expression,
          if (TREE_CODE (first_fn) == TEMPLATE_DECL)
            first_fn = DECL_TEMPLATE_RESULT (first_fn);
 
-         if (!really_overloaded_fn (decl))
-           mark_used (first_fn);
+         if (!really_overloaded_fn (decl)
+             && !mark_used (first_fn))
+           return error_mark_node;
 
          if (!template_arg_p
              && TREE_CODE (first_fn) == FUNCTION_DECL
@@ -3378,7 +3414,7 @@ finish_underlying_type (tree type)
 
   if (TREE_CODE (type) != ENUMERAL_TYPE)
     {
-      error ("%qE is not an enumeration type", type);
+      error ("%qT is not an enumeration type", type);
       return error_mark_node;
     }
 
@@ -3568,7 +3604,7 @@ finish_offsetof (tree expr)
       if (!complete_type_or_else (TREE_TYPE (object), object))
        return error_mark_node;
     }
-  return fold_offsetof (expr, NULL_TREE);
+  return fold_offsetof (expr);
 }
 
 /* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR.  This
@@ -4041,6 +4077,8 @@ finish_omp_clauses (tree clauses)
          t = maybe_convert_cond (t);
          if (t == error_mark_node)
            remove = true;
+         else if (!processing_template_decl)
+           t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
          OMP_CLAUSE_IF_EXPR (c) = t;
          break;
 
@@ -4049,6 +4087,8 @@ finish_omp_clauses (tree clauses)
          t = maybe_convert_cond (t);
          if (t == error_mark_node)
            remove = true;
+         else if (!processing_template_decl)
+           t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
          OMP_CLAUSE_FINAL_EXPR (c) = t;
          break;
 
@@ -4062,6 +4102,13 @@ finish_omp_clauses (tree clauses)
              error ("num_threads expression must be integral");
              remove = true;
            }
+         else
+           {
+             t = mark_rvalue_use (t);
+             if (!processing_template_decl)
+               t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+             OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
+           }
          break;
 
        case OMP_CLAUSE_SCHEDULE:
@@ -4076,6 +4123,13 @@ finish_omp_clauses (tree clauses)
              error ("schedule chunk size expression must be integral");
              remove = true;
            }
+         else
+           {
+             t = mark_rvalue_use (t);
+             if (!processing_template_decl)
+               t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+             OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
+           }
          break;
 
        case OMP_CLAUSE_NOWAIT:
@@ -4965,6 +5019,84 @@ finish_omp_taskyield (void)
   finish_expr_stmt (stmt);
 }
 \f
+/* Begin a __transaction_atomic or __transaction_relaxed statement.
+   If PCOMPOUND is non-null, this is for a function-transaction-block, and we
+   should create an extra compound stmt.  */
+
+tree
+begin_transaction_stmt (location_t loc, tree *pcompound, int flags)
+{
+  tree r;
+
+  if (pcompound)
+    *pcompound = begin_compound_stmt (0);
+
+  r = build_stmt (loc, TRANSACTION_EXPR, NULL_TREE);
+
+  /* Only add the statement to the function if support enabled.  */
+  if (flag_tm)
+    add_stmt (r);
+  else
+    error_at (loc, ((flags & TM_STMT_ATTR_RELAXED) != 0
+                   ? G_("%<__transaction_relaxed%> without "
+                        "transactional memory support enabled")
+                   : G_("%<__transaction_atomic%> without "
+                        "transactional memory support enabled")));
+
+  TRANSACTION_EXPR_BODY (r) = push_stmt_list ();
+  return r;
+}
+
+/* End a __transaction_atomic or __transaction_relaxed statement.
+   If COMPOUND_STMT is non-null, this is for a function-transaction-block,
+   and we should end the compound.  If NOEX is non-NULL, we wrap the body in
+   a MUST_NOT_THROW_EXPR with NOEX as condition.  */
+
+void
+finish_transaction_stmt (tree stmt, tree compound_stmt, int flags, tree noex)
+{
+  TRANSACTION_EXPR_BODY (stmt) = pop_stmt_list (TRANSACTION_EXPR_BODY (stmt));
+  TRANSACTION_EXPR_OUTER (stmt) = (flags & TM_STMT_ATTR_OUTER) != 0;
+  TRANSACTION_EXPR_RELAXED (stmt) = (flags & TM_STMT_ATTR_RELAXED) != 0;
+  TRANSACTION_EXPR_IS_STMT (stmt) = 1;
+
+  /* noexcept specifications are not allowed for function transactions.  */
+  gcc_assert (!(noex && compound_stmt));
+  if (noex)
+    {
+      tree body = build_must_not_throw_expr (TRANSACTION_EXPR_BODY (stmt),
+                                            noex);
+      SET_EXPR_LOCATION (body, EXPR_LOCATION (TRANSACTION_EXPR_BODY (stmt)));
+      TREE_SIDE_EFFECTS (body) = 1;
+      TRANSACTION_EXPR_BODY (stmt) = body;
+    }
+
+  if (compound_stmt)
+    finish_compound_stmt (compound_stmt);
+  finish_stmt ();
+}
+
+/* Build a __transaction_atomic or __transaction_relaxed expression.  If
+   NOEX is non-NULL, we wrap the body in a MUST_NOT_THROW_EXPR with NOEX as
+   condition.  */
+
+tree
+build_transaction_expr (location_t loc, tree expr, int flags, tree noex)
+{
+  tree ret;
+  if (noex)
+    {
+      expr = build_must_not_throw_expr (expr, noex);
+      SET_EXPR_LOCATION (expr, loc);
+      TREE_SIDE_EFFECTS (expr) = 1;
+    }
+  ret = build1 (TRANSACTION_EXPR, TREE_TYPE (expr), expr);
+  if (flags & TM_STMT_ATTR_RELAXED)
+       TRANSACTION_EXPR_RELAXED (ret) = 1;
+  SET_EXPR_LOCATION (ret, loc);
+  return ret;
+}
+\f
 void
 init_cp_semantics (void)
 {
@@ -5019,7 +5151,7 @@ finish_static_assert (tree condition, tree message, location_t location,
       if (TREE_CODE (condition) == INTEGER_CST 
           && integer_zerop (condition))
         /* Report the error. */
-        error ("static assertion failed: %E", message);
+        error ("static assertion failed: %s", TREE_STRING_POINTER (message));
       else if (condition && condition != error_mark_node)
        {
          error ("non-constant condition for static assertion");
@@ -5115,7 +5247,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
            step.  */
         expr = TREE_OPERAND (expr, 1);
 
-      if (TREE_CODE (expr) == BASELINK)
+      if (BASELINK_P (expr))
         /* See through BASELINK nodes to the underlying function.  */
         expr = BASELINK_FUNCTIONS (expr);
 
@@ -5154,8 +5286,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
           gcc_unreachable ();
 
         case INTEGER_CST:
+       case PTRMEM_CST:
           /* We can get here when the id-expression refers to an
-             enumerator.  */
+             enumerator or non-type template parameter.  */
           type = TREE_TYPE (expr);
           break;
 
@@ -5240,6 +5373,7 @@ classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
       else if (copy_fn_p (fn) <= 0)
        continue;
 
+      maybe_instantiate_noexcept (fn);
       if (!TYPE_NOTHROW_P (TREE_TYPE (fn)))
        return false;
     }
@@ -5281,7 +5415,8 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
       return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2) 
              || (CLASS_TYPE_P (type1)
                  && (t = locate_ctor (type1))
-                 && TYPE_NOTHROW_P (TREE_TYPE (t))));
+                 && (maybe_instantiate_noexcept (t),
+                     TYPE_NOTHROW_P (TREE_TYPE (t)))));
 
     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
       type1 = strip_array_types (type1);
@@ -5330,6 +5465,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
     case CPTK_IS_ENUM:
       return (type_code1 == ENUMERAL_TYPE);
 
+    case CPTK_IS_FINAL:
+      return (CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1));
+
     case CPTK_IS_LITERAL_TYPE:
       return (literal_type_p (type1));
 
@@ -5389,6 +5527,7 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
              || kind == CPTK_IS_CONVERTIBLE_TO
              || kind == CPTK_IS_EMPTY
              || kind == CPTK_IS_ENUM
+             || kind == CPTK_IS_FINAL
              || kind == CPTK_IS_LITERAL_TYPE
              || kind == CPTK_IS_POD
              || kind == CPTK_IS_POLYMORPHIC
@@ -5429,6 +5568,7 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
     case CPTK_HAS_VIRTUAL_DESTRUCTOR:
     case CPTK_IS_ABSTRACT:
     case CPTK_IS_EMPTY:
+    case CPTK_IS_FINAL:
     case CPTK_IS_LITERAL_TYPE:
     case CPTK_IS_POD:
     case CPTK_IS_POLYMORPHIC:
@@ -5616,6 +5756,12 @@ is_valid_constexpr_fn (tree fun, bool complain)
            }
        }
     }
+  else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun)))
+    {
+      ret = false;
+      if (complain)
+       error ("%q#T has virtual base classes", DECL_CONTEXT (fun));
+    }
 
   return ret;
 }
@@ -5663,15 +5809,19 @@ build_data_member_initialization (tree t, VEC(constructor_elt,gc) **vec)
       member = TREE_OPERAND (t, 0);
       init = unshare_expr (TREE_OPERAND (t, 1));
     }
-  else
+  else if (TREE_CODE (t) == CALL_EXPR)
     {
-      gcc_assert (TREE_CODE (t) == CALL_EXPR);
       member = CALL_EXPR_ARG (t, 0);
       /* We don't use build_cplus_new here because it complains about
         abstract bases.  Leaving the call unwrapped means that it has the
         wrong type, but cxx_eval_constant_expression doesn't care.  */
       init = unshare_expr (t);
     }
+  else if (TREE_CODE (t) == DECL_EXPR)
+    /* Declaring a temporary, don't add it to the CONSTRUCTOR.  */
+    return true;
+  else
+    gcc_unreachable ();
   if (TREE_CODE (member) == INDIRECT_REF)
     member = TREE_OPERAND (member, 0);
   if (TREE_CODE (member) == NOP_EXPR)
@@ -5687,14 +5837,17 @@ build_data_member_initialization (tree t, VEC(constructor_elt,gc) **vec)
             the const_cast.  */
          member = op;
        }
+      else if (op == current_class_ptr
+              && (same_type_ignoring_top_level_qualifiers_p
+                  (TREE_TYPE (TREE_TYPE (member)),
+                   current_class_type)))
+       /* Delegating constructor.  */
+       member = op;
       else
        {
-         /* We don't put out anything for an empty base.  */
+         /* This is an initializer for an empty base; keep it for now so
+            we can check it in cxx_eval_bare_aggregate.  */
          gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
-         /* But if the initializer isn't constexpr, leave it in so we
-            complain later.  */
-         if (potential_constant_expression (init))
-           return true;
        }
     }
   if (TREE_CODE (member) == ADDR_EXPR)
@@ -5751,6 +5904,44 @@ check_constexpr_ctor_body (tree last, tree list)
   return ok;
 }
 
+/* VEC is a vector of constructor elements built up for the base and member
+   initializers of a constructor for TYPE.  They need to be in increasing
+   offset order, which they might not be yet if TYPE has a primary base
+   which is not first in the base-clause or a vptr and at least one base
+   all of which are non-primary.  */
+
+static VEC(constructor_elt,gc) *
+sort_constexpr_mem_initializers (tree type, VEC(constructor_elt,gc) *vec)
+{
+  tree pri = CLASSTYPE_PRIMARY_BINFO (type);
+  tree field_type;
+  constructor_elt elt;
+  int i;
+
+  if (pri)
+    field_type = BINFO_TYPE (pri);
+  else if (TYPE_CONTAINS_VPTR_P (type))
+    field_type = vtbl_ptr_type_node;
+  else
+    return vec;
+
+  /* Find the element for the primary base or vptr and move it to the
+     beginning of the vec.  */
+  for (i = 0; ; ++i)
+    if (TREE_TYPE (VEC_index (constructor_elt, vec, i)->index) == field_type)
+      break;
+
+  if (i > 0)
+    {
+      elt = *VEC_index (constructor_elt, vec, i);
+      for (; i > 0; --i)
+       VEC_replace (constructor_elt, vec, i,
+                    VEC_index (constructor_elt, vec, i-1));
+      VEC_replace (constructor_elt, vec, 0, &elt);
+    }
+  return vec;
+}
+
 /* Build compile-time evalable representations of member-initializer list
    for a constexpr constructor.  */
 
@@ -5790,10 +5981,26 @@ build_constexpr_constructor_member_initializers (tree type, tree body)
            break;
        }
     }
+  else if (EXPR_P (body))
+    ok = build_data_member_initialization (body, &vec);
   else
     gcc_assert (errorcount > 0);
   if (ok)
-    return build_constructor (type, vec);
+    {
+      if (VEC_length (constructor_elt, vec) > 0)
+       {
+         /* In a delegating constructor, return the target.  */
+         constructor_elt *ce = VEC_index (constructor_elt, vec, 0);
+         if (ce->index == current_class_ptr)
+           {
+             body = ce->value;
+             VEC_free (constructor_elt, gc, vec);
+             return body;
+           }
+       }
+      vec = sort_constexpr_mem_initializers (type, vec);
+      return build_constructor (type, vec);
+    }
   else
     return error_mark_node;
 }
@@ -5859,12 +6066,12 @@ massage_constexpr_body (tree fun, tree body)
       (DECL_CONTEXT (fun), body);
   else
     {
-      if (TREE_CODE (body) == BIND_EXPR)
-       body = BIND_EXPR_BODY (body);
       if (TREE_CODE (body) == EH_SPEC_BLOCK)
         body = EH_SPEC_STMTS (body);
       if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
        body = TREE_OPERAND (body, 0);
+      if (TREE_CODE (body) == BIND_EXPR)
+       body = BIND_EXPR_BODY (body);
       body = constexpr_fn_retval (body);
     }
   return body;
@@ -5879,13 +6086,28 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
   bool bad;
   tree field;
   unsigned i, nelts;
+  tree ctype;
 
   if (TREE_CODE (body) != CONSTRUCTOR)
     return false;
 
-  bad = false;
   nelts = CONSTRUCTOR_NELTS (body);
-  field = TYPE_FIELDS (DECL_CONTEXT (fun));
+  ctype = DECL_CONTEXT (fun);
+  field = TYPE_FIELDS (ctype);
+
+  if (TREE_CODE (ctype) == UNION_TYPE)
+    {
+      if (nelts == 0 && next_initializable_field (field))
+       {
+         if (complain)
+           error ("%<constexpr%> constructor for union %qT must "
+                  "initialize exactly one non-static data member", ctype);
+         return true;
+       }
+      return false;
+    }
+
+  bad = false;
   for (i = 0; i <= nelts; ++i)
     {
       tree index;
@@ -5895,26 +6117,29 @@ cx_check_missing_mem_inits (tree fun, tree body, bool complain)
        {
          index = CONSTRUCTOR_ELT (body, i)->index;
          /* Skip base and vtable inits.  */
-         if (TREE_CODE (index) != FIELD_DECL)
+         if (TREE_CODE (index) != FIELD_DECL
+             || DECL_ARTIFICIAL (index))
            continue;
        }
       for (; field != index; field = DECL_CHAIN (field))
        {
          tree ftype;
          if (TREE_CODE (field) != FIELD_DECL
-             || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)))
+             || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field))
+             || DECL_ARTIFICIAL (field))
            continue;
-         if (!complain)
-           return true;
          ftype = strip_array_types (TREE_TYPE (field));
          if (type_has_constexpr_default_constructor (ftype))
            {
              /* It's OK to skip a member with a trivial constexpr ctor.
                 A constexpr ctor that isn't trivial should have been
                 added in by now.  */
-             gcc_checking_assert (!TYPE_HAS_COMPLEX_DFLT (ftype));
+             gcc_checking_assert (!TYPE_HAS_COMPLEX_DFLT (ftype)
+                                  || errorcount != 0);
              continue;
            }
+         if (!complain)
+           return true;
          error ("uninitialized member %qD in %<constexpr%> constructor",
                 field);
          bad = true;
@@ -6422,7 +6647,7 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t,
   else
     {
       result = entry->result;
-      if (!result || (result == error_mark_node && !allow_non_constant))
+      if (!result || result == error_mark_node)
        result = (cxx_eval_constant_expression
                  (&new_call, new_call.fundef->body,
                   allow_non_constant, addr,
@@ -6680,6 +6905,12 @@ cxx_eval_component_reference (const constexpr_call *call, tree t,
        error ("%qE is not a constant expression", orig_whole);
       *non_constant_p = true;
     }
+  if (DECL_MUTABLE_P (part))
+    {
+      if (!allow_non_constant)
+       error ("mutable %qD is not usable in a constant expression", part);
+      *non_constant_p = true;
+    }
   if (*non_constant_p)
     return t;
   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
@@ -6872,6 +7103,12 @@ cxx_eval_bare_aggregate (const constexpr_call *call, tree t,
          constructor_elt *inner = base_field_constructor_elt (n, ce->index);
          inner->value = elt;
        }
+      else if (TREE_CODE (ce->index) == NOP_EXPR)
+       {
+         /* This is an initializer for an empty base; now that we've
+            checked that it's constant, we can ignore it.  */
+         gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (ce->index))));
+       }
       else
        CONSTRUCTOR_APPEND_ELT (n, ce->index, elt);
     }
@@ -6945,7 +7182,7 @@ cxx_eval_vec_init_1 (const constexpr_call *call, tree atype, tree init,
       if (TREE_CODE (elttype) == ARRAY_TYPE)
        {
          /* A multidimensional array; recurse.  */
-         if (value_init)
+         if (value_init || init == NULL_TREE)
            eltinit = NULL_TREE;
          else
            eltinit = cp_build_array_ref (input_location, init, idx,
@@ -7034,7 +7271,8 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
   sub = op0;
   STRIP_NOPS (sub);
   subtype = TREE_TYPE (sub);
-  gcc_assert (POINTER_TYPE_P (subtype));
+  if (!POINTER_TYPE_P (subtype))
+    return NULL_TREE;
 
   if (TREE_CODE (sub) == ADDR_EXPR)
     {
@@ -7174,15 +7412,17 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
            }
        }
     }
-  /* *(foo *)fooarrptreturn> (*fooarrptr)[0] */
+  /* *(foo *)fooarrptr => (*fooarrptr)[0] */
   else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
           && (same_type_ignoring_top_level_qualifiers_p
               (type, TREE_TYPE (TREE_TYPE (subtype)))))
     {
       tree type_domain;
       tree min_val = size_zero_node;
-      sub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL);
-      if (!sub)
+      tree newsub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL);
+      if (newsub)
+       sub = newsub;
+      else
        sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub);
       type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
       if (type_domain && TYPE_MIN_VALUE (type_domain))
@@ -7219,9 +7459,15 @@ cxx_eval_indirect_ref (const constexpr_call *call, tree t,
     {
       tree sub = op0;
       STRIP_NOPS (sub);
-      if (TREE_CODE (sub) == ADDR_EXPR
-         || TREE_CODE (sub) == POINTER_PLUS_EXPR)
+      if (TREE_CODE (sub) == POINTER_PLUS_EXPR)
        {
+         sub = TREE_OPERAND (sub, 0);
+         STRIP_NOPS (sub);
+       }
+      if (TREE_CODE (sub) == ADDR_EXPR)
+       {
+         /* We couldn't fold to a constant value.  Make sure it's not
+            something we should have been able to fold.  */
          gcc_assert (!same_type_ignoring_top_level_qualifiers_p
                      (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
          /* DR 1188 says we don't have to deal with this.  */
@@ -7245,7 +7491,11 @@ cxx_eval_indirect_ref (const constexpr_call *call, tree t,
     }
 
   if (r == NULL_TREE)
-    return t;
+    {
+      if (!addr)
+       VERIFY_CONSTANT (t);
+      return t;
+    }
   return r;
 }
 
@@ -7469,6 +7719,7 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
            /* Check that the LHS is constant and then discard it.  */
            cxx_eval_constant_expression (call, op0, allow_non_constant,
                                          false, non_constant_p);
+           op1 = TREE_OPERAND (t, 1);
            r = cxx_eval_constant_expression (call, op1, allow_non_constant,
                                              addr, non_constant_p);
          }
@@ -7578,17 +7829,6 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
        tree oldop = TREE_OPERAND (t, 0);
        tree op = oldop;
        tree to = TREE_TYPE (t);
-       tree source = TREE_TYPE (op);
-        if (TYPE_PTR_P (source) && ARITHMETIC_TYPE_P (to)
-           && !(TREE_CODE (op) == COMPONENT_REF
-                && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (op, 0)))))
-          {
-            if (!allow_non_constant)
-              error ("conversion of expression %qE of pointer type "
-                     "cannot yield a constant expression", op);
-           *non_constant_p = true;
-           return t;
-          }
        op = cxx_eval_constant_expression (call, TREE_OPERAND (t, 0),
                                           allow_non_constant, addr,
                                           non_constant_p);
@@ -7665,6 +7905,32 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant)
 
   verify_constant (r, allow_non_constant, &non_constant_p);
 
+  if (TREE_CODE (t) != CONSTRUCTOR
+      && cp_has_mutable_p (TREE_TYPE (t)))
+    {
+      /* We allow a mutable type if the original expression was a
+        CONSTRUCTOR so that we can do aggregate initialization of
+        constexpr variables.  */
+      if (!allow_non_constant)
+       error ("%qT cannot be the type of a complete constant expression "
+              "because it has mutable sub-objects", TREE_TYPE (t));
+      non_constant_p = true;
+    }
+
+  /* Technically we should check this for all subexpressions, but that
+     runs into problems with our internal representation of pointer
+     subtraction and the 5.19 rules are still in flux.  */
+  if (CONVERT_EXPR_CODE_P (TREE_CODE (r))
+      && ARITHMETIC_TYPE_P (TREE_TYPE (r))
+      && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
+    {
+      if (!allow_non_constant)
+       error ("conversion from pointer type %qT "
+              "to arithmetic type %qT in a constant-expression",
+              TREE_TYPE (TREE_OPERAND (r, 0)), TREE_TYPE (r));
+      non_constant_p = true;
+    }
+
   if (non_constant_p && !allow_non_constant)
     return error_mark_node;
   else if (non_constant_p && TREE_CONSTANT (t))
@@ -7865,6 +8131,7 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
     case TEMPLATE_PARM_INDEX:
     case TRAIT_EXPR:
     case IDENTIFIER_NODE:
+    case USERDEF_LITERAL:
       /* We can see a FIELD_DECL in a pointer-to-member expression.  */
     case FIELD_DECL:
     case PARM_DECL:
@@ -7971,25 +8238,10 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
     case NOP_EXPR:
     case CONVERT_EXPR:
     case VIEW_CONVERT_EXPR:
-      /* -- an array-to-pointer conversion that is applied to an lvalue
-            that designates an object with thread or automatic storage
-            duration;  FIXME not implemented as it breaks constexpr arrays;
-           need to fix the standard
-         -- a type conversion from a pointer or pointer-to-member type
-            to a literal type.  */
+      /* -- a reinterpret_cast.  FIXME not implemented, and this rule
+        may change to something more specific to type-punning (DR 1312).  */
       {
         tree from = TREE_OPERAND (t, 0);
-        tree source = TREE_TYPE (from);
-        tree target = TREE_TYPE (t);
-        if (TYPE_PTR_P (source) && ARITHMETIC_TYPE_P (target)
-           && !(TREE_CODE (from) == COMPONENT_REF
-                && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (from, 0)))))
-          {
-            if (flags & tf_error)
-              error ("conversion of expression %qE of pointer type "
-                     "cannot yield a constant expression", from);
-            return false;
-          }
         return (potential_constant_expression_1
                (from, TREE_CODE (t) != VIEW_CONVERT_EXPR, flags));
       }
@@ -8077,6 +8329,11 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
     case STMT_EXPR:
     case EXPR_STMT:
     case BIND_EXPR:
+    case TRANSACTION_EXPR:
+    case IF_STMT:
+    case DO_STMT:
+    case FOR_STMT:
+    case WHILE_STMT:
       if (flags & tf_error)
         error ("expression %qE is not a constant-expression", t);
       return false;
@@ -8286,6 +8543,7 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
     case UNGT_EXPR:
     case UNGE_EXPR:
     case UNEQ_EXPR:
+    case LTGT_EXPR:
     case RANGE_EXPR:
     case COMPLEX_EXPR:
       want_rval = true;
@@ -8494,7 +8752,9 @@ begin_lambda_type (tree lambda)
   xref_basetypes (type, /*bases=*/NULL_TREE);
 
   /* Start the class.  */
-  type = begin_class_definition (type, /*attributes=*/NULL_TREE);
+  type = begin_class_definition (type);
+  if (type == error_mark_node)
+    return error_mark_node;
 
   /* Cross-reference the expression and the type.  */
   LAMBDA_EXPR_CLOSURE (lambda) = type;
@@ -8540,7 +8800,8 @@ lambda_function (tree lambda)
       && !COMPLETE_OR_OPEN_TYPE_P (type))
     return NULL_TREE;
   lambda = lookup_member (type, ansi_opname (CALL_EXPR),
-                         /*protect=*/0, /*want_type=*/false);
+                         /*protect=*/0, /*want_type=*/false,
+                         tf_warning_or_error);
   if (lambda)
     lambda = BASELINK_FUNCTIONS (lambda);
   return lambda;
@@ -8554,7 +8815,8 @@ tree
 lambda_capture_field_type (tree expr)
 {
   tree type;
-  if (type_dependent_expression_p (expr))
+  if (type_dependent_expression_p (expr)
+      && !(TREE_TYPE (expr) && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE))
     {
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
@@ -8695,17 +8957,16 @@ is_normal_capture_proxy (tree decl)
 /* VAR is a capture proxy created by build_capture_proxy; add it to the
    current function, which is the operator() for the appropriate lambda.  */
 
-static inline void
+void
 insert_capture_proxy (tree var)
 {
   cp_binding_level *b;
-  int skip;
   tree stmt_list;
 
   /* Put the capture proxy in the extra body block so that it won't clash
      with a later local variable.  */
   b = current_binding_level;
-  for (skip = 0; ; ++skip)
+  for (;;)
     {
       cp_binding_level *n = b->level_chain;
       if (n->kind == sk_function_parms)
@@ -8716,8 +8977,7 @@ insert_capture_proxy (tree var)
 
   /* And put a DECL_EXPR in the STATEMENT_LIST for the same block.  */
   var = build_stmt (DECL_SOURCE_LOCATION (var), DECL_EXPR, var);
-  stmt_list = VEC_index (tree, stmt_list_stack,
-                        VEC_length (tree, stmt_list_stack) - 1 - skip);
+  stmt_list = VEC_index (tree, stmt_list_stack, 1);
   gcc_assert (stmt_list);
   append_to_statement_list_force (var, &stmt_list);
 }
@@ -8759,7 +9019,8 @@ lambda_proxy_type (tree ref)
   if (REFERENCE_REF_P (ref))
     ref = TREE_OPERAND (ref, 0);
   type = TREE_TYPE (ref);
-  if (!dependent_type_p (type))
+  if (!dependent_type_p (type)
+      || (type && TREE_CODE (type) == POINTER_TYPE))
     return type;
   type = cxx_make_type (DECLTYPE_TYPE);
   DECLTYPE_TYPE_EXPR (type) = ref;
@@ -9173,6 +9434,8 @@ maybe_add_lambda_conv_op (tree type)
   body = begin_function_body ();
   compound_stmt = begin_compound_stmt (0);
 
+  /* decl_needed_p needs to see that it's used.  */
+  TREE_USED (statfn) = 1;
   finish_return_stmt (decay_conversion (statfn));
 
   finish_compound_stmt (compound_stmt);