Do not update SSA in lto-stremaer-in
[gcc.git] / gcc / cp / semantics.c
index 798a2b3bb30f70d8ad830904cfd4c50908b5244b..17de39eea5489af212e46fb30dfe047e19dd0498 100644 (file)
@@ -658,7 +658,7 @@ maybe_convert_cond (tree cond)
   if (TREE_CODE (cond) == MODIFY_EXPR
       && !TREE_NO_WARNING (cond)
       && warn_parentheses
-      && warning_at (cp_expr_loc_or_loc (cond, input_location),
+      && warning_at (cp_expr_loc_or_input_loc (cond),
                     OPT_Wparentheses, "suggest parentheses around "
                                       "assignment used as truth value"))
     TREE_NO_WARNING (cond) = 1;
@@ -686,7 +686,7 @@ finish_expr_stmt (tree expr)
          expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
        }
       else if (!type_dependent_expression_p (expr))
-       convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT, 
+       convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT,
                          tf_warning_or_error);
 
       if (check_for_bare_parameter_packs (expr))
@@ -723,6 +723,28 @@ begin_if_stmt (void)
   return r;
 }
 
+/* Returns true if FN, a CALL_EXPR, is a call to
+   std::is_constant_evaluated or __builtin_is_constant_evaluated.  */
+
+static bool
+is_std_constant_evaluated_p (tree fn)
+{
+  /* std::is_constant_evaluated takes no arguments.  */
+  if (call_expr_nargs (fn) != 0)
+    return false;
+
+  tree fndecl = cp_get_callee_fndecl_nofold (fn);
+  if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+                        BUILT_IN_FRONTEND))
+    return true;
+
+  if (!decl_in_std_namespace_p (fndecl))
+    return false;
+
+  tree name = DECL_NAME (fndecl);
+  return name && id_equal (name, "is_constant_evaluated");
+}
+
 /* Process the COND of an if-statement, which may be given by
    IF_STMT.  */
 
@@ -738,6 +760,20 @@ finish_if_stmt_cond (tree cond, tree if_stmt)
         converted to bool.  */
       && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
     {
+      /* if constexpr (std::is_constant_evaluated()) is always true,
+        so give the user a clue.  */
+      if (warn_tautological_compare)
+       {
+         tree t = cond;
+         if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
+           t = TREE_OPERAND (t, 0);
+         if (TREE_CODE (t) == CALL_EXPR
+             && is_std_constant_evaluated_p (t))
+           warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
+                       "%qs always evaluates to true in %<if constexpr%>",
+                       "std::is_constant_evaluated");
+       }
+
       cond = instantiate_non_dependent_expr (cond);
       cond = cxx_constant_value (cond, NULL_TREE);
     }
@@ -774,6 +810,18 @@ finish_else_clause (tree if_stmt)
   ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt));
 }
 
+/* Callback for cp_walk_tree to mark all {VAR,PARM}_DECLs in a tree as
+   read.  */
+
+static tree
+maybe_mark_exp_read_r (tree *tp, int *, void *)
+{
+  tree t = *tp;
+  if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
+    mark_exp_read (t);
+  return NULL_TREE;
+}
+
 /* Finish an if-statement.  */
 
 void
@@ -781,6 +829,16 @@ finish_if_stmt (tree if_stmt)
 {
   tree scope = IF_SCOPE (if_stmt);
   IF_SCOPE (if_stmt) = NULL;
+  if (IF_STMT_CONSTEXPR_P (if_stmt))
+    {
+      /* Prevent various -Wunused warnings.  We might not instantiate
+        either of these branches, so we would not mark the variables
+        used in that branch as read.  */
+      cp_walk_tree_without_duplicates (&THEN_CLAUSE (if_stmt),
+                                      maybe_mark_exp_read_r, NULL);
+      cp_walk_tree_without_duplicates (&ELSE_CLAUSE (if_stmt),
+                                      maybe_mark_exp_read_r, NULL);
+    }
   add_stmt (do_poplevel (scope));
 }
 
@@ -906,7 +964,7 @@ finish_return_stmt (tree expr)
     {
       if (warn_sequence_point)
        verify_sequence_points (expr);
-      
+
       if (DECL_DESTRUCTOR_P (current_function_decl)
          || (DECL_CONSTRUCTOR_P (current_function_decl)
              && targetm.cxx.cdtor_returns_this ()))
@@ -1185,10 +1243,12 @@ finish_switch_cond (tree cond, tree switch_stmt)
   if (!processing_template_decl)
     {
       /* Convert the condition to an integer or enumeration type.  */
+      tree orig_cond = cond;
       cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
       if (cond == NULL_TREE)
        {
-         error ("switch quantity not an integer");
+         error_at (cp_expr_loc_or_input_loc (orig_cond),
+                   "switch quantity not an integer");
          cond = error_mark_node;
        }
       /* We want unlowered type here to handle enum bit-fields.  */
@@ -1484,8 +1544,9 @@ finish_compound_stmt (tree stmt)
    considered volatile, and whether it is asm inline.  */
 
 tree
-finish_asm_stmt (int volatile_p, tree string, tree output_operands,
-                tree input_operands, tree clobbers, tree labels, bool inline_p)
+finish_asm_stmt (location_t loc, int volatile_p, tree string,
+                tree output_operands, tree input_operands, tree clobbers,
+                tree labels, bool inline_p)
 {
   tree r;
   tree t;
@@ -1527,13 +1588,12 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
                  || CP_TYPE_CONST_P (TREE_TYPE (operand))
                  /* Functions are not modifiable, even though they are
                     lvalues.  */
-                 || TREE_CODE (TREE_TYPE (operand)) == FUNCTION_TYPE
-                 || TREE_CODE (TREE_TYPE (operand)) == METHOD_TYPE
+                 || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (operand))
                  /* If it's an aggregate and any field is const, then it is
                     effectively const.  */
                  || (CLASS_TYPE_P (TREE_TYPE (operand))
                      && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
-           cxx_readonly_error (input_location, operand, lv_asm);
+           cxx_readonly_error (loc, operand, lv_asm);
 
          tree *op = &operand;
          while (TREE_CODE (*op) == COMPOUND_EXPR)
@@ -1571,7 +1631,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
        {
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
          bool constraint_parsed
-           = parse_input_constraint (&constraint, i, ninputs, noutputs, 0,   
+           = parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
                                      oconstraints, &allows_mem, &allows_reg);
          /* If the operand is going to end up in memory, don't call
             decay_conversion.  */
@@ -1586,8 +1646,9 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
             resolve the overloading.  */
          if (TREE_TYPE (operand) == unknown_type_node)
            {
-             error ("type of asm operand %qE could not be determined",
-                    TREE_VALUE (t));
+             error_at (loc,
+                       "type of %<asm%> operand %qE could not be determined",
+                       TREE_VALUE (t));
              operand = error_mark_node;
            }
 
@@ -1635,7 +1696,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
        }
     }
 
-  r = build_stmt (input_location, ASM_EXPR, string,
+  r = build_stmt (loc, ASM_EXPR, string,
                  output_operands, input_operands,
                  clobbers, labels);
   ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
@@ -1668,7 +1729,7 @@ finish_label_decl (tree name)
 {
   if (!at_function_scope_p ())
     {
-      error ("__label__ declarations are only allowed in function scopes");
+      error ("%<__label__%> declarations are only allowed in function scopes");
       return;
     }
 
@@ -1727,10 +1788,10 @@ finish_mem_initializers (tree mem_inits)
 
 /* Obfuscate EXPR if it looks like an id-expression or member access so
    that the call to finish_decltype in do_auto_deduction will give the
-   right result.  */
+   right result.  If EVEN_UNEVAL, do this even in unevaluated context.  */
 
 tree
-force_paren_expr (tree expr)
+force_paren_expr (tree expr, bool even_uneval)
 {
   /* This is only needed for decltype(auto) in C++14.  */
   if (cxx_dialect < cxx14)
@@ -1738,7 +1799,7 @@ force_paren_expr (tree expr)
 
   /* If we're in unevaluated context, we can't be deducing a
      return/initializer type, so we don't need to mess with this.  */
-  if (cp_unevaluated_operand)
+  if (cp_unevaluated_operand && !even_uneval)
     return expr;
 
   if (!DECL_P (tree_strip_any_location_wrapper (expr))
@@ -1746,14 +1807,16 @@ force_paren_expr (tree expr)
       && TREE_CODE (expr) != SCOPE_REF)
     return expr;
 
+  location_t loc = cp_expr_location (expr);
+
   if (TREE_CODE (expr) == COMPONENT_REF
       || TREE_CODE (expr) == SCOPE_REF)
     REF_PARENTHESIZED_P (expr) = true;
   else if (processing_template_decl)
-    expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr);
+    expr = build1_loc (loc, PAREN_EXPR, TREE_TYPE (expr), expr);
   else
     {
-      expr = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr);
+      expr = build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr);
       REF_PARENTHESIZED_P (expr) = true;
     }
 
@@ -1828,7 +1891,15 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
     {
       tree scope = qualifying_scope;
       if (scope == NULL_TREE)
-       scope = context_for_name_lookup (decl);
+       {
+         scope = context_for_name_lookup (decl);
+         if (!TYPE_P (scope))
+           {
+             /* Can happen during error recovery (c++/85014).  */
+             gcc_assert (seen_error ());
+             return error_mark_node;
+           }
+       }
       object = maybe_dummy_object (scope, NULL);
     }
 
@@ -1853,7 +1924,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
 
   if (current_class_ptr)
     TREE_USED (current_class_ptr) = 1;
-  if (processing_template_decl && !qualifying_scope)
+  if (processing_template_decl)
     {
       tree type = TREE_TYPE (decl);
 
@@ -1874,17 +1945,16 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
          type = cp_build_qualified_type (type, quals);
        }
 
-      ret = (convert_from_reference
-             (build_min (COMPONENT_REF, type, object, decl, NULL_TREE)));
+      if (qualifying_scope)
+       /* Wrap this in a SCOPE_REF for now.  */
+       ret = build_qualified_name (type, qualifying_scope, decl,
+                                   /*template_p=*/false);
+      else
+       ret = (convert_from_reference
+              (build_min (COMPONENT_REF, type, object, decl, NULL_TREE)));
     }
   /* If PROCESSING_TEMPLATE_DECL is nonzero here, then
-     QUALIFYING_SCOPE is also non-null.  Wrap this in a SCOPE_REF
-     for now.  */
-  else if (processing_template_decl)
-    ret = build_qualified_name (TREE_TYPE (decl),
-                               qualifying_scope,
-                               decl,
-                               /*template_p=*/false);
+     QUALIFYING_SCOPE is also non-null.  */
   else
     {
       tree access_type = TREE_TYPE (object);
@@ -2014,7 +2084,7 @@ check_accessibility_of_qualified_id (tree decl,
        its bases.  */
     qualifying_type = currently_open_derived_class (scope);
 
-  if (qualifying_type 
+  if (qualifying_type
       /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM
         or similar in a default argument value.  */
       && CLASS_TYPE_P (qualifying_type)
@@ -2112,6 +2182,14 @@ finish_qualified_id_expr (tree qualifying_class,
        expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
                                 complain);
     }
+  else if (!template_p
+          && TREE_CODE (expr) == TEMPLATE_DECL
+          && !DECL_FUNCTION_TEMPLATE_P (expr))
+    {
+      if (complain & tf_error)
+       error ("%qE missing template arguments", expr);
+      return error_mark_node;
+    }
   else
     {
       /* In a template, return a SCOPE_REF for most qualified-ids
@@ -2127,6 +2205,8 @@ finish_qualified_id_expr (tree qualifying_class,
        expr = build_qualified_name (TREE_TYPE (expr),
                                     qualifying_class, expr,
                                     template_p);
+      else if (tree wrap = maybe_get_tls_wrapper_call (expr))
+       expr = wrap;
 
       expr = convert_from_reference (expr);
     }
@@ -2410,7 +2490,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
          || any_type_dependent_arguments_p (*args))
        {
          result = build_min_nt_call_vec (orig_fn, *args);
-         SET_EXPR_LOCATION (result, cp_expr_loc_or_loc (fn, input_location));
+         SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn));
          KOENIG_LOOKUP_P (result) = koenig_p;
          if (is_overloaded_fn (fn))
            fn = get_fns (fn);
@@ -2509,6 +2589,23 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
                                      /*fn_p=*/NULL,
                                      complain);
     }
+  else if (concept_check_p (fn))
+    {
+      /* FN is actually a template-id referring to a concept definition.  */
+      tree id = unpack_concept_check (fn);
+      tree tmpl = TREE_OPERAND (id, 0);
+      tree args = TREE_OPERAND (id, 1);
+
+      if (!function_concept_p (tmpl))
+       {
+         error_at (EXPR_LOC_OR_LOC (fn, input_location),
+                   "cannot call a concept as a function");
+         return error_mark_node;
+       }
+
+      /* Ensure the result is wrapped as a call expression.  */
+      result = build_concept_check (tmpl, args, tf_warning_or_error);
+    }
   else if (is_overloaded_fn (fn))
     {
       /* If the function is an overloaded builtin, resolve it.  */
@@ -2947,6 +3044,14 @@ finish_translation_unit (void)
 
   /* Do file scope __FUNCTION__ et al.  */
   finish_fname_decls ();
+
+  if (scope_chain->omp_declare_target_attribute)
+    {
+      if (!errorcount)
+       error ("%<#pragma omp declare target%> without corresponding "
+              "%<#pragma omp end declare target%>");
+      scope_chain->omp_declare_target_attribute = 0;
+    }
 }
 
 /* Finish a template type parameter, specified as AGGR IDENTIFIER.
@@ -2978,8 +3083,8 @@ finish_template_template_parm (tree aggr, tree identifier)
   DECL_TEMPLATE_RESULT (tmpl) = decl;
   DECL_ARTIFICIAL (decl) = 1;
 
-  // Associate the constraints with the underlying declaration,
-  // not the template.
+  /* Associate the constraints with the underlying declaration,
+     not the template.  */
   tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
   tree constr = build_constraints (reqs, NULL_TREE);
   set_constraints (decl, constr);
@@ -2988,7 +3093,7 @@ finish_template_template_parm (tree aggr, tree identifier)
 
   gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
 
-  check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl), 
+  check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl),
                           /*is_primary=*/true, /*is_partial=*/false,
                           /*is_friend=*/0);
 
@@ -3025,6 +3130,12 @@ begin_class_definition (tree t)
   if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t)))
     return error_mark_node;
 
+  if (processing_template_parmlist && !LAMBDA_TYPE_P (t))
+    {
+      error ("definition of %q#T inside template parameter list", t);
+      return error_mark_node;
+    }
+
   /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733
      are passed the same as decimal scalar types.  */
   if (TREE_CODE (t) == RECORD_TYPE
@@ -3357,7 +3468,7 @@ baselink_for_fns (tree fns)
   tree scope;
   tree cl;
 
-  if (BASELINK_P (fns) 
+  if (BASELINK_P (fns)
       || error_operand_p (fns))
     return fns;
 
@@ -3459,16 +3570,12 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
        /* A lambda in an NSDMI (c++/64496).  */
        break;
 
-      if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr)
-         == CPLD_NONE)
+      if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
        break;
 
-      lambda_stack = tree_cons (NULL_TREE,
-                               lambda_expr,
-                               lambda_stack);
+      lambda_stack = tree_cons (NULL_TREE, lambda_expr, lambda_stack);
 
-      containing_function
-       = decl_function_context (containing_function);
+      containing_function = decl_function_context (containing_function);
     }
 
   /* In a lambda within a template, wait until instantiation time to implicitly
@@ -3479,8 +3586,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
       && DECL_PACK_P (decl))
     return decl;
 
-  if (lambda_expr && VAR_P (decl)
-      && DECL_ANON_UNION_VAR_P (decl))
+  if (lambda_expr && VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl))
     {
       if (complain & tf_error)
        error ("cannot capture member %qD of anonymous union", decl);
@@ -3489,11 +3595,8 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
   /* Do lambda capture when processing the id-expression, not when
      odr-using a variable.  */
   if (!odr_use && context == containing_function)
-    {
-      decl = add_default_capture (lambda_stack,
-                                 /*id=*/DECL_NAME (decl),
-                                 initializer);
-    }
+    decl = add_default_capture (lambda_stack,
+                               /*id=*/DECL_NAME (decl), initializer);
   /* Only an odr-use of an outer automatic variable causes an
      error, and a constant variable can decay to a prvalue
      constant without odr-use.  So don't complain yet.  */
@@ -3505,8 +3608,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
        {
          error ("%qD is not captured", decl);
          tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr);
-         if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr)
-             == CPLD_NONE)
+         if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
            inform (location_of (closure),
                    "the lambda has no capture-default");
          else if (TYPE_CLASS_SCOPE_P (closure))
@@ -3726,17 +3828,13 @@ finish_id_expression_1 (tree id_expression,
           wrong, so just return the identifier.  */
        return id_expression;
 
-      if (TREE_CODE (decl) == NAMESPACE_DECL)
-       {
-         error ("use of namespace %qD as expression", decl);
-         return error_mark_node;
-       }
-      else if (DECL_CLASS_TEMPLATE_P (decl))
+      if (DECL_CLASS_TEMPLATE_P (decl))
        {
          error ("use of class template %qT as expression", decl);
          return error_mark_node;
        }
-      else if (TREE_CODE (decl) == TREE_LIST)
+
+      if (TREE_CODE (decl) == TREE_LIST)
        {
          /* Ambiguous reference to base members.  */
          error ("request for member %qD is ambiguous in "
@@ -3760,9 +3858,10 @@ finish_id_expression_1 (tree id_expression,
       if (! error_operand_p (decl)
          && !dependent_p
          && integral_constant_expression_p
-         && ! decl_constant_var_p (decl)
+         && !decl_constant_var_p (decl)
          && TREE_CODE (decl) != CONST_DECL
-         && ! builtin_valid_in_constant_expr_p (decl))
+         && !builtin_valid_in_constant_expr_p (decl)
+         && !concept_check_p (decl))
        {
          if (!allow_non_integral_constant_expression_p)
            {
@@ -3772,26 +3871,24 @@ finish_id_expression_1 (tree id_expression,
          *non_integral_constant_expression_p = true;
        }
 
-      tree wrap;
-      if (VAR_P (decl)
-         && !cp_unevaluated_operand
-         && !processing_template_decl
-         && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
-         && CP_DECL_THREAD_LOCAL_P (decl)
-         && (wrap = get_tls_wrapper_fn (decl)))
-       {
-         /* Replace an evaluated use of the thread_local variable with
-            a call to its wrapper.  */
-         decl = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
-       }
+      if (tree wrap = maybe_get_tls_wrapper_call (decl))
+       /* Replace an evaluated use of the thread_local variable with
+          a call to its wrapper.  */
+       decl = wrap;
       else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
               && !dependent_p
-              && variable_template_p (TREE_OPERAND (decl, 0)))
+              && variable_template_p (TREE_OPERAND (decl, 0))
+              && !concept_check_p (decl))
        {
          decl = finish_template_variable (decl);
          mark_used (decl);
          decl = convert_from_reference (decl);
        }
+      else if (concept_check_p (decl))
+       {
+         /* Nothing more to do. All of the analysis for concept checks
+            is done by build_conept_id, called from the parser.  */
+       }
       else if (scope)
        {
          if (TREE_CODE (decl) == SCOPE_REF)
@@ -3806,6 +3903,8 @@ finish_id_expression_1 (tree id_expression,
          if (TREE_CODE (decl) == FUNCTION_DECL)
            mark_used (decl);
 
+         cp_warn_deprecated_use_scopes (scope);
+
          if (TYPE_P (scope))
            decl = finish_qualified_id_expr (scope,
                                             decl,
@@ -3829,10 +3928,11 @@ finish_id_expression_1 (tree id_expression,
        }
       else if (is_overloaded_fn (decl))
        {
+         /* We only need to look at the first function,
+            because all the fns share the attribute we're
+            concerned with (all member fns or all non-members).  */
          tree first_fn = get_first_fn (decl);
-
-         if (TREE_CODE (first_fn) == TEMPLATE_DECL)
-           first_fn = DECL_TEMPLATE_RESULT (first_fn);
+         first_fn = STRIP_TEMPLATE (first_fn);
 
          /* [basic.def.odr]: "A function whose name appears as a
             potentially-evaluated expression is odr-used if it is the unique
@@ -3866,7 +3966,7 @@ finish_id_expression_1 (tree id_expression,
          if (DECL_P (decl) && DECL_NONLOCAL (decl)
              && DECL_CLASS_SCOPE_P (decl))
            {
-             tree context = context_for_name_lookup (decl); 
+             tree context = context_for_name_lookup (decl);
              if (context != current_class_type)
                {
                  tree path = currently_open_derived_class (context);
@@ -3990,7 +4090,7 @@ calculate_direct_bases (tree type, tsubst_flags_t complain)
       || !NON_UNION_CLASS_TYPE_P (type))
     return make_tree_vec (0);
 
-  vec<tree, va_gc> *vector = make_tree_vector ();
+  releasing_vec vector;
   vec<tree, va_gc> *base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
   tree binfo;
   unsigned i;
@@ -4010,7 +4110,6 @@ calculate_direct_bases (tree type, tsubst_flags_t complain)
   for (i = 0; i < vector->length (); ++i)
     TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
 
-  release_tree_vector (vector);
   return bases_vec;
 }
 
@@ -4056,27 +4155,24 @@ calculate_bases (tree type, tsubst_flags_t complain)
       || !NON_UNION_CLASS_TYPE_P (type))
     return make_tree_vec (0);
 
-  vec<tree, va_gc> *vector = make_tree_vector ();
+  releasing_vec vector;
   tree bases_vec = NULL_TREE;
   unsigned i;
   vec<tree, va_gc> *vbases;
-  vec<tree, va_gc> *nonvbases;
   tree binfo;
 
   /* First go through virtual base classes */
   for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0;
        vec_safe_iterate (vbases, i, &binfo); i++)
     {
-      vec<tree, va_gc> *vbase_bases
+      releasing_vec vbase_bases
        = calculate_bases_helper (BINFO_TYPE (binfo));
       vec_safe_splice (vector, vbase_bases);
-      release_tree_vector (vbase_bases);
     }
 
   /* Now for the non-virtual bases */
-  nonvbases = calculate_bases_helper (type);
+  releasing_vec nonvbases = calculate_bases_helper (type);
   vec_safe_splice (vector, nonvbases);
-  release_tree_vector (nonvbases);
 
   /* Note that during error recovery vector->length can even be zero.  */
   if (vector->length () > 1)
@@ -4090,7 +4186,6 @@ calculate_bases (tree type, tsubst_flags_t complain)
   else
     bases_vec = make_tree_vec (0);
 
-  release_tree_vector (vector);
   return bases_vec;
 }
 
@@ -4102,7 +4197,7 @@ finish_bases (tree type, bool direct)
   if (!processing_template_decl)
     {
       /* Parameter packs can only be used in templates */
-      error ("Parameter pack __bases only valid in template declaration");
+      error ("parameter pack %<__bases%> only valid in template declaration");
       return error_mark_node;
     }
 
@@ -4129,14 +4224,16 @@ finish_offsetof (tree object_ptr, tree expr, location_t loc)
       return expr;
     }
 
+  if (expr == error_mark_node)
+    return error_mark_node;
+
   if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
     {
       error ("cannot apply %<offsetof%> to destructor %<~%T%>",
              TREE_OPERAND (expr, 2));
       return error_mark_node;
     }
-  if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
-      || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
+  if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr))
       || TREE_TYPE (expr) == unknown_type_node)
     {
       while (TREE_CODE (expr) == COMPONENT_REF
@@ -4165,7 +4262,7 @@ finish_offsetof (tree object_ptr, tree expr, location_t loc)
       && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (object_ptr)))
       && CLASSTYPE_NON_STD_LAYOUT (TREE_TYPE (TREE_TYPE (object_ptr)))
       && cp_unevaluated_operand == 0)
-    warning_at (loc, OPT_Winvalid_offsetof, "offsetof within "
+    warning_at (loc, OPT_Winvalid_offsetof, "%<offsetof%> within "
                "non-standard-layout type %qT is conditionally-supported",
                TREE_TYPE (TREE_TYPE (object_ptr)));
   return fold_offsetof (expr);
@@ -4320,7 +4417,9 @@ expand_or_defer_fn_1 (tree fn)
       if (DECL_INTERFACE_KNOWN (fn))
        /* We've already made a decision as to how this function will
           be handled.  */;
-      else if (!at_eof)
+      else if (!at_eof
+              || DECL_IMMEDIATE_FUNCTION_P (fn)
+              || DECL_OMP_DECLARE_REDUCTION_P (fn))
        tentative_decl_linkage (fn);
       else
        import_export_decl (fn);
@@ -4331,6 +4430,8 @@ expand_or_defer_fn_1 (tree fn)
         be emitted; there may be callers in other DLLs.  */
       if (DECL_DECLARED_INLINE_P (fn)
          && !DECL_REALLY_EXTERN (fn)
+         && !DECL_IMMEDIATE_FUNCTION_P (fn)
+         && !DECL_OMP_DECLARE_REDUCTION_P (fn)
          && (flag_keep_inline_functions
              || (flag_keep_inline_dllexport
                  && lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))))
@@ -4363,6 +4464,9 @@ expand_or_defer_fn_1 (tree fn)
       return false;
     }
 
+  if (DECL_OMP_DECLARE_REDUCTION_P (fn))
+    return false;
+
   return true;
 }
 
@@ -4381,8 +4485,9 @@ expand_or_defer_fn (tree fn)
     }
 }
 
-struct nrv_data
+class nrv_data
 {
+public:
   nrv_data () : visited (37) {}
 
   tree var;
@@ -4395,7 +4500,7 @@ struct nrv_data
 static tree
 finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
 {
-  struct nrv_data *dp = (struct nrv_data *)data;
+  class nrv_data *dp = (class nrv_data *)data;
   tree_node **slot;
 
   /* No need to walk into types.  There wouldn't be any need to walk into
@@ -4453,7 +4558,7 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
 void
 finalize_nrv (tree *tp, tree var, tree result)
 {
-  struct nrv_data data;
+  class nrv_data data;
 
   /* Copy name from VAR to RESULT.  */
   DECL_NAME (result) = DECL_NAME (var);
@@ -4951,6 +5056,17 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
       TREE_PURPOSE (t) = lb;
       low_bound = lb;
     }
+  /* Temporarily disable -fstrong-eval-order for array reductions.
+     The SAVE_EXPR and COMPOUND_EXPR added if low_bound has side-effects
+     is something the middle-end can't cope with and more importantly,
+     it needs to be the actual base variable that is privatized, not some
+     temporary assigned previous value of it.  That, together with OpenMP
+     saying how many times the side-effects are evaluated is unspecified,
+     makes int *a, *b; ... reduction(+:a[a = b, 3:10]) really unspecified.  */
+  warning_sentinel s (flag_strong_eval_order,
+                     OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+                     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
+                     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION);
   ret = grok_array_decl (OMP_CLAUSE_LOCATION (c), ret, low_bound, false);
   return ret;
 }
@@ -5532,8 +5648,7 @@ cp_check_omp_declare_reduction (tree udr)
          return;
        }
     }
-  else if (TREE_CODE (type) == FUNCTION_TYPE
-          || TREE_CODE (type) == METHOD_TYPE
+  else if (FUNC_OR_METHOD_TYPE_P (type)
           || TREE_CODE (type) == ARRAY_TYPE)
     {
       error_at (loc, "function or array type %qT in "
@@ -5548,8 +5663,8 @@ cp_check_omp_declare_reduction (tree udr)
     }
   else if (TYPE_QUALS_NO_ADDR_SPACE (type))
     {
-      error_at (loc, "const, volatile or __restrict qualified type %qT in "
-                    "%<#pragma omp declare reduction%>", type);
+      error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified "
+               "type %qT in %<#pragma omp declare reduction%>", type);
       return;
     }
 
@@ -6128,10 +6243,14 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
   bool branch_seen = false;
   bool copyprivate_seen = false;
   bool ordered_seen = false;
+  bool order_seen = false;
+  bool schedule_seen = false;
   bool oacc_async = false;
   tree last_iterators = NULL_TREE;
   bool last_iterators_remove = false;
-  bool reduction_seen = false;
+  /* 1 if normal/task reduction has been seen, -1 if inscan reduction
+     has been seen, -2 if mixed inscan/normal reduction diagnosed.  */
+  int reduction_seen = 0;
 
   bitmap_obstack_initialize (NULL);
   bitmap_initialize (&generic_head, &bitmap_default_obstack);
@@ -6141,7 +6260,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
   /* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead.  */
   bitmap_initialize (&map_head, &bitmap_default_obstack);
   bitmap_initialize (&map_field_head, &bitmap_default_obstack);
-  /* If ort == C_ORT_OMP used as nontemporal_head instead.  */
+  /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head
+     instead.  */
   bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack);
 
   if (ort & C_ORT_ACC)
@@ -6166,7 +6286,17 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
          field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
          goto check_dup_generic;
        case OMP_CLAUSE_REDUCTION:
-         reduction_seen = true;
+         if (reduction_seen == 0)
+           reduction_seen = OMP_CLAUSE_REDUCTION_INSCAN (c) ? -1 : 1;
+         else if (reduction_seen != -2
+                  && reduction_seen != (OMP_CLAUSE_REDUCTION_INSCAN (c)
+                                        ? -1 : 1))
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
+                       "%<inscan%> and non-%<inscan%> %<reduction%> clauses "
+                       "on the same construct");
+             reduction_seen = -2;
+           }
          /* FALLTHRU */
        case OMP_CLAUSE_IN_REDUCTION:
        case OMP_CLAUSE_TASK_REDUCTION:
@@ -6179,6 +6309,15 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                  remove = true;
                  break;
                }
+             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+                 && OMP_CLAUSE_REDUCTION_INSCAN (c))
+               {
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "%<inscan%> %<reduction%> clause with array "
+                           "section");
+                 remove = true;
+                 break;
+               }
              if (TREE_CODE (t) == TREE_LIST)
                {
                  while (TREE_CODE (t) == TREE_LIST)
@@ -6380,13 +6519,19 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                          omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
              remove = true;
            }
-         else if (ort == C_ORT_ACC
-                  && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
+         else if ((ort == C_ORT_ACC
+                   && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
+                  || (ort == C_ORT_OMP
+                      && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
+                          || (OMP_CLAUSE_CODE (c)
+                              == OMP_CLAUSE_USE_DEVICE_ADDR))))
            {
              if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
                {
                  error_at (OMP_CLAUSE_LOCATION (c),
-                           "%qD appears more than once in reduction clauses",
+                           ort == C_ORT_ACC
+                           ? "%qD appears more than once in reduction clauses"
+                           : "%qD appears more than once in data clauses",
                            t);
                  remove = true;
                }
@@ -6686,6 +6831,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                }
              OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
            }
+         if (!remove)
+           schedule_seen = true;
          break;
 
        case OMP_CLAUSE_SIMDLEN:
@@ -7033,7 +7180,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                remove = true;
              else
                {
-                 t = cp_build_indirect_ref (addr, RO_UNARY_STAR,
+                 t = cp_build_indirect_ref (OMP_CLAUSE_LOCATION (c),
+                                            addr, RO_UNARY_STAR,
                                             tf_warning_or_error);
                  if (t == error_mark_node)
                    remove = true;
@@ -7068,6 +7216,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                                "array section does not have mappable type "
                                "in %qs clause",
                                omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+                     cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
                      remove = true;
                    }
                  while (TREE_CODE (t) == ARRAY_REF)
@@ -7136,6 +7285,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                  error_at (OMP_CLAUSE_LOCATION (c),
                            "%qE does not have a mappable type in %qs clause",
                            t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+                 cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
                  remove = true;
                }
              while (TREE_CODE (t) == COMPONENT_REF)
@@ -7214,6 +7364,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
              error_at (OMP_CLAUSE_LOCATION (c),
                        "%qD does not have a mappable type in %qs clause", t,
                        omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+             cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
              remove = true;
            }
          else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
@@ -7362,6 +7513,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
              error_at (OMP_CLAUSE_LOCATION (c),
                        "%qD does not have a mappable type in %qs clause", t,
                        omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+             cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
              remove = true;
            }
          if (remove)
@@ -7494,20 +7646,41 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            {
              tree type = TREE_TYPE (t);
              if (!TYPE_PTR_P (type)
-                 && TREE_CODE (type) != ARRAY_TYPE
-                 && (!TYPE_REF_P (type)
-                     || (!TYPE_PTR_P (TREE_TYPE (type))
-                         && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)))
+                 && (!TYPE_REF_P (type) || !TYPE_PTR_P (TREE_TYPE (type))))
                {
-                 error_at (OMP_CLAUSE_LOCATION (c),
-                           "%qs variable is neither a pointer, nor an array "
-                           "nor reference to pointer or array",
-                           omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
-                 remove = true;
+                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
+                     && ort == C_ORT_OMP)
+                   {
+                     error_at (OMP_CLAUSE_LOCATION (c),
+                               "%qs variable is neither a pointer "
+                               "nor reference to pointer",
+                               omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+                     remove = true;
+                   }
+                 else if (TREE_CODE (type) != ARRAY_TYPE
+                          && (!TYPE_REF_P (type)
+                              || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
+                   {
+                     error_at (OMP_CLAUSE_LOCATION (c),
+                               "%qs variable is neither a pointer, nor an "
+                               "array nor reference to pointer or array",
+                               omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+                     remove = true;
+                   }
                }
            }
          goto check_dup_generic;
 
+       case OMP_CLAUSE_USE_DEVICE_ADDR:
+         field_ok = true;
+         t = OMP_CLAUSE_DECL (c);
+         if (!processing_template_decl
+             && (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
+             && !TYPE_REF_P (TREE_TYPE (t))
+             && !cxx_mark_addressable (t))
+           remove = true;
+         goto check_dup_generic;
+
        case OMP_CLAUSE_NOWAIT:
        case OMP_CLAUSE_DEFAULT:
        case OMP_CLAUSE_UNTIED:
@@ -7518,10 +7691,12 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
        case OMP_CLAUSE_SECTIONS:
        case OMP_CLAUSE_TASKGROUP:
        case OMP_CLAUSE_PROC_BIND:
+       case OMP_CLAUSE_DEVICE_TYPE:
        case OMP_CLAUSE_NOGROUP:
        case OMP_CLAUSE_THREADS:
        case OMP_CLAUSE_SIMD:
        case OMP_CLAUSE_DEFAULTMAP:
+       case OMP_CLAUSE_BIND:
        case OMP_CLAUSE_AUTO:
        case OMP_CLAUSE_INDEPENDENT:
        case OMP_CLAUSE_SEQ:
@@ -7573,6 +7748,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
          ordered_seen = true;
          break;
 
+       case OMP_CLAUSE_ORDER:
+         if (order_seen)
+           remove = true;
+         else
+           order_seen = true;
+         break;
+
        case OMP_CLAUSE_INBRANCH:
        case OMP_CLAUSE_NOTINBRANCH:
          if (branch_seen)
@@ -7585,6 +7767,37 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
          branch_seen = true;
          break;
 
+       case OMP_CLAUSE_INCLUSIVE:
+       case OMP_CLAUSE_EXCLUSIVE:
+         t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
+         if (!t)
+           t = OMP_CLAUSE_DECL (c);
+         if (t == current_class_ptr)
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
+                       "%<this%> allowed in OpenMP only in %<declare simd%>"
+                       " clauses");
+             remove = true;
+             break;
+           }
+         if (!VAR_P (t)
+             && TREE_CODE (t) != PARM_DECL
+             && TREE_CODE (t) != FIELD_DECL)
+           {
+             if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
+               break;
+             if (DECL_P (t))
+               error_at (OMP_CLAUSE_LOCATION (c),
+                         "%qD is not a variable in clause %qs", t,
+                         omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+             else
+               error_at (OMP_CLAUSE_LOCATION (c),
+                         "%qE is not a variable in clause %qs", t,
+                         omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+             remove = true;
+           }
+         break;
+
        default:
          gcc_unreachable ();
        }
@@ -7595,6 +7808,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
        pc = &OMP_CLAUSE_CHAIN (c);
     }
 
+  if (reduction_seen < 0 && (ordered_seen || schedule_seen))
+    reduction_seen = -2;
+
   for (pc = &clauses, c = clauses; c ; c = *pc)
     {
       enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
@@ -7630,8 +7846,16 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
          need_implicitly_determined = true;
          break;
        case OMP_CLAUSE_REDUCTION:
+         if (reduction_seen == -2)
+           OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
+         if (OMP_CLAUSE_REDUCTION_INSCAN (c))
+           need_copy_assignment = true;
+         need_implicitly_determined = true;
+         break;
        case OMP_CLAUSE_IN_REDUCTION:
        case OMP_CLAUSE_TASK_REDUCTION:
+       case OMP_CLAUSE_INCLUSIVE:
+       case OMP_CLAUSE_EXCLUSIVE:
          need_implicitly_determined = true;
          break;
        case OMP_CLAUSE_LINEAR:
@@ -7682,6 +7906,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                  (OMP_CLAUSE_SCHEDULE_KIND (c)
                   & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
            }
+         if (reduction_seen == -2)
+           error_at (OMP_CLAUSE_LOCATION (c),
+                     "%qs clause specified together with %<inscan%> "
+                     "%<reduction%> clause", "schedule");
          pc = &OMP_CLAUSE_CHAIN (c);
          continue;
        case OMP_CLAUSE_NOGROUP:
@@ -7695,6 +7923,24 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            }
          pc = &OMP_CLAUSE_CHAIN (c);
          continue;
+       case OMP_CLAUSE_ORDERED:
+         if (reduction_seen == -2)
+           error_at (OMP_CLAUSE_LOCATION (c),
+                     "%qs clause specified together with %<inscan%> "
+                     "%<reduction%> clause", "ordered");
+         pc = &OMP_CLAUSE_CHAIN (c);
+         continue;
+       case OMP_CLAUSE_ORDER:
+         if (ordered_seen)
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
+                       "%<order%> clause must not be used together "
+                       "with %<ordered%>");
+             *pc = OMP_CLAUSE_CHAIN (c);
+             continue;
+           }
+         pc = &OMP_CLAUSE_CHAIN (c);
+         continue;
        case OMP_CLAUSE_NOWAIT:
          if (copyprivate_seen)
            {
@@ -7756,7 +8002,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
          t = require_complete_type (t);
          if (t == error_mark_node)
            remove = true;
-         else if (TYPE_REF_P (TREE_TYPE (t))
+         else if (!processing_template_decl
+                  && TYPE_REF_P (TREE_TYPE (t))
                   && !complete_type_or_else (TREE_TYPE (TREE_TYPE (t)), t))
            remove = true;
        }
@@ -7771,6 +8018,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
              break;
            case OMP_CLAUSE_DEFAULT_SHARED:
+             if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
+                  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
+                 && c_omp_predefined_variable (t))
+               /* The __func__ variable and similar function-local predefined
+                  variables may be listed in a shared or firstprivate
+                  clause.  */
+               break;
              if (VAR_P (t)
                  && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
                  && TREE_STATIC (t)
@@ -7956,7 +8210,7 @@ restore_omp_privatization_clauses (vec<tree> &save)
       save.release ();
       return;
     }
-    
+
   omp_private_member_map = new hash_map <tree, tree>;
   while (!save.is_empty ())
     {
@@ -8168,7 +8422,6 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
   if (init && EXPR_HAS_LOCATION (init))
     elocus = EXPR_LOCATION (init);
 
-  cond = cp_fully_fold (cond);
   switch (TREE_CODE (cond))
     {
     case GT_EXPR:
@@ -8319,24 +8572,25 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
 
   incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error);
   incr = cp_fully_fold (incr);
-  bool taskloop_iv_seen = false;
+  tree loop_iv_seen = NULL_TREE;
   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
        && OMP_CLAUSE_DECL (c) == iter)
       {
-       if (code == OMP_TASKLOOP)
+       if (code == OMP_TASKLOOP || code == OMP_LOOP)
          {
-           taskloop_iv_seen = true;
-           OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c) = 1;
+           loop_iv_seen = c;
+           OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) = 1;
          }
        break;
       }
-    else if (code == OMP_TASKLOOP
+    else if ((code == OMP_TASKLOOP || code == OMP_LOOP)
             && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
             && OMP_CLAUSE_DECL (c) == iter)
       {
-       taskloop_iv_seen = true;
-       OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1;
+       loop_iv_seen = c;
+       if (code == OMP_TASKLOOP)
+         OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1;
       }
 
   decl = create_temporary_var (TREE_TYPE (diff));
@@ -8356,7 +8610,7 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
   tree diffvar = NULL_TREE;
   if (code == OMP_TASKLOOP)
     {
-      if (!taskloop_iv_seen)
+      if (!loop_iv_seen)
        {
          tree ivc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
          OMP_CLAUSE_DECL (ivc) = iter;
@@ -8372,6 +8626,28 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
       pushdecl (diffvar);
       add_decl_expr (diffvar);
     }
+  else if (code == OMP_LOOP)
+    {
+      if (!loop_iv_seen)
+       {
+         /* While iterators on the loop construct are predetermined
+            lastprivate, if the decl is not declared inside of the
+            loop, OMP_CLAUSE_LASTPRIVATE should have been added
+            already.  */
+         loop_iv_seen = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
+         OMP_CLAUSE_DECL (loop_iv_seen) = iter;
+         OMP_CLAUSE_CHAIN (loop_iv_seen) = clauses;
+         clauses = loop_iv_seen;
+       }
+      else if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_PRIVATE)
+       {
+         OMP_CLAUSE_PRIVATE_DEBUG (loop_iv_seen) = 0;
+         OMP_CLAUSE_PRIVATE_OUTER_REF (loop_iv_seen) = 0;
+         OMP_CLAUSE_CODE (loop_iv_seen) = OMP_CLAUSE_FIRSTPRIVATE;
+       }
+      if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_FIRSTPRIVATE)
+       cxx_omp_finish_clause (loop_iv_seen, NULL);
+    }
 
   orig_pre_body = *pre_body;
   *pre_body = push_stmt_list ();
@@ -8722,9 +8998,7 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
     omp_for = NULL_TREE;
 
   if (omp_for == NULL)
-    {
-      return NULL;
-    }
+    return NULL;
 
   add_stmt (omp_for);
 
@@ -8823,6 +9097,16 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
              gcc_unreachable ();
            }
        }
+  /* Override saved methods on OMP_LOOP's OMP_CLAUSE_LASTPRIVATE_LOOP_IV
+     clauses, we need copy ctor for those rather than default ctor,
+     plus as for other lastprivates assignment op and dtor.  */
+  if (code == OMP_LOOP && !processing_template_decl)
+    for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+         && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
+         && cxx_omp_create_clause_info (c, TREE_TYPE (OMP_CLAUSE_DECL (c)),
+                                        false, true, true, true))
+       CP_OMP_CLAUSE_INFO (c) = NULL_TREE;
 
   return omp_for;
 }
@@ -8970,7 +9254,7 @@ finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
        {
          if (opcode == NOP_EXPR)
            stmt = build2 (MODIFY_EXPR, void_type_node, orig_lhs, orig_rhs);
-         else 
+         else
            stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs);
          if (orig_rhs1)
            stmt = build_min_nt_loc (EXPR_LOCATION (orig_rhs1),
@@ -8987,6 +9271,11 @@ finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
       OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
       SET_EXPR_LOCATION (stmt, loc);
     }
+
+  /* Avoid -Wunused-value warnings here, the whole construct has side-effects
+     and even if it might be wrapped from fold-const.c or c-omp.c wrapped
+     in some tree that appears to be unused, the value is not unused.  */
+  warning_sentinel w (warn_unused_value);
   finish_expr_stmt (stmt);
 }
 
@@ -8994,9 +9283,8 @@ void
 finish_omp_barrier (void)
 {
   tree fn = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
-  vec<tree, va_gc> *vec = make_tree_vector ();
+  releasing_vec vec;
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
-  release_tree_vector (vec);
   finish_expr_stmt (stmt);
 }
 
@@ -9028,7 +9316,7 @@ finish_omp_depobj (location_t loc, tree depobj,
       if (addr == error_mark_node)
        depobj = error_mark_node;
       else
-       depobj = cp_build_indirect_ref (addr, RO_UNARY_STAR,
+       depobj = cp_build_indirect_ref (loc, addr, RO_UNARY_STAR,
                                        tf_warning_or_error);
     }
 
@@ -9039,14 +9327,13 @@ void
 finish_omp_flush (int mo)
 {
   tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
-  vec<tree, va_gc> *vec = make_tree_vector ();
+  releasing_vec vec;
   if (mo != MEMMODEL_LAST)
     {
       fn = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
       vec->quick_push (build_int_cst (integer_type_node, mo));
     }
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
-  release_tree_vector (vec);
   finish_expr_stmt (stmt);
 }
 
@@ -9054,9 +9341,8 @@ void
 finish_omp_taskwait (void)
 {
   tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
-  vec<tree, va_gc> *vec = make_tree_vector ();
+  releasing_vec vec;
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
-  release_tree_vector (vec);
   finish_expr_stmt (stmt);
 }
 
@@ -9064,9 +9350,8 @@ void
 finish_omp_taskyield (void)
 {
   tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
-  vec<tree, va_gc> *vec = make_tree_vector ();
+  releasing_vec vec;
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
-  release_tree_vector (vec);
   finish_expr_stmt (stmt);
 }
 
@@ -9089,7 +9374,7 @@ finish_omp_cancel (tree clauses)
             "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
       return;
     }
-  vec<tree, va_gc> *vec = make_tree_vector ();
+  releasing_vec vec;
   tree ifc = omp_find_clause (clauses, OMP_CLAUSE_IF);
   if (ifc != NULL_TREE)
     {
@@ -9123,7 +9408,6 @@ finish_omp_cancel (tree clauses)
   vec->quick_push (build_int_cst (integer_type_node, mask));
   vec->quick_push (ifc);
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
-  release_tree_vector (vec);
   finish_expr_stmt (stmt);
 }
 
@@ -9146,10 +9430,9 @@ finish_omp_cancellation_point (tree clauses)
             "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
       return;
     }
-  vec<tree, va_gc> *vec
+  releasing_vec vec
     = make_tree_vector_single (build_int_cst (integer_type_node, mask));
   tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
-  release_tree_vector (vec);
   finish_expr_stmt (stmt);
 }
 \f
@@ -9242,8 +9525,8 @@ init_cp_semantics (void)
    CONDITION and the message text MESSAGE.  LOCATION is the location
    of the static assertion in the source code.  When MEMBER_P, this
    static assertion is a member of a class.  */
-void 
-finish_static_assert (tree condition, tree message, location_t location, 
+void
+finish_static_assert (tree condition, tree message, location_t location,
                       bool member_p)
 {
   tsubst_flags_t complain = tf_warning_or_error;
@@ -9269,7 +9552,7 @@ finish_static_assert (tree condition, tree message, location_t location,
       STATIC_ASSERT_SOURCE_LOCATION (assertion) = location;
 
       if (member_p)
-        maybe_add_class_template_decl_list (current_class_type, 
+        maybe_add_class_template_decl_list (current_class_type,
                                             assertion,
                                             /*friend_p=*/0);
       else
@@ -9278,6 +9561,9 @@ finish_static_assert (tree condition, tree message, location_t location,
       return;
     }
 
+  /* Save the condition in case it was a concept check.  */
+  tree orig_condition = condition;
+
   /* Fold the expression and convert it to a boolean value. */
   condition = perform_implicit_conversion_flags (boolean_type_node, condition,
                                                 complain, LOOKUP_NORMAL);
@@ -9287,12 +9573,12 @@ finish_static_assert (tree condition, tree message, location_t location,
   if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
     /* Do nothing; the condition is satisfied. */
     ;
-  else 
+  else
     {
       location_t saved_loc = input_location;
 
       input_location = location;
-      if (TREE_CODE (condition) == INTEGER_CST 
+      if (TREE_CODE (condition) == INTEGER_CST
           && integer_zerop (condition))
        {
          int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
@@ -9304,6 +9590,10 @@ finish_static_assert (tree condition, tree message, location_t location,
          else
             error ("static assertion failed: %s",
                   TREE_STRING_POINTER (message));
+
+         /* Actually explain the failure if this is a concept check.  */
+         if (concept_check_p (orig_condition))
+           diagnose_constraints (location, orig_condition, NULL_TREE);
        }
       else if (condition && condition != error_mark_node)
        {
@@ -9337,7 +9627,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
          && TYPE_P (TREE_OPERAND (expr, 0))))
     {
       if (complain & tf_error)
-       error ("argument to decltype must be an expression");
+       error ("argument to %<decltype%> must be an expression");
       return error_mark_node;
     }
 
@@ -9365,7 +9655,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
   if (type_unknown_p (expr))
     {
       if (complain & tf_error)
-       error ("decltype cannot resolve address of overloaded function");
+       error ("%<decltype%> cannot resolve address of overloaded function");
       return error_mark_node;
     }
 
@@ -9507,7 +9797,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
   return type;
 }
 
-/* Called from trait_expr_value to evaluate either __has_nothrow_assign or 
+/* Called from trait_expr_value to evaluate either __has_nothrow_assign or
    __has_nothrow_copy, depending on assign_p.  Returns true iff all
    the copy {ctor,assign} fns are nothrow.  */
 
@@ -9528,8 +9818,8 @@ classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
       if (copy_fn_p (fn) > 0)
        {
          saw_copy = true;
-         maybe_instantiate_noexcept (fn);
-         if (!TYPE_NOTHROW_P (TREE_TYPE (fn)))
+         if (!maybe_instantiate_noexcept (fn)
+             || !TYPE_NOTHROW_P (TREE_TYPE (fn)))
            return false;
        }
     }
@@ -9568,11 +9858,11 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
 
     case CPTK_HAS_NOTHROW_CONSTRUCTOR:
       type1 = strip_array_types (type1);
-      return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2) 
+      return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
              || (CLASS_TYPE_P (type1)
                  && (t = locate_ctor (type1))
-                 && (maybe_instantiate_noexcept (t),
-                     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);
@@ -9695,7 +9985,7 @@ check_trait_type (tree type)
 /* Process a trait expression.  */
 
 tree
-finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
+finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
 {
   if (type1 == error_mark_node
       || type2 == error_mark_node)
@@ -9708,6 +9998,7 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
       TRAIT_EXPR_TYPE1 (trait_expr) = type1;
       TRAIT_EXPR_TYPE2 (trait_expr) = type2;
       TRAIT_EXPR_KIND (trait_expr) = kind;
+      TRAIT_EXPR_LOCATION (trait_expr) = loc;
       return trait_expr;
     }
 
@@ -9765,8 +10056,9 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
       gcc_unreachable ();
     }
 
-  return (trait_expr_value (kind, type1, type2)
-         ? boolean_true_node : boolean_false_node);
+tree val = (trait_expr_value (kind, type1, type2)
+           ? boolean_true_node : boolean_false_node);
+ return maybe_wrap_with_location (val, loc);
 }
 
 /* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
@@ -9847,7 +10139,6 @@ apply_deduced_return_type (tree fco, tree return_type)
 #endif
       cfun->returns_struct = aggr;
     }
-
 }
 
 /* DECL is a local variable or parameter from the surrounding scope of a
@@ -9904,7 +10195,7 @@ capture_decltype (tree decl)
 static tree
 finish_unary_fold_expr (tree expr, int op, tree_code dir)
 {
-  // Build a pack expansion (assuming expr has pack type).
+  /* Build a pack expansion (assuming expr has pack type).  */
   if (!uses_parameter_packs (expr))
     {
       error_at (location_of (expr), "operand of fold expression has no "
@@ -9913,7 +10204,7 @@ finish_unary_fold_expr (tree expr, int op, tree_code dir)
     }
   tree pack = make_pack_expansion (expr);
 
-  // Build the fold expression.
+  /* Build the fold expression.  */
   tree code = build_int_cstu (integer_type_node, abs (op));
   tree fold = build_min_nt_loc (UNKNOWN_LOCATION, dir, code, pack);
   FOLD_EXPR_MODIFY_P (fold) = (op < 0);
@@ -10002,7 +10293,7 @@ cp_build_vec_convert (tree arg, location_t loc, tree type,
 
   tree ret = NULL_TREE;
   if (!type_dependent_expression_p (arg) && !dependent_type_p (type))
-    ret = c_build_vec_convert (cp_expr_loc_or_loc (arg, input_location), arg,
+    ret = c_build_vec_convert (cp_expr_loc_or_input_loc (arg), arg,
                               loc, type, (complain & tf_error) != 0);
 
   if (!processing_template_decl)