re PR c++/68464 (ICE in valid constexpr function: ../../src/gcc/tree.c:11497)
[gcc.git] / gcc / cp / decl.c
index ab55e75f27eab465a0270e4c24cc4870d3b4f8d3..62636c9eefaed72def3ec29d6b5950b0711ed0af 100644 (file)
@@ -29,38 +29,25 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "alias.h"
-#include "tree.h"
-#include "tree-hasher.h"
+#include "target.h"
+#include "c-family/c-target.h"
+#include "cp-tree.h"
+#include "timevar.h"
 #include "stringpool.h"
+#include "cgraph.h"
 #include "stor-layout.h"
 #include "varasm.h"
 #include "attribs.h"
-#include "calls.h"
 #include "flags.h"
-#include "cp-tree.h"
 #include "tree-iterator.h"
-#include "tree-inline.h"
 #include "decl.h"
 #include "intl.h"
 #include "toplev.h"
-#include "tm_p.h"
-#include "target.h"
-#include "c-family/c-common.h"
 #include "c-family/c-objc.h"
 #include "c-family/c-pragma.h"
-#include "c-family/c-target.h"
 #include "c-family/c-ubsan.h"
-#include "diagnostic.h"
-#include "intl.h"
 #include "debug.h"
-#include "timevar.h"
-#include "splay-tree.h"
 #include "plugin.h"
-#include "hard-reg-set.h"
-#include "function.h"
-#include "cgraph.h"
 #include "cilk.h"
 #include "builtins.h"
 
@@ -113,7 +100,7 @@ static void end_cleanup_fn (void);
 static tree cp_make_fname_decl (location_t, tree, int);
 static void initialize_predefined_identifiers (void);
 static tree check_special_function_return_type
-       (special_function_kind, tree, tree);
+       (special_function_kind, tree, tree, int, const location_t*);
 static tree push_cp_library_fn (enum tree_code, tree, int);
 static tree build_cp_library_fn (tree, enum tree_code, tree, int);
 static void store_parm_decls (tree);
@@ -230,6 +217,7 @@ struct GTY((for_user)) named_label_entry {
   bool in_try_scope;
   bool in_catch_scope;
   bool in_omp_scope;
+  bool in_transaction_scope;
 };
 
 #define named_labels cp_function_chain->x_named_labels
@@ -498,6 +486,9 @@ poplevel_named_label_1 (named_label_entry **slot, cp_binding_level *bl)
        case sk_omp:
          ent->in_omp_scope = true;
          break;
+       case sk_transaction:
+         ent->in_transaction_scope = true;
+         break;
        default:
          break;
        }
@@ -2023,7 +2014,22 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       /* For typedefs use the old type, as the new type's DECL_NAME points
         at newdecl, which will be ggc_freed.  */
       if (TREE_CODE (newdecl) == TYPE_DECL)
-       newtype = oldtype;
+       {
+         newtype = oldtype;
+
+         /* And remove the new type from the variants list.  */
+         if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl)
+           {
+             tree remove = TREE_TYPE (newdecl);
+             for (tree t = TYPE_MAIN_VARIANT (remove); ;
+                  t = TYPE_NEXT_VARIANT (t))
+               if (TYPE_NEXT_VARIANT (t) == remove)
+                 {
+                   TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove);
+                   break;
+                 }
+           }
+       }
       else
        /* Merge the data types specified in the two decls.  */
        newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
@@ -2049,6 +2055,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
            }
        }
 
+      /* An explicit specialization of a function template or of a member
+        function of a class template can be declared transaction_safe
+        independently of whether the corresponding template entity is declared
+        transaction_safe. */
+      if (flag_tm && TREE_CODE (newdecl) == FUNCTION_DECL
+         && DECL_TEMPLATE_INSTANTIATION (olddecl)
+         && DECL_TEMPLATE_SPECIALIZATION (newdecl)
+         && tx_safe_fn_type_p (newtype)
+         && !tx_safe_fn_type_p (TREE_TYPE (newdecl)))
+       newtype = tx_unsafe_fn_variant (newtype);
+
       TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
 
       if (TREE_CODE (newdecl) == FUNCTION_DECL)
@@ -2950,14 +2967,16 @@ decl_jump_unsafe (tree decl)
   return 0;
 }
 
-/* A subroutine of check_previous_goto_1 to identify a branch to the user.  */
+/* A subroutine of check_previous_goto_1 and check_goto to identify a branch
+   to the user.  */
 
 static bool
-identify_goto (tree decl, const location_t *locus)
+identify_goto (tree decl, location_t loc, const location_t *locus,
+              diagnostic_t diag_kind)
 {
-  bool complained = (decl
-                    ? permerror (input_location, "jump to label %qD", decl)
-                    : permerror (input_location, "jump to case label"));
+  bool complained
+    = (decl ? emit_diagnostic (diag_kind, loc, 0, "jump to label %qD", decl)
+           : emit_diagnostic (diag_kind, loc, 0, "jump to case label"));
   if (complained && locus)
     inform (*locus, "  from here");
   return complained;
@@ -2974,15 +2993,17 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
                       bool exited_omp, const location_t *locus)
 {
   cp_binding_level *b;
-  bool identified = false, complained = false;
-  bool saw_eh = false, saw_omp = false;
+  bool complained = false;
+  int identified = 0;
+  bool saw_eh = false, saw_omp = false, saw_tm = false;
 
   if (exited_omp)
     {
-      complained = identify_goto (decl, locus);
+      complained = identify_goto (decl, input_location, locus, DK_ERROR);
       if (complained)
        inform (input_location, "  exits OpenMP structured block");
-      identified = saw_omp = true;
+      saw_omp = true;
+      identified = 2;
     }
 
   for (b = current_binding_level; b ; b = b->level_chain)
@@ -2999,8 +3020,9 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
 
          if (!identified)
            {
-             complained = identify_goto (decl, locus);
-             identified = true;
+             complained = identify_goto (decl, input_location, locus,
+                                         DK_PERMERROR);
+             identified = 1;
            }
          if (complained)
            {
@@ -3018,10 +3040,11 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
        break;
       if ((b->kind == sk_try || b->kind == sk_catch) && !saw_eh)
        {
-         if (!identified)
+         if (identified < 2)
            {
-             complained = identify_goto (decl, locus);
-             identified = true;
+             complained = identify_goto (decl, input_location, locus,
+                                         DK_ERROR);
+             identified = 2;
            }
          if (complained)
            {
@@ -3034,15 +3057,29 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
        }
       if (b->kind == sk_omp && !saw_omp)
        {
-         if (!identified)
+         if (identified < 2)
            {
-             complained = identify_goto (decl, locus);
-             identified = true;
+             complained = identify_goto (decl, input_location, locus,
+                                         DK_ERROR);
+             identified = 2;
            }
          if (complained)
            inform (input_location, "  enters OpenMP structured block");
          saw_omp = true;
        }
+      if (b->kind == sk_transaction && !saw_tm)
+       {
+         if (identified < 2)
+           {
+             complained = identify_goto (decl, input_location, locus,
+                                         DK_ERROR);
+             identified = 2;
+           }
+         if (complained)
+           inform (input_location,
+                   "  enters synchronized or atomic statement");
+         saw_tm = true;
+       }
     }
 
   return !identified;
@@ -3069,7 +3106,8 @@ void
 check_goto (tree decl)
 {
   struct named_label_entry *ent, dummy;
-  bool saw_catch = false, identified = false, complained = false;
+  bool saw_catch = false, complained = false;
+  int identified = 0;
   tree bad;
   unsigned ix;
 
@@ -3109,14 +3147,16 @@ check_goto (tree decl)
       return;
     }
 
-  if (ent->in_try_scope || ent->in_catch_scope
+  if (ent->in_try_scope || ent->in_catch_scope || ent->in_transaction_scope
       || ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls))
     {
-      complained = permerror (DECL_SOURCE_LOCATION (decl),
-                             "jump to label %qD", decl);
-      if (complained)
-       inform (input_location, "  from here");
-      identified = true;
+      diagnostic_t diag_kind = DK_PERMERROR;
+      if (ent->in_try_scope || ent->in_catch_scope
+         || ent->in_transaction_scope || ent->in_omp_scope)
+       diag_kind = DK_ERROR;
+      complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl),
+                                 &input_location, diag_kind);
+      identified = 1 + (diag_kind == DK_ERROR);
     }
 
   FOR_EACH_VEC_SAFE_ELT (ent->bad_decls, ix, bad)
@@ -3126,6 +3166,12 @@ check_goto (tree decl)
       if (u > 1 && DECL_ARTIFICIAL (bad))
        {
          /* Can't skip init of __exception_info.  */
+         if (identified == 1)
+           {
+             complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl),
+                                         &input_location, DK_ERROR);
+             identified = 2;
+           }
          if (complained)
            inform (DECL_SOURCE_LOCATION (bad), "  enters catch block");
          saw_catch = true;
@@ -3148,6 +3194,8 @@ check_goto (tree decl)
        inform (input_location, "  enters try block");
       else if (ent->in_catch_scope && !saw_catch)
        inform (input_location, "  enters catch block");
+      else if (ent->in_transaction_scope)
+       inform (input_location, "  enters synchronized or atomic statement");
     }
 
   if (ent->in_omp_scope)
@@ -3164,13 +3212,12 @@ check_goto (tree decl)
            break;
          if (b->kind == sk_omp)
            {
-             if (!identified)
+             if (identified < 2)
                {
-                 complained = permerror (DECL_SOURCE_LOCATION (decl),
-                                         "jump to label %qD", decl);
-                 if (complained)
-                   inform (input_location, "  from here");
-                 identified = true;
+                 complained = identify_goto (decl,
+                                             DECL_SOURCE_LOCATION (decl),
+                                             &input_location, DK_ERROR);
+                 identified = 2;
                }
              if (complained)
                inform (input_location, "  exits OpenMP structured block");
@@ -4508,8 +4555,9 @@ check_tag_decl (cp_decl_specifier_seq *declspecs,
     permerror (input_location, "declaration does not declare anything");
   else if (declared_type != NULL_TREE && type_uses_auto (declared_type))
     {
-      error ("%<auto%> can only be specified for variables "
-            "or function declarations");
+      error_at (declspecs->locations[ds_type_spec],
+               "%<auto%> can only be specified for variables "
+               "or function declarations");
       return error_mark_node;
     }
   /* Check for an anonymous union.  */
@@ -6685,6 +6733,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
               to put statics on the list so we can deal with the label
               address extension.  FIXME.  */
            add_local_decl (cfun, decl);
+         /* And make sure it's in the symbol table for
+            c_parse_final_cleanups to find.  */
+         varpool_node::get_create (decl);
        }
 
       /* Convert the initializer to the type of DECL, if we have not
@@ -7797,6 +7848,9 @@ grokfndecl (tree ctype,
       parm = build_this_parm (type, quals);
       DECL_CHAIN (parm) = parms;
       parms = parm;
+
+      /* Allocate space to hold the vptr bit if needed.  */
+      DECL_ALIGN (decl) = MINIMUM_METHOD_BOUNDARY;
     }
   DECL_ARGUMENTS (decl) = parms;
   for (t = parms; t; t = DECL_CHAIN (t))
@@ -7820,14 +7874,6 @@ grokfndecl (tree ctype,
       break;
     }
 
-  /* If pointers to member functions use the least significant bit to
-     indicate whether a function is virtual, ensure a pointer
-     to this function will have that bit clear.  */
-  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
-      && TREE_CODE (type) == METHOD_TYPE
-      && DECL_ALIGN (decl) < 2 * BITS_PER_UNIT)
-    DECL_ALIGN (decl) = 2 * BITS_PER_UNIT;
-
   if (friendp
       && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
     {
@@ -7971,6 +8017,11 @@ grokfndecl (tree ctype,
   DECL_EXTERNAL (decl) = 1;
   if (TREE_CODE (type) == FUNCTION_TYPE)
     {
+      if (quals || rqual)
+       TREE_TYPE (decl) = apply_memfn_quals (TREE_TYPE (decl),
+                                             TYPE_UNQUALIFIED,
+                                             REF_QUAL_NONE);
+
       if (quals)
        {
          error (ctype
@@ -8357,8 +8408,7 @@ grokvardecl (tree type,
 
   if (DECL_NAME (decl)
       && MAIN_NAME_P (DECL_NAME (decl))
-      && CP_DECL_CONTEXT (decl) == global_namespace
-      && !at_function_scope_p ())
+      && scope == global_namespace)
     error ("cannot declare %<::main%> to be a global variable");
 
   /* Check that the variable can be safely declared as a concept.
@@ -8556,33 +8606,24 @@ stabilize_vla_size (tree size)
   cp_walk_tree (&size, stabilize_save_expr_r, &pset, &pset);
 }
 
-/* Helper function for compute_array_index_type.  Look for SIZEOF_EXPR
-   not inside of SAVE_EXPR and fold them.  */
+/* Reduce a SIZEOF_EXPR to its value.  */
 
-static tree
-fold_sizeof_expr_r (tree *expr_p, int *walk_subtrees, void *data)
-{
-  tree expr = *expr_p;
-  if (TREE_CODE (expr) == SAVE_EXPR || TYPE_P (expr))
-    *walk_subtrees = 0;
-  else if (TREE_CODE (expr) == SIZEOF_EXPR)
-    {
-      *(bool *)data = true;
-      if (SIZEOF_EXPR_TYPE_P (expr))
-       expr = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (expr, 0)),
-                                          SIZEOF_EXPR, false);
-      else if (TYPE_P (TREE_OPERAND (expr, 0)))
-       expr = cxx_sizeof_or_alignof_type (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
-                                          false);
-      else
-        expr = cxx_sizeof_or_alignof_expr (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
-                                          false);
-      if (expr == error_mark_node)
-        expr = size_one_node;
-      *expr_p = expr;
-      *walk_subtrees = 0;
-    }
-  return NULL;
+tree
+fold_sizeof_expr (tree t)
+{
+  tree r;
+  if (SIZEOF_EXPR_TYPE_P (t))
+    r = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (t, 0)),
+                                   SIZEOF_EXPR, false);
+  else if (TYPE_P (TREE_OPERAND (t, 0)))
+    r = cxx_sizeof_or_alignof_type (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+                                   false);
+  else
+    r = cxx_sizeof_or_alignof_expr (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+                                   false);
+  if (r == error_mark_node)
+    r = size_one_node;
+  return r;
 }
 
 /* Given the SIZE (i.e., number of elements) in an array, compute an
@@ -8675,7 +8716,18 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
       SET_TYPE_STRUCTURAL_EQUALITY (itype);
       return itype;
     }
-  
+
+  if (TREE_CODE (size) != INTEGER_CST)
+    {
+      tree folded = cp_fully_fold (size);
+      if (TREE_CODE (folded) == INTEGER_CST)
+       pedwarn (location_of (size), OPT_Wpedantic,
+                "size of array is not an integral constant-expression");
+      /* Use the folded result for VLAs, too; it will have resolved
+        SIZEOF_EXPR.  */
+      size = folded;
+    }
+
   /* Normally, the array-bound will be a constant.  */
   if (TREE_CODE (size) == INTEGER_CST)
     {
@@ -8762,7 +8814,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
                                  cp_convert (ssizetype, integer_one_node,
                                              complain),
                                  complain);
-      itype = fold (itype);
+      itype = maybe_constant_value (itype);
       processing_template_decl = saved_processing_template_decl;
 
       if (!TREE_CONSTANT (itype))
@@ -8770,18 +8822,6 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
          /* A variable sized array.  */
          itype = variable_size (itype);
 
-         if (TREE_CODE (itype) != SAVE_EXPR)
-           {
-             /* Look for SIZEOF_EXPRs in itype and fold them, otherwise
-                they might survive till gimplification.  */
-             tree newitype = itype;
-             bool found = false;
-             cp_walk_tree_without_duplicates (&newitype,
-                                              fold_sizeof_expr_r, &found);
-             if (found)
-               itype = variable_size (fold (newitype));
-           }
-
          stabilize_vla_size (itype);
 
          if (flag_sanitize & SANITIZE_VLA
@@ -8925,24 +8965,51 @@ create_array_type_for_decl (tree name, tree type, tree size)
   return build_cplus_array_type (type, itype);
 }
 
-/* Check that it's OK to declare a function with the indicated TYPE.
-   SFK indicates the kind of special function (if any) that this
-   function is.  OPTYPE is the type given in a conversion operator
-   declaration, or the class type for a constructor/destructor.
-   Returns the actual return type of the function; that
-   may be different than TYPE if an error occurs, or for certain
-   special functions.  */
+/* Returns the smallest location != UNKNOWN_LOCATION among the
+   three stored in LOCATIONS[ds_const], LOCATIONS[ds_volatile],
+   and LOCATIONS[ds_restrict].  */
+
+static location_t
+smallest_type_quals_location (int type_quals, const location_t* locations)
+{
+  location_t loc = UNKNOWN_LOCATION;
+
+  if (type_quals & TYPE_QUAL_CONST)
+    loc = locations[ds_const];
+
+  if ((type_quals & TYPE_QUAL_VOLATILE)
+      && (loc == UNKNOWN_LOCATION || locations[ds_volatile] < loc))
+    loc = locations[ds_volatile];
+
+  if ((type_quals & TYPE_QUAL_RESTRICT)
+      && (loc == UNKNOWN_LOCATION || locations[ds_restrict] < loc))
+    loc = locations[ds_restrict];
+
+  return loc;
+}
+
+/* Check that it's OK to declare a function with the indicated TYPE
+   and TYPE_QUALS.  SFK indicates the kind of special function (if any)
+   that this function is.  OPTYPE is the type given in a conversion
+   operator declaration, or the class type for a constructor/destructor.
+   Returns the actual return type of the function; that may be different
+   than TYPE if an error occurs, or for certain special functions.  */
 
 static tree
 check_special_function_return_type (special_function_kind sfk,
                                    tree type,
-                                   tree optype)
+                                   tree optype,
+                                   int type_quals,
+                                   const location_t* locations)
 {
   switch (sfk)
     {
     case sfk_constructor:
       if (type)
        error ("return type specification for constructor invalid");
+      else if (type_quals != TYPE_UNQUALIFIED)
+       error_at (smallest_type_quals_location (type_quals, locations),
+                 "qualifiers are not allowed on constructor declaration");
 
       if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (optype))
        type = build_pointer_type (optype);
@@ -8953,6 +9020,10 @@ check_special_function_return_type (special_function_kind sfk,
     case sfk_destructor:
       if (type)
        error ("return type specification for destructor invalid");
+      else if (type_quals != TYPE_UNQUALIFIED)
+       error_at (smallest_type_quals_location (type_quals, locations),
+                 "qualifiers are not allowed on destructor declaration");
+
       /* We can't use the proper return type here because we run into
         problems with ambiguous bases and covariant returns.
         Java classes are left unchanged because (void *) isn't a valid
@@ -8965,7 +9036,12 @@ check_special_function_return_type (special_function_kind sfk,
 
     case sfk_conversion:
       if (type)
-       error ("return type specified for %<operator %T%>",  optype);
+       error ("return type specified for %<operator %T%>", optype);
+      else if (type_quals != TYPE_UNQUALIFIED)
+       error_at (smallest_type_quals_location (type_quals, locations),
+                 "qualifiers are not allowed on declaration of "
+                 "%<operator %T%>", optype);
+
       type = optype;
       break;
 
@@ -9091,7 +9167,7 @@ grokdeclarator (const cp_declarator *declarator,
      a member function.  */
   cp_ref_qualifier rqual = REF_QUAL_NONE;
   /* cv-qualifiers that apply to the type specified by the DECLSPECS.  */
-  int type_quals;
+  int type_quals = TYPE_UNQUALIFIED;
   tree raises = NULL_TREE;
   int template_count = 0;
   tree returned_attrs = NULL_TREE;
@@ -9138,6 +9214,13 @@ grokdeclarator (const cp_declarator *declarator,
   if (concept_p)
     constexpr_p = true;
 
+  if (decl_spec_seq_has_spec_p (declspecs, ds_const))
+    type_quals |= TYPE_QUAL_CONST;
+  if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
+    type_quals |= TYPE_QUAL_VOLATILE;
+  if (decl_spec_seq_has_spec_p (declspecs, ds_restrict))
+    type_quals |= TYPE_QUAL_RESTRICT;
+
   if (decl_context == FUNCDEF)
     funcdef_flag = true, decl_context = NORMAL;
   else if (decl_context == MEMFUNCDEF)
@@ -9463,8 +9546,13 @@ grokdeclarator (const cp_declarator *declarator,
     ctor_return_type = ctype;
 
   if (sfk != sfk_none)
-    type = check_special_function_return_type (sfk, type,
-                                              ctor_return_type);
+    {
+      type = check_special_function_return_type (sfk, type,
+                                                ctor_return_type,
+                                                type_quals,
+                                                declspecs->locations);
+      type_quals = TYPE_UNQUALIFIED;
+    }
   else if (type == NULL_TREE)
     {
       int is_main;
@@ -9649,17 +9737,6 @@ grokdeclarator (const cp_declarator *declarator,
        type = build_complex_type (type);
     }
 
-  type_quals = TYPE_UNQUALIFIED;
-  if (decl_spec_seq_has_spec_p (declspecs, ds_const))
-    type_quals |= TYPE_QUAL_CONST;
-  if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
-    type_quals |= TYPE_QUAL_VOLATILE;
-  if (decl_spec_seq_has_spec_p (declspecs, ds_restrict))
-    type_quals |= TYPE_QUAL_RESTRICT;
-  if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED)
-    error ("qualifiers are not allowed on declaration of %<operator %T%>",
-          ctor_return_type);
-
   /* If we're using the injected-class-name to form a compound type or a
      declaration, replace it with the underlying class so we don't get
      redundant typedefs in the debug output.  But if we are returning the
@@ -9884,6 +9961,9 @@ grokdeclarator (const cp_declarator *declarator,
        case cdk_array:
          type = create_array_type_for_decl (dname, type,
                                             declarator->u.array.bounds);
+         if (!valid_array_size_p (input_location, type, dname))
+           type = error_mark_node;
+
          if (declarator->std_attributes)
            /* [dcl.array]/1:
 
@@ -9940,6 +10020,8 @@ grokdeclarator (const cp_declarator *declarator,
             virt_specifiers = declarator->u.function.virt_specifiers;
            /* And ref-qualifier, too */
            rqual = declarator->u.function.ref_qualifier;
+           /* And tx-qualifier.  */
+           tree tx_qual = declarator->u.function.tx_qualifier;
            /* Pick up the exception specifications.  */
            raises = declarator->u.function.exception_specification;
            /* If the exception-specification is ill-formed, let's pretend
@@ -10117,13 +10199,24 @@ grokdeclarator (const cp_declarator *declarator,
              }
 
            type = build_function_type (type, arg_types);
-           if (declarator->std_attributes)
+
+           tree attrs = declarator->std_attributes;
+           if (tx_qual)
+             {
+               tree att = build_tree_list (tx_qual, NULL_TREE);
+               /* transaction_safe applies to the type, but
+                  transaction_safe_dynamic applies to the function.  */
+               if (is_attribute_p ("transaction_safe", tx_qual))
+                 attrs = chainon (attrs, att);
+               else
+                 returned_attrs = chainon (returned_attrs, att);
+             }
+           if (attrs)
              /* [dcl.fct]/2:
 
                 The optional attribute-specifier-seq appertains to
                 the function type.  */
-             decl_attributes (&type, declarator->std_attributes,
-                              0);
+             decl_attributes (&type, attrs, 0);
          }
          break;
 
@@ -10434,19 +10527,6 @@ grokdeclarator (const cp_declarator *declarator,
         error ("non-parameter %qs cannot be a parameter pack", name);
     }
 
-  /* Did array size calculations overflow or does the array cover more
-     than half of the address-space?  */
-  if (TREE_CODE (type) == ARRAY_TYPE
-      && COMPLETE_TYPE_P (type)
-      && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
-      && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
-    {
-      error ("size of array %qs is too large", name);
-      /* If we proceed with the array type as it is, we'll eventually
-        crash in tree_to_[su]hwi().  */
-      type = error_mark_node;
-    }
-
   if ((decl_context == FIELD || decl_context == PARM)
       && !processing_template_decl
       && variably_modified_type_p (type, NULL_TREE))
@@ -12693,6 +12773,7 @@ xref_basetypes (tree ref, tree base_list)
   tree binfo, base_binfo;
   unsigned max_vbases = 0; /* Maximum direct & indirect virtual bases.  */
   unsigned max_bases = 0;  /* Maximum direct bases.  */
+  unsigned max_dvbases = 0; /* Maximum direct virtual bases.  */
   int i;
   tree default_access;
   tree igo_prev; /* Track Inheritance Graph Order.  */
@@ -12730,12 +12811,13 @@ xref_basetypes (tree ref, tree base_list)
        {
          max_bases++;
          if (TREE_TYPE (*basep))
-           max_vbases++;
+           max_dvbases++;
          if (CLASS_TYPE_P (basetype))
            max_vbases += vec_safe_length (CLASSTYPE_VBASECLASSES (basetype));
          basep = &TREE_CHAIN (*basep);
        }
     }
+  max_vbases += max_dvbases;
 
   TYPE_MARKED_P (ref) = 1;
 
@@ -12778,6 +12860,9 @@ xref_basetypes (tree ref, tree base_list)
          error ("Java class %qT cannot have multiple bases", ref);
           return false;
         }
+      else
+       warning (OPT_Wmultiple_inheritance,
+                "%qT defined with multiple direct bases", ref);
     }
 
   if (max_vbases)
@@ -12789,6 +12874,9 @@ xref_basetypes (tree ref, tree base_list)
          error ("Java class %qT cannot have virtual bases", ref);
           return false;
         }
+      else if (max_dvbases)
+       warning (OPT_Wvirtual_inheritance,
+                "%qT defined with direct virtual base", ref);
     }
 
   for (igo_prev = binfo; base_list; base_list = TREE_CHAIN (base_list))
@@ -13433,7 +13521,7 @@ incremented enumerator value is too large for %<long%>");
                   "type %<%T%>", value, ENUM_UNDERLYING_TYPE (enumtype));
 
           /* Convert the value to the appropriate type.  */
-          value = convert (ENUM_UNDERLYING_TYPE (enumtype), value);
+          value = fold_convert (ENUM_UNDERLYING_TYPE (enumtype), value);
         }
     }
 
@@ -13544,6 +13632,16 @@ check_function_type (tree decl, tree current_function_parms)
     abstract_virtuals_error (decl, TREE_TYPE (fntype));
 }
 
+/* True iff FN is an implicitly-defined default constructor.  */
+
+static bool
+implicit_default_ctor_p (tree fn)
+{
+  return (DECL_CONSTRUCTOR_P (fn)
+         && !user_provided_p (fn)
+         && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)));
+}
+
 /* Create the FUNCTION_DECL for a function definition.
    DECLSPECS and DECLARATOR are the parts of the declaration;
    they describe the function's name and the type it returns,
@@ -13950,7 +14048,11 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   store_parm_decls (current_function_parms);
 
   if (!processing_template_decl
-      && flag_lifetime_dse && DECL_CONSTRUCTOR_P (decl1))
+      && flag_lifetime_dse && DECL_CONSTRUCTOR_P (decl1)
+      /* We can't clobber safely for an implicitly-defined default constructor
+        because part of the initialization might happen before we enter the
+        constructor, via AGGR_INIT_ZERO_FIRST (c++/68006).  */
+      && !implicit_default_ctor_p (decl1))
     {
       /* Insert a clobber to let the back end know that the object storage
         is dead when we enter the constructor.  */
@@ -14478,6 +14580,14 @@ finish_function (int flags)
      the NRV transformation.   */
   maybe_save_function_definition (fndecl);
 
+  /* Invoke the pre-genericize plugin before we start munging things.  */
+  if (!processing_template_decl)
+    invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
+
+  /* Perform delayed folding before NRV transformation.  */
+  if (!processing_template_decl)
+    cp_fold_function (fndecl);
+
   /* Set up the named return value optimization, if we can.  Candidate
      variables are selected in check_return_expr.  */
   if (current_function_return_value)
@@ -14584,7 +14694,6 @@ finish_function (int flags)
   if (!processing_template_decl)
     {
       struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl);
-      invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
       cp_genericize (fndecl);
       /* Clear out the bits we don't need.  */
       f->x_current_class_ptr = NULL;
@@ -14787,10 +14896,6 @@ complete_vars (tree type)
              cp_apply_type_quals_to_decl (cp_type_quals (type), var);
            }
 
-         if (DECL_INITIAL (var)
-             && decl_constant_var_p (var))
-           DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var));
-
          /* Remove this entry from the list.  */
          incomplete_vars->unordered_remove (ix);
        }
@@ -14878,8 +14983,7 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
      a "jumpy" behaviour for users of debuggers when they step around
      the end of the block.  So let's unset the location of the
      destructor call instead.  */
-  if (cleanup != NULL && EXPR_P (cleanup))
-    SET_EXPR_LOCATION (cleanup, UNKNOWN_LOCATION);
+  protected_set_expr_location (cleanup, UNKNOWN_LOCATION);
 
   if (cleanup
       && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (TREE_TYPE (decl)))