c++: Yet more name-lookup api simplification
[gcc.git] / gcc / cp / semantics.c
index 56f70a0a58929b52cff9940cf346d4baac977aee..da452c58daaf7e74a908e190eeca6b7aa427d08b 100644 (file)
@@ -3,7 +3,7 @@
    building RTL.  These routines are used both during actual parsing
    and during the instantiation of template functions.
 
-   Copyright (C) 1998-2019 Free Software Foundation, Inc.
+   Copyright (C) 1998-2020 Free Software Foundation, Inc.
    Written by Mark Mitchell (mmitchell@usa.net) based on code found
    formerly in parse.y and pt.c.
 
@@ -127,11 +127,10 @@ struct GTY(()) deferred_access {
        A::B* A::f() { return 0; }
 
      is valid, even though `A::B' is not generally accessible.  */
-  vec<deferred_access_check, va_gc> * GTY(()) deferred_access_checks;
+  vec<deferred_access_check, va_gc> *deferred_access_checks;
 
   /* The current mode of access checks.  */
   enum deferring_kind deferring_access_checks_kind;
-
 };
 
 /* Data for deferred access checking.  */
@@ -257,6 +256,75 @@ pop_to_parent_deferring_access_checks (void)
     }
 }
 
+/* If the current scope isn't allowed to access DECL along
+   BASETYPE_PATH, give an error, or if we're parsing a function or class
+   template, defer the access check to be performed at instantiation time.
+   The most derived class in BASETYPE_PATH is the one used to qualify DECL.
+   DIAG_DECL is the declaration to use in the error diagnostic.  */
+
+static bool
+enforce_access (tree basetype_path, tree decl, tree diag_decl,
+               tsubst_flags_t complain, access_failure_info *afi = NULL)
+{
+  gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
+
+  if (flag_new_inheriting_ctors
+      && DECL_INHERITED_CTOR (decl))
+    {
+      /* 7.3.3/18: The additional constructors are accessible if they would be
+        accessible when used to construct an object of the corresponding base
+        class.  */
+      decl = strip_inheriting_ctors (decl);
+      basetype_path = lookup_base (basetype_path, DECL_CONTEXT (decl),
+                                  ba_any, NULL, complain);
+    }
+
+  tree cs = current_scope ();
+  if (processing_template_decl
+      && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
+    if (tree template_info = get_template_info (cs))
+      {
+       /* When parsing a function or class template, we in general need to
+          defer access checks until template instantiation time, since a friend
+          declaration may grant access only to a particular specialization of
+          the template.  */
+
+       if (accessible_p (basetype_path, decl, /*consider_local_p=*/true))
+         /* But if the member is deemed accessible at parse time, then we can
+            assume it'll be accessible at instantiation time.  */
+         return true;
+
+       /* Access of a dependent decl should be rechecked after tsubst'ing
+          into the user of the decl, rather than explicitly deferring the
+          check here.  */
+       gcc_assert (!uses_template_parms (decl));
+       if (TREE_CODE (decl) == FIELD_DECL)
+         gcc_assert (!uses_template_parms (DECL_CONTEXT (decl)));
+
+       /* Defer this access check until instantiation time.  */
+       deferred_access_check access_check;
+       access_check.binfo = basetype_path;
+       access_check.decl = decl;
+       access_check.diag_decl = diag_decl;
+       access_check.loc = input_location;
+       vec_safe_push (TI_DEFERRED_ACCESS_CHECKS (template_info), access_check);
+       return true;
+      }
+
+  if (!accessible_p (basetype_path, decl, /*consider_local_p=*/true))
+    {
+      if (flag_new_inheriting_ctors)
+       diag_decl = strip_inheriting_ctors (diag_decl);
+      if (complain & tf_error)
+       complain_about_access (decl, diag_decl, true);
+      if (afi)
+       afi->record_access_failure (basetype_path, decl, diag_decl);
+      return false;
+    }
+
+  return true;
+}
+
 /* Perform the access checks in CHECKS.  The TREE_PURPOSE of each node
    is the BINFO indicating the qualifying scope used to access the
    DECL node stored in the TREE_VALUE of the node.  If CHECKS is empty
@@ -321,9 +389,7 @@ perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl,
   deferred_access *ptr;
   deferred_access_check *chk;
 
-
-  /* Exit if we are in a context that no access checking is performed.
-     */
+  /* Exit if we are in a context that no access checking is performed.  */
   if (deferred_access_no_check)
     return true;
 
@@ -380,7 +446,8 @@ add_stmt (tree t)
 
       /* When we expand a statement-tree, we must know whether or not the
         statements are full-expressions.  We record that fact here.  */
-      STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
+      if (STATEMENT_CODE_P (TREE_CODE (t)))
+       STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
     }
 
   if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
@@ -734,6 +801,9 @@ is_std_constant_evaluated_p (tree fn)
     return false;
 
   tree fndecl = cp_get_callee_fndecl_nofold (fn);
+  if (fndecl == NULL_TREE)
+    return false;
+
   if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
                         BUILT_IN_FRONTEND))
     return true;
@@ -1429,15 +1499,19 @@ finish_handler_parms (tree decl, tree handler)
          if (CLASS_TYPE_P (orig_type))
            {
              if (TYPE_POLYMORPHIC_P (orig_type))
-               warning (OPT_Wcatch_value_,
-                        "catching polymorphic type %q#T by value", orig_type);
+               warning_at (DECL_SOURCE_LOCATION (decl),
+                           OPT_Wcatch_value_,
+                           "catching polymorphic type %q#T by value",
+                           orig_type);
              else if (warn_catch_value > 1)
-               warning (OPT_Wcatch_value_,
-                        "catching type %q#T by value", orig_type);
+               warning_at (DECL_SOURCE_LOCATION (decl),
+                           OPT_Wcatch_value_,
+                           "catching type %q#T by value", orig_type);
            }
          else if (warn_catch_value > 2)
-           warning (OPT_Wcatch_value_,
-                    "catching non-reference type %q#T", orig_type);
+           warning_at (DECL_SOURCE_LOCATION (decl),
+                       OPT_Wcatch_value_,
+                       "catching non-reference type %q#T", orig_type);
        }
     }
   HANDLER_TYPE (handler) = type;
@@ -1788,10 +1862,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)
@@ -1799,7 +1873,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))
@@ -1985,70 +2059,34 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
   return ret;
 }
 
-/* If we are currently parsing a template and we encountered a typedef
-   TYPEDEF_DECL that is being accessed though CONTEXT, this function
-   adds the typedef to a list tied to the current template.
-   At template instantiation time, that list is walked and access check
-   performed for each typedef.
-   LOCATION is the location of the usage point of TYPEDEF_DECL.  */
-
-void
-add_typedef_to_current_template_for_access_check (tree typedef_decl,
-                                                  tree context,
-                                                 location_t location)
-{
-    tree template_info = NULL;
-    tree cs = current_scope ();
-
-    if (!is_typedef_decl (typedef_decl)
-       || !context
-       || !CLASS_TYPE_P (context)
-       || !cs)
-      return;
-
-    if (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL)
-      template_info = get_template_info (cs);
-
-    if (template_info
-       && TI_TEMPLATE (template_info)
-       && !currently_open_class (context))
-      append_type_to_template_for_access_check (cs, typedef_decl,
-                                               context, location);
-}
-
 /* DECL was the declaration to which a qualified-id resolved.  Issue
    an error message if it is not accessible.  If OBJECT_TYPE is
    non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the
    type of `*x', or `x', respectively.  If the DECL was named as
-   `A::B' then NESTED_NAME_SPECIFIER is `A'.  */
+   `A::B' then NESTED_NAME_SPECIFIER is `A'.  Return value is like
+   perform_access_checks above.  */
 
-void
+bool
 check_accessibility_of_qualified_id (tree decl,
                                     tree object_type,
-                                    tree nested_name_specifier)
+                                    tree nested_name_specifier,
+                                    tsubst_flags_t complain)
 {
-  tree scope;
-  tree qualifying_type = NULL_TREE;
-
-  /* If we are parsing a template declaration and if decl is a typedef,
-     add it to a list tied to the template.
-     At template instantiation time, that list will be walked and
-     access check performed.  */
-  add_typedef_to_current_template_for_access_check (decl,
-                                                   nested_name_specifier
-                                                   ? nested_name_specifier
-                                                   : DECL_CONTEXT (decl),
-                                                   input_location);
-
   /* If we're not checking, return immediately.  */
   if (deferred_access_no_check)
-    return;
+    return true;
 
   /* Determine the SCOPE of DECL.  */
-  scope = context_for_name_lookup (decl);
+  tree scope = context_for_name_lookup (decl);
   /* If the SCOPE is not a type, then DECL is not a member.  */
-  if (!TYPE_P (scope))
-    return;
+  if (!TYPE_P (scope)
+      /* If SCOPE is dependent then we can't perform this access check now,
+        and since we'll perform this access check again after substitution
+        there's no need to explicitly defer it.  */
+      || dependent_type_p (scope))
+    return true;
+
+  tree qualifying_type = NULL_TREE;
   /* Compute the scope through which DECL is being accessed.  */
   if (object_type
       /* OBJECT_TYPE might not be a class type; consider:
@@ -2087,10 +2125,11 @@ check_accessibility_of_qualified_id (tree decl,
   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)
-      && !dependent_type_p (qualifying_type))
-    perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
-                                  decl, tf_warning_or_error);
+      && CLASS_TYPE_P (qualifying_type))
+    return perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
+                                         decl, complain);
+
+  return true;
 }
 
 /* EXPR is the result of a qualified-id.  The QUALIFYING_CLASS was the
@@ -2500,7 +2539,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
              bool abnormal = true;
              for (lkp_iterator iter (fn); abnormal && iter; ++iter)
                {
-                 tree fndecl = *iter;
+                 tree fndecl = STRIP_TEMPLATE (*iter);
                  if (TREE_CODE (fndecl) != FUNCTION_DECL
                      || !TREE_THIS_VOLATILE (fndecl))
                    abnormal = false;
@@ -2589,6 +2628,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.  */
@@ -2640,7 +2696,6 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
              tree arg2 = (*orig_args)[2];
              int literal_mask = ((literal_integer_zerop (arg1) << 1)
                                  | (literal_integer_zerop (arg2) << 2));
-             arg2 = instantiate_non_dependent_expr (arg2);
              warn_for_memset (input_location, arg0, arg2, literal_mask);
            }
 
@@ -2652,12 +2707,16 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
     {
       if (!vec_safe_is_empty (*args))
        error ("arguments to destructor are not allowed");
-      /* Mark the pseudo-destructor call as having side-effects so
-        that we do not issue warnings about its use.  */
-      result = build1 (NOP_EXPR,
-                      void_type_node,
-                      TREE_OPERAND (fn, 0));
-      TREE_SIDE_EFFECTS (result) = 1;
+      /* C++20/DR: If the postfix-expression names a pseudo-destructor (in
+        which case the postfix-expression is a possibly-parenthesized class
+        member access), the function call destroys the object of scalar type
+        denoted by the object expression of the class member access.  */
+      tree ob = TREE_OPERAND (fn, 0);
+      if (obvalue_p (ob))
+       result = build_trivial_dtor_call (ob);
+      else
+       /* No location to clobber.  */
+       result = convert_to_void (ob, ICV_STATEMENT, complain);
     }
   else if (CLASS_TYPE_P (TREE_TYPE (fn)))
     /* If the "function" is really an object of class type, it might
@@ -2790,7 +2849,10 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor,
        }
     }
 
-  return build3_loc (loc, PSEUDO_DTOR_EXPR, void_type_node, object,
+  tree type = (type_dependent_expression_p (object)
+              ? NULL_TREE : void_type_node);
+
+  return build3_loc (loc, PSEUDO_DTOR_EXPR, type, object,
                     scope, destructor);
 }
 
@@ -2912,7 +2974,8 @@ finish_compound_literal (tree type, tree compound_literal,
         that it came from T{} rather than T({}).  */
       CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1;
       compound_literal = build_tree_list (NULL_TREE, compound_literal);
-      return build_functional_cast (type, compound_literal, complain);
+      return build_functional_cast (input_location, type,
+                                   compound_literal, complain);
     }
 
   if (TREE_CODE (type) == ARRAY_TYPE
@@ -3027,6 +3090,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.
@@ -3058,8 +3129,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);
@@ -3179,7 +3250,7 @@ begin_class_definition (tree t)
       SET_CLASSTYPE_INTERFACE_UNKNOWN_X
        (t, finfo->interface_unknown);
     }
-  reset_specialization();
+  reset_specialization ();
 
   /* Make a declaration for this class in its own scope.  */
   build_self_reference ();
@@ -3492,8 +3563,15 @@ tree
 process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
 {
   if (cp_unevaluated_operand)
-    /* It's not a use (3.2) if we're in an unevaluated context.  */
-    return decl;
+    {
+      tree type = TREE_TYPE (decl);
+      if (!dependent_type_p (type)
+         && variably_modified_type_p (type, NULL_TREE))
+       /* VLAs are used even in unevaluated context.  */;
+      else
+       /* It's not a use (3.2) if we're in an unevaluated context.  */
+       return decl;
+    }
   if (decl == error_mark_node)
     return decl;
 
@@ -3833,9 +3911,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)
            {
@@ -3851,12 +3930,18 @@ finish_id_expression_1 (tree id_expression,
        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)
@@ -4385,7 +4470,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);
@@ -4396,6 +4483,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)))))
@@ -4428,6 +4517,9 @@ expand_or_defer_fn_1 (tree fn)
       return false;
     }
 
+  if (DECL_OMP_DECLARE_REDUCTION_P (fn))
+    return false;
+
   return true;
 }
 
@@ -4700,7 +4792,6 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
        t = TREE_OPERAND (t, 0);
       ret = t;
       if (TREE_CODE (t) == COMPONENT_REF
-         && ort == C_ORT_OMP
          && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
              || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO
              || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM)
@@ -4724,6 +4815,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
                  return error_mark_node;
                }
              t = TREE_OPERAND (t, 0);
+             if (ort == C_ORT_ACC && TREE_CODE (t) == INDIRECT_REF)
+               t = TREE_OPERAND (t, 0);
            }
          if (REFERENCE_REF_P (t))
            t = TREE_OPERAND (t, 0);
@@ -4823,6 +4916,18 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
   if (low_bound == NULL_TREE)
     low_bound = integer_zero_node;
 
+  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
+      && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
+         || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH))
+    {
+      if (length != integer_one_node)
+       {
+         error_at (OMP_CLAUSE_LOCATION (c),
+                   "expected single pointer in %qs clause",
+                   c_omp_map_clause_name (c, ort == C_ORT_ACC));
+         return error_mark_node;
+       }
+    }
   if (length != NULL_TREE)
     {
       if (!integer_nonzerop (length))
@@ -5017,6 +5122,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;
 }
@@ -5237,6 +5353,7 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort)
            switch (OMP_CLAUSE_MAP_KIND (c))
              {
              case GOMP_MAP_ALLOC:
+             case GOMP_MAP_IF_PRESENT:
              case GOMP_MAP_TO:
              case GOMP_MAP_FROM:
              case GOMP_MAP_TOFROM:
@@ -5259,12 +5376,18 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort)
          if ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP && ort != C_ORT_ACC)
            OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_POINTER);
          else if (TREE_CODE (t) == COMPONENT_REF)
-           OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER);
+           {
+             gomp_map_kind k = (ort == C_ORT_ACC) ? GOMP_MAP_ATTACH_DETACH
+                                                  : GOMP_MAP_ALWAYS_POINTER;
+             OMP_CLAUSE_SET_MAP_KIND (c2, k);
+           }
          else if (REFERENCE_REF_P (t)
                   && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF)
            {
              t = TREE_OPERAND (t, 0);
-             OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER);
+             gomp_map_kind k = (ort == C_ORT_ACC) ? GOMP_MAP_ATTACH_DETACH
+                                                  : GOMP_MAP_ALWAYS_POINTER;
+             OMP_CLAUSE_SET_MAP_KIND (c2, k);
            }
          else
            OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER);
@@ -5399,7 +5522,7 @@ omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp,
                                omp_reduction_id (ERROR_MARK,
                                                  TREE_OPERAND (id, 1),
                                                  type),
-                               false, false);
+                               LOOK_want::NORMAL, false);
   tree fns = id;
   id = NULL_TREE;
   if (fns && is_overloaded_fn (fns))
@@ -5867,9 +5990,11 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
              if (need_static_cast)
                {
                  tree rtype = build_reference_type (atype);
-                 omp_out = build_static_cast (rtype, omp_out,
+                 omp_out = build_static_cast (input_location,
+                                              rtype, omp_out,
                                               tf_warning_or_error);
-                 omp_in = build_static_cast (rtype, omp_in,
+                 omp_in = build_static_cast (input_location,
+                                             rtype, omp_in,
                                              tf_warning_or_error);
                  if (omp_out == error_mark_node || omp_in == error_mark_node)
                    return true;
@@ -5904,9 +6029,11 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
                      return true;
                    }
                  tree rtype = build_reference_type (atype);
-                 omp_priv = build_static_cast (rtype, omp_priv,
+                 omp_priv = build_static_cast (input_location,
+                                               rtype, omp_priv,
                                                tf_warning_or_error);
-                 omp_orig = build_static_cast (rtype, omp_orig,
+                 omp_orig = build_static_cast (input_location,
+                                               rtype, omp_orig,
                                                tf_warning_or_error);
                  if (omp_priv == error_mark_node
                      || omp_orig == error_mark_node)
@@ -6087,13 +6214,16 @@ cp_omp_finish_iterators (tree iter)
       begin = mark_rvalue_use (begin);
       end = mark_rvalue_use (end);
       step = mark_rvalue_use (step);
-      begin = cp_build_c_cast (type, begin, tf_warning_or_error);
-      end = cp_build_c_cast (type, end, tf_warning_or_error);
+      begin = cp_build_c_cast (input_location, type, begin,
+                              tf_warning_or_error);
+      end = cp_build_c_cast (input_location, type, end,
+                            tf_warning_or_error);
       orig_step = step;
       if (!processing_template_decl)
        step = orig_step = save_expr (step);
       tree stype = POINTER_TYPE_P (type) ? sizetype : type;
-      step = cp_build_c_cast (stype, step, tf_warning_or_error);
+      step = cp_build_c_cast (input_location, stype, step,
+                             tf_warning_or_error);
       if (POINTER_TYPE_P (type) && !processing_template_decl)
        {
          begin = save_expr (begin);
@@ -6180,6 +6310,41 @@ cp_omp_finish_iterators (tree iter)
   return ret;
 }
 
+/* Ensure that pointers are used in OpenACC attach and detach clauses.
+   Return true if an error has been detected.  */
+
+static bool
+cp_oacc_check_attachments (tree c)
+{
+  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
+    return false;
+
+  /* OpenACC attach / detach clauses must be pointers.  */
+  if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
+      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
+    {
+      tree t = OMP_CLAUSE_DECL (c);
+      tree type;
+
+      while (TREE_CODE (t) == TREE_LIST)
+       t = TREE_CHAIN (t);
+
+      type = TREE_TYPE (t);
+
+      if (TREE_CODE (type) == REFERENCE_TYPE)
+       type = TREE_TYPE (type);
+
+      if (TREE_CODE (type) != POINTER_TYPE)
+       {
+         error_at (OMP_CLAUSE_LOCATION (c), "expected pointer in %qs clause",
+                   c_omp_map_clause_name (c, true));
+         return true;
+       }
+    }
+
+  return false;
+}
+
 /* For all elements of CLAUSES, validate them vs OpenMP constraints.
    Remove any elements from the list that are invalid.  */
 
@@ -6444,7 +6609,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            t = OMP_CLAUSE_DECL (c);
        check_dup_generic_t:
          if (t == current_class_ptr
-             && (ort != C_ORT_OMP_DECLARE_SIMD
+             && ((ort != C_ORT_OMP_DECLARE_SIMD && ort != C_ORT_ACC)
                  || (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
                      && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_UNIFORM)))
            {
@@ -6514,8 +6679,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
        handle_field_decl:
          if (!remove
              && TREE_CODE (t) == FIELD_DECL
-             && t == OMP_CLAUSE_DECL (c)
-             && ort != C_ORT_ACC)
+             && t == OMP_CLAUSE_DECL (c))
            {
              OMP_CLAUSE_DECL (c)
                = omp_privatize_field (t, (OMP_CLAUSE_CODE (c)
@@ -6582,7 +6746,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
          else
            t = OMP_CLAUSE_DECL (c);
-         if (t == current_class_ptr)
+         if (ort != C_ORT_ACC && t == current_class_ptr)
            {
              error_at (OMP_CLAUSE_LOCATION (c),
                        "%<this%> allowed in OpenMP only in %<declare simd%>"
@@ -7071,7 +7235,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            }
          if (t == error_mark_node)
            remove = true;
-         else if (t == current_class_ptr)
+         else if (ort != C_ORT_ACC && t == current_class_ptr)
            {
              error_at (OMP_CLAUSE_LOCATION (c),
                        "%<this%> allowed in OpenMP only in %<declare simd%>"
@@ -7130,7 +7294,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;
@@ -7202,6 +7367,17 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                        }
                    }
                }
+             if (cp_oacc_check_attachments (c))
+               remove = true;
+             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
+                 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
+                     || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH))
+               /* In this case, we have a single array element which is a
+                  pointer, and we already set OMP_CLAUSE_SIZE in
+                  handle_omp_array_sections above.  For attach/detach clauses,
+                  reset the OMP_CLAUSE_SIZE (representing a bias) to zero
+                  here.  */
+               OMP_CLAUSE_SIZE (c) = size_zero_node;
              break;
            }
          if (t == error_mark_node)
@@ -7209,14 +7385,32 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
              remove = true;
              break;
            }
+         /* OpenACC attach / detach clauses must be pointers.  */
+         if (cp_oacc_check_attachments (c))
+           {
+             remove = true;
+             break;
+           }
+         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
+             && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
+                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH))
+           /* For attach/detach clauses, set OMP_CLAUSE_SIZE (representing a
+              bias) to zero here, so it is not set erroneously to the pointer
+              size later on in gimplify.c.  */
+           OMP_CLAUSE_SIZE (c) = size_zero_node;
          if (REFERENCE_REF_P (t)
              && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF)
            {
              t = TREE_OPERAND (t, 0);
              OMP_CLAUSE_DECL (c) = t;
            }
+         if (ort == C_ORT_ACC
+             && TREE_CODE (t) == COMPONENT_REF
+             && TREE_CODE (TREE_OPERAND (t, 0)) == INDIRECT_REF)
+           t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
          if (TREE_CODE (t) == COMPONENT_REF
-             && (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP
+             && ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP
+                 || ort == C_ORT_ACC)
              && OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_)
            {
              if (type_dependent_expression_p (t))
@@ -7266,7 +7460,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                break;
              if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
                  && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
-                     || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER))
+                     || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
+                     || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH))
                break;
              if (DECL_P (t))
                error_at (OMP_CLAUSE_LOCATION (c),
@@ -7348,7 +7543,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
              else
                bitmap_set_bit (&generic_head, DECL_UID (t));
            }
-         else if (bitmap_bit_p (&map_head, DECL_UID (t)))
+         else if (bitmap_bit_p (&map_head, DECL_UID (t))
+                  && (ort != C_ORT_ACC
+                      || !bitmap_bit_p (&map_field_head, DECL_UID (t))))
            {
              if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
                error_at (OMP_CLAUSE_LOCATION (c),
@@ -7403,7 +7600,12 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                  tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
                                              OMP_CLAUSE_MAP);
                  if (TREE_CODE (t) == COMPONENT_REF)
-                   OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER);
+                   {
+                     gomp_map_kind k
+                       = (ort == C_ORT_ACC) ? GOMP_MAP_ATTACH_DETACH
+                                            : GOMP_MAP_ALWAYS_POINTER;
+                     OMP_CLAUSE_SET_MAP_KIND (c2, k);
+                   }
                  else
                    OMP_CLAUSE_SET_MAP_KIND (c2,
                                             GOMP_MAP_FIRSTPRIVATE_REFERENCE);
@@ -7967,6 +8169,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)
@@ -8364,7 +8573,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:
@@ -8409,7 +8617,7 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
                TREE_OPERAND (cond, 1), iter);
       return true;
     }
-  if (!c_omp_check_loop_iv_exprs (locus, orig_declv,
+  if (!c_omp_check_loop_iv_exprs (locus, orig_declv, i,
                                  TREE_VEC_ELT (declv, i), NULL_TREE,
                                  cond, cp_walk_subtrees))
     return true;
@@ -8795,8 +9003,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
       tree orig_init;
       FOR_EACH_VEC_ELT (*orig_inits, i, orig_init)
        if (orig_init
-           && !c_omp_check_loop_iv_exprs (locus, orig_declv
-                                                 ? orig_declv : declv,
+           && !c_omp_check_loop_iv_exprs (locus,
+                                          orig_declv ? orig_declv : declv, i,
                                           TREE_VEC_ELT (declv, i), orig_init,
                                           NULL_TREE, cp_walk_subtrees))
          fail = true;
@@ -8890,35 +9098,11 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
          return NULL;
        }
 
-      if (!processing_template_decl)
-       {
-         init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
-         init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init,
-                                      tf_warning_or_error);
-       }
+      if (!processing_template_decl && TREE_CODE (init) != TREE_VEC)
+       init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init,
+                                    tf_warning_or_error);
       else
        init = build2 (MODIFY_EXPR, void_type_node, decl, init);
-      if (cond
-         && TREE_SIDE_EFFECTS (cond)
-         && COMPARISON_CLASS_P (cond)
-         && !processing_template_decl)
-       {
-         tree t = TREE_OPERAND (cond, 0);
-         if (TREE_SIDE_EFFECTS (t)
-             && t != decl
-             && (TREE_CODE (t) != NOP_EXPR
-                 || TREE_OPERAND (t, 0) != decl))
-           TREE_OPERAND (cond, 0)
-             = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
-
-         t = TREE_OPERAND (cond, 1);
-         if (TREE_SIDE_EFFECTS (t)
-             && t != decl
-             && (TREE_CODE (t) != NOP_EXPR
-                 || TREE_OPERAND (t, 0) != decl))
-           TREE_OPERAND (cond, 1)
-             = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
-       }
       if (decl == error_mark_node || init == error_mark_node)
        return NULL;
 
@@ -8947,9 +9131,45 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
 
   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
     {
-      decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i), 0);
+      init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i);
+      decl = TREE_OPERAND (init, 0);
+      cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), i);
       incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i);
 
+      if (!processing_template_decl)
+       {
+         if (TREE_CODE (TREE_OPERAND (init, 1)) == TREE_VEC)
+           {
+             tree t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 1);
+             TREE_VEC_ELT (TREE_OPERAND (init, 1), 1)
+               = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+             t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 2);
+             TREE_VEC_ELT (TREE_OPERAND (init, 1), 2)
+               = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+           }
+         else
+           {
+             tree t = TREE_OPERAND (init, 1);
+             TREE_OPERAND (init, 1)
+               = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+           }
+         if (TREE_CODE (TREE_OPERAND (cond, 1)) == TREE_VEC)
+           {
+             tree t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1);
+             TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1)
+               = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+             t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2);
+             TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2)
+               = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+           }
+         else
+           {
+             tree t = TREE_OPERAND (cond, 1);
+             TREE_OPERAND (cond, 1)
+               = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+           }
+       }
+
       if (TREE_CODE (incr) != MODIFY_EXPR)
        continue;
 
@@ -9259,7 +9479,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);
     }
 
@@ -9504,6 +9724,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);
@@ -9530,6 +9753,12 @@ 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 or a
+            requires-expression.  */
+         if (concept_check_p (orig_condition)
+             || TREE_CODE (orig_condition) == REQUIRES_EXPR)
+           diagnose_constraints (location, orig_condition, NULL_TREE);
        }
       else if (condition && condition != error_mark_node)
        {
@@ -9580,6 +9809,14 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
 
       return type;
     }
+  else if (processing_template_decl)
+    {
+      ++cp_unevaluated_operand;
+      expr = instantiate_non_dependent_expr_sfinae (expr, complain);
+      --cp_unevaluated_operand;
+      if (expr == error_mark_node)
+       return error_mark_node;
+    }
 
   /* The type denoted by decltype(e) is defined as follows:  */
 
@@ -10075,7 +10312,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
@@ -10086,8 +10322,8 @@ static tree
 capture_decltype (tree decl)
 {
   tree lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl));
-  tree cap = lookup_name_real (DECL_NAME (decl), /*type*/0, /*nonclass*/1,
-                              /*block_p=*/true, /*ns*/0, LOOKUP_HIDDEN);
+  tree cap = lookup_name_real (DECL_NAME (decl), LOOK_where::BLOCK,
+                              LOOK_want::NORMAL | LOOK_want::HIDDEN_LAMBDA);
   tree type;
 
   if (cap && is_capture_proxy (cap))
@@ -10132,7 +10368,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 "
@@ -10141,7 +10377,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);
@@ -10230,7 +10466,8 @@ 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_input_loc (arg), arg,
+    ret = c_build_vec_convert (cp_expr_loc_or_input_loc (arg),
+                              decay_conversion (arg, complain),
                               loc, type, (complain & tf_error) != 0);
 
   if (!processing_template_decl)