class.c (fixup_type_variants): Do not copy TYPE_METHODS
[gcc.git] / gcc / cp / class.c
index edb87fe2e0a46df0f9f8100023251cb2287ac492..41607055493bc74fb08dbbb12d9cbe64d54595ab 100644 (file)
@@ -447,10 +447,20 @@ build_base_path (enum tree_code code,
          v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
        }
       else
-       v_offset = build_vfield_ref (cp_build_indirect_ref (expr, RO_NULL,
-                                                            complain),
-                                    TREE_TYPE (TREE_TYPE (expr)));
-      
+       {
+         tree t = expr;
+         if ((flag_sanitize & SANITIZE_VPTR) && fixed_type_p == 0)
+           {
+             t = cp_ubsan_maybe_instrument_cast_to_vbase (input_location,
+                                                          probe, expr);
+             if (t == NULL_TREE)
+               t = expr;
+           }
+         v_offset = build_vfield_ref (cp_build_indirect_ref (t, RO_NULL,
+                                                             complain),
+         TREE_TYPE (TREE_TYPE (expr)));
+       }
+
       if (v_offset == error_mark_node)
        return error_mark_node;
 
@@ -1372,44 +1382,53 @@ struct abi_tag_data
    a tag NAMESPACE_DECL) or a STRING_CST (a tag attribute).  */
 
 static void
-check_tag (tree tag, tree *tp, abi_tag_data *p)
+check_tag (tree tag, tree id, tree *tp, abi_tag_data *p)
 {
-  tree id;
-
-  if (TREE_CODE (tag) == STRING_CST)
-    id = get_identifier (TREE_STRING_POINTER (tag));
-  else
-    {
-      id = tag;
-      tag = NULL_TREE;
-    }
-
   if (!IDENTIFIER_MARKED (id))
     {
-      if (!tag)
-       tag = build_string (IDENTIFIER_LENGTH (id) + 1,
-                           IDENTIFIER_POINTER (id));
       if (p->tags != error_mark_node)
        {
-         /* We're collecting tags from template arguments.  */
+         /* We're collecting tags from template arguments or from
+            the type of a variable or function return type.  */
          p->tags = tree_cons (NULL_TREE, tag, p->tags);
-         ABI_TAG_IMPLICIT (p->tags) = true;
 
          /* Don't inherit this tag multiple times.  */
          IDENTIFIER_MARKED (id) = true;
+
+         if (TYPE_P (p->t))
+           {
+             /* Tags inherited from type template arguments are only used
+                to avoid warnings.  */
+             ABI_TAG_IMPLICIT (p->tags) = true;
+             return;
+           }
+         /* For functions and variables we want to warn, too.  */
        }
 
       /* Otherwise we're diagnosing missing tags.  */
+      if (TREE_CODE (p->t) == FUNCTION_DECL)
+       {
+         if (warning (OPT_Wabi_tag, "%qD inherits the %E ABI tag "
+                      "that %qT (used in its return type) has",
+                      p->t, tag, *tp))
+           inform (location_of (*tp), "%qT declared here", *tp);
+       }
+      else if (TREE_CODE (p->t) == VAR_DECL)
+       {
+         if (warning (OPT_Wabi_tag, "%qD inherits the %E ABI tag "
+                      "that %qT (used in its type) has", p->t, tag, *tp))
+           inform (location_of (*tp), "%qT declared here", *tp);
+       }
       else if (TYPE_P (p->subob))
        {
-         if (warning (OPT_Wabi_tag, "%qT does not have the %E abi tag "
+         if (warning (OPT_Wabi_tag, "%qT does not have the %E ABI tag "
                       "that base %qT has", p->t, tag, p->subob))
            inform (location_of (p->subob), "%qT declared here",
                    p->subob);
        }
       else
        {
-         if (warning (OPT_Wabi_tag, "%qT does not have the %E abi tag "
+         if (warning (OPT_Wabi_tag, "%qT does not have the %E ABI tag "
                       "that %qT (used in the type of %qD) has",
                       p->t, tag, *tp, p->subob))
            {
@@ -1421,8 +1440,53 @@ check_tag (tree tag, tree *tp, abi_tag_data *p)
     }
 }
 
+/* Find all the ABI tags in the attribute list ATTR and either call
+   check_tag (if TP is non-null) or set IDENTIFIER_MARKED to val.  */
+
+static void
+mark_or_check_attr_tags (tree attr, tree *tp, abi_tag_data *p, bool val)
+{
+  if (!attr)
+    return;
+  for (; (attr = lookup_attribute ("abi_tag", attr));
+       attr = TREE_CHAIN (attr))
+    for (tree list = TREE_VALUE (attr); list;
+        list = TREE_CHAIN (list))
+      {
+       tree tag = TREE_VALUE (list);
+       tree id = get_identifier (TREE_STRING_POINTER (tag));
+       if (tp)
+         check_tag (tag, id, tp, p);
+       else
+         IDENTIFIER_MARKED (id) = val;
+      }
+}
+
+/* Find all the ABI tags on T and its enclosing scopes and either call
+   check_tag (if TP is non-null) or set IDENTIFIER_MARKED to val.  */
+
+static void
+mark_or_check_tags (tree t, tree *tp, abi_tag_data *p, bool val)
+{
+  while (t != global_namespace)
+    {
+      tree attr;
+      if (TYPE_P (t))
+       {
+         attr = TYPE_ATTRIBUTES (t);
+         t = CP_TYPE_CONTEXT (t);
+       }
+      else
+       {
+         attr = DECL_ATTRIBUTES (t);
+         t = CP_DECL_CONTEXT (t);
+       }
+      mark_or_check_attr_tags (attr, tp, p, val);
+    }
+}
+
 /* walk_tree callback for check_abi_tags: if the type at *TP involves any
-   types with abi tags, add the corresponding identifiers to the VEC in
+   types with ABI tags, add the corresponding identifiers to the VEC in
    *DATA and set IDENTIFIER_MARKED.  */
 
 static tree
@@ -1437,63 +1501,112 @@ find_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
 
   abi_tag_data *p = static_cast<struct abi_tag_data*>(data);
 
-  for (tree ns = decl_namespace_context (*tp);
-       ns != global_namespace;
-       ns = CP_DECL_CONTEXT (ns))
-    if (NAMESPACE_ABI_TAG (ns))
-      check_tag (DECL_NAME (ns), tp, p);
+  mark_or_check_tags (*tp, tp, p, false);
 
-  if (tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (*tp)))
-    {
-      for (tree list = TREE_VALUE (attributes); list;
-          list = TREE_CHAIN (list))
-       {
-         tree tag = TREE_VALUE (list);
-         check_tag (tag, tp, p);
-       }
-    }
   return NULL_TREE;
 }
 
-/* Set IDENTIFIER_MARKED on all the ABI tags on T and its (transitively
-   complete) template arguments.  */
+/* walk_tree callback for mark_abi_tags: if *TP is a class, set
+   IDENTIFIER_MARKED on its ABI tags.  */
 
-static void
-mark_type_abi_tags (tree t, bool val)
+static tree
+mark_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
 {
-  for (tree ns = decl_namespace_context (t);
-       ns != global_namespace;
-       ns = CP_DECL_CONTEXT (ns))
-    if (NAMESPACE_ABI_TAG (ns))
-      IDENTIFIER_MARKED (DECL_NAME (ns)) = val;
+  if (!OVERLOAD_TYPE_P (*tp))
+    return NULL_TREE;
+
+  /* walk_tree shouldn't be walking into any subtrees of a RECORD_TYPE
+     anyway, but let's make sure of it.  */
+  *walk_subtrees = false;
+
+  bool *valp = static_cast<bool*>(data);
+
+  mark_or_check_tags (*tp, NULL, NULL, *valp);
+
+  return NULL_TREE;
+}
 
-  tree attributes = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
-  if (attributes)
+/* Set IDENTIFIER_MARKED on all the ABI tags on T and its enclosing
+   scopes.  */
+
+static void
+mark_abi_tags (tree t, bool val)
+{
+  mark_or_check_tags (t, NULL, NULL, val);
+  if (DECL_P (t))
     {
-      for (tree list = TREE_VALUE (attributes); list;
-          list = TREE_CHAIN (list))
+      if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t)
+         && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))
        {
-         tree tag = TREE_VALUE (list);
-         tree id = get_identifier (TREE_STRING_POINTER (tag));
-         IDENTIFIER_MARKED (id) = val;
+         /* Template arguments are part of the signature.  */
+         tree level = INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (t));
+         for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
+           {
+             tree arg = TREE_VEC_ELT (level, j);
+             cp_walk_tree_without_duplicates (&arg, mark_abi_tags_r, &val);
+           }
        }
+      if (TREE_CODE (t) == FUNCTION_DECL)
+       /* A function's parameter types are part of the signature, so
+          we don't need to inherit any tags that are also in them.  */
+       for (tree arg = FUNCTION_FIRST_USER_PARMTYPE (t); arg;
+            arg = TREE_CHAIN (arg))
+         cp_walk_tree_without_duplicates (&TREE_VALUE (arg),
+                                          mark_abi_tags_r, &val);
     }
 }
 
-/* Check that class T has all the abi tags that subobject SUBOB has, or
-   warn if not.  */
+/* Check that T has all the ABI tags that subobject SUBOB has, or
+   warn if not.  If T is a (variable or function) declaration, also
+   add any missing tags.  */
 
 static void
 check_abi_tags (tree t, tree subob)
 {
-  mark_type_abi_tags (t, true);
+  bool inherit = DECL_P (t);
+
+  if (!inherit && !warn_abi_tag)
+    return;
+
+  tree decl = TYPE_P (t) ? TYPE_NAME (t) : t;
+  if (!TREE_PUBLIC (decl))
+    /* No need to worry about things local to this TU.  */
+    return;
+
+  mark_abi_tags (t, true);
 
   tree subtype = TYPE_P (subob) ? subob : TREE_TYPE (subob);
   struct abi_tag_data data = { t, subob, error_mark_node };
+  if (inherit)
+    data.tags = NULL_TREE;
 
   cp_walk_tree_without_duplicates (&subtype, find_abi_tags_r, &data);
 
-  mark_type_abi_tags (t, false);
+  if (inherit && data.tags)
+    {
+      tree attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t));
+      if (attr)
+       TREE_VALUE (attr) = chainon (data.tags, TREE_VALUE (attr));
+      else
+       DECL_ATTRIBUTES (t)
+         = tree_cons (get_identifier ("abi_tag"), data.tags,
+                      DECL_ATTRIBUTES (t));
+    }
+
+  mark_abi_tags (t, false);
+}
+
+/* Check that DECL has all the ABI tags that are used in parts of its type
+   that are not reflected in its mangled name.  */
+
+void
+check_abi_tags (tree decl)
+{
+  if (TREE_CODE (decl) == VAR_DECL)
+    check_abi_tags (decl, TREE_TYPE (decl));
+  else if (TREE_CODE (decl) == FUNCTION_DECL
+          && !mangle_return_type_p (decl))
+    check_abi_tags (decl, TREE_TYPE (TREE_TYPE (decl)));
 }
 
 void
@@ -1503,7 +1616,7 @@ inherit_targ_abi_tags (tree t)
       || CLASSTYPE_TEMPLATE_INFO (t) == NULL_TREE)
     return;
 
-  mark_type_abi_tags (t, true);
+  mark_abi_tags (t, true);
 
   tree args = CLASSTYPE_TI_ARGS (t);
   struct abi_tag_data data = { t, NULL_TREE, NULL_TREE };
@@ -1531,7 +1644,7 @@ inherit_targ_abi_tags (tree t)
                       TYPE_ATTRIBUTES (t));
     }
 
-  mark_type_abi_tags (t, false);
+  mark_abi_tags (t, false);
 }
 
 /* Return true, iff class T has a non-virtual destructor that is
@@ -1859,7 +1972,6 @@ fixup_type_variants (tree t)
 
       /* Copy whatever these are holding today.  */
       TYPE_VFIELD (variants) = TYPE_VFIELD (t);
-      TYPE_METHODS (variants) = TYPE_METHODS (t);
       TYPE_FIELDS (variants) = TYPE_FIELDS (t);
     }
 }
@@ -1876,14 +1988,23 @@ fixup_attribute_variants (tree t)
   if (!t)
     return;
 
+  tree attrs = TYPE_ATTRIBUTES (t);
+  unsigned align = TYPE_ALIGN (t);
+  bool user_align = TYPE_USER_ALIGN (t);
+
   for (variants = TYPE_NEXT_VARIANT (t);
        variants;
        variants = TYPE_NEXT_VARIANT (variants))
     {
       /* These are the two fields that check_qualified_type looks at and
         are affected by attributes.  */
-      TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t);
-      TYPE_ALIGN (variants) = TYPE_ALIGN (t);
+      TYPE_ATTRIBUTES (variants) = attrs;
+      unsigned valign = align;
+      if (TYPE_USER_ALIGN (variants))
+       valign = MAX (valign, TYPE_ALIGN (variants));
+      else
+       TYPE_USER_ALIGN (variants) = user_align;
+      TYPE_ALIGN (variants) = valign;
     }
 }
 \f
@@ -3116,6 +3237,7 @@ one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
     parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
   tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
                                   t, false, ctor, parmlist);
+  gcc_assert (TYPE_MAIN_VARIANT (t) == t);
   if (add_method (t, fn, NULL_TREE))
     {
       DECL_CHAIN (fn) = TYPE_METHODS (t);
@@ -5321,7 +5443,8 @@ remove_zero_width_bit_fields (tree t)
             DECL_INITIAL (*fieldsp).
             check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
             to that width.  */
-         && integer_zerop (DECL_SIZE (*fieldsp)))
+         && (DECL_SIZE (*fieldsp) == NULL_TREE
+             || integer_zerop (DECL_SIZE (*fieldsp))))
        *fieldsp = DECL_CHAIN (*fieldsp);
       else
        fieldsp = &DECL_CHAIN (*fieldsp);
@@ -6144,7 +6267,7 @@ layout_class_type (tree t, tree *virtuals_p)
                padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
                                      TYPE_SIZE (integer_type));
            }
-#ifdef PCC_BITFIELD_TYPE_MATTERS
+
          /* An unnamed bitfield does not normally affect the
             alignment of the containing class on a target where
             PCC_BITFIELD_TYPE_MATTERS.  But, the C++ ABI does not
@@ -6156,7 +6279,7 @@ layout_class_type (tree t, tree *virtuals_p)
              was_unnamed_p = true;
              DECL_NAME (field) = make_anon_name ();
            }
-#endif
+
          DECL_SIZE (field) = TYPE_SIZE (integer_type);
          DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
          DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
@@ -6777,12 +6900,13 @@ finish_struct (tree t, tree attributes)
          if (f && TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE)
            {
              f = next_initializable_field (DECL_CHAIN (f));
-             if (f && TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE)
+             if (f && same_type_p (TREE_TYPE (f), size_type_node))
                ok = true;
            }
        }
       if (!ok)
-       fatal_error ("definition of std::initializer_list does not match "
+       fatal_error (input_location,
+                    "definition of std::initializer_list does not match "
                     "#include <initializer_list>");
     }
 
@@ -7356,7 +7480,7 @@ pop_lang_context (void)
 static tree
 resolve_address_of_overloaded_function (tree target_type,
                                        tree overload,
-                                       tsubst_flags_t flags,
+                                       tsubst_flags_t complain,
                                        bool template_only,
                                        tree explicit_targs,
                                        tree access_path)
@@ -7416,7 +7540,7 @@ resolve_address_of_overloaded_function (tree target_type,
     target_type = build_reference_type (target_type);
   else
     {
-      if (flags & tf_error)
+      if (complain & tf_error)
        error ("cannot resolve overloaded function %qD based on"
               " conversion to type %qT",
               DECL_NAME (OVL_FUNCTION (overload)), target_type);
@@ -7552,7 +7676,7 @@ resolve_address_of_overloaded_function (tree target_type,
   if (matches == NULL_TREE)
     {
       /* There were *no* matches.  */
-      if (flags & tf_error)
+      if (complain & tf_error)
        {
          error ("no matches converting function %qD to type %q#T",
                 DECL_NAME (OVL_CURRENT (overload)),
@@ -7580,7 +7704,7 @@ resolve_address_of_overloaded_function (tree target_type,
 
       if (match)
        {
-         if (flags & tf_error)
+         if (complain & tf_error)
            {
              error ("converting overloaded function %qD to type %q#T is ambiguous",
                     DECL_NAME (OVL_FUNCTION (overload)),
@@ -7602,11 +7726,11 @@ resolve_address_of_overloaded_function (tree target_type,
   fn = TREE_PURPOSE (matches);
 
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
-      && !(flags & tf_ptrmem_ok) && !flag_ms_extensions)
+      && !(complain & tf_ptrmem_ok) && !flag_ms_extensions)
     {
       static int explained;
 
-      if (!(flags & tf_error))
+      if (!(complain & tf_error))
        return error_mark_node;
 
       permerror (input_location, "assuming pointer to member %qD", fn);
@@ -7627,7 +7751,7 @@ resolve_address_of_overloaded_function (tree target_type,
       if (fn == NULL)
        return error_mark_node;
       /* Mark all the versions corresponding to the dispatcher as used.  */
-      if (!(flags & tf_conv))
+      if (!(complain & tf_conv))
        mark_versions_used (fn);
     }
 
@@ -7635,13 +7759,13 @@ resolve_address_of_overloaded_function (tree target_type,
      determining conversion sequences, we should not consider the
      function used.  If this conversion sequence is selected, the
      function will be marked as used at this point.  */
-  if (!(flags & tf_conv))
+  if (!(complain & tf_conv))
     {
       /* Make =delete work with SFINAE.  */
-      if (DECL_DELETED_FN (fn) && !(flags & tf_error))
+      if (DECL_DELETED_FN (fn) && !(complain & tf_error))
+       return error_mark_node;
+      if (!mark_used (fn, complain) && !(complain & tf_error))
        return error_mark_node;
-      
-      mark_used (fn);
     }
 
   /* We could not check access to member functions when this
@@ -7650,11 +7774,11 @@ resolve_address_of_overloaded_function (tree target_type,
   if (DECL_FUNCTION_MEMBER_P (fn))
     {
       gcc_assert (access_path);
-      perform_or_defer_access_check (access_path, fn, fn, flags);
+      perform_or_defer_access_check (access_path, fn, fn, complain);
     }
 
   if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
-    return cp_build_addr_expr (fn, flags);
+    return cp_build_addr_expr (fn, complain);
   else
     {
       /* The target must be a REFERENCE_TYPE.  Above, cp_build_unary_op
@@ -7668,7 +7792,7 @@ resolve_address_of_overloaded_function (tree target_type,
 
 /* This function will instantiate the type of the expression given in
    RHS to match the type of LHSTYPE.  If errors exist, then return
-   error_mark_node. FLAGS is a bit mask.  If TF_ERROR is set, then
+   error_mark_node. COMPLAIN is a bit mask.  If TF_ERROR is set, then
    we complain on errors.  If we are not complaining, never modify rhs,
    as overload resolution wants to try many possible instantiations, in
    the hope that at least one will work.
@@ -7677,16 +7801,16 @@ resolve_address_of_overloaded_function (tree target_type,
    function, or a pointer to member function.  */
 
 tree
-instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
+instantiate_type (tree lhstype, tree rhs, tsubst_flags_t complain)
 {
-  tsubst_flags_t flags_in = flags;
+  tsubst_flags_t complain_in = complain;
   tree access_path = NULL_TREE;
 
-  flags &= ~tf_ptrmem_ok;
+  complain &= ~tf_ptrmem_ok;
 
   if (lhstype == unknown_type_node)
     {
-      if (flags & tf_error)
+      if (complain & tf_error)
        error ("not enough type information");
       return error_mark_node;
     }
@@ -7704,7 +7828,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
        ;
       else
        {
-         if (flags & tf_error)
+         if (complain & tf_error)
            error ("cannot convert %qE from type %qT to type %qT",
                   rhs, TREE_TYPE (rhs), fntype);
          return error_mark_node;
@@ -7721,7 +7845,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
      deduce any type information.  */
   if (TREE_CODE (rhs) == NON_DEPENDENT_EXPR)
     {
-      if (flags & tf_error)
+      if (complain & tf_error)
        error ("not enough type information");
       return error_mark_node;
     }
@@ -7744,7 +7868,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
       {
        tree member = TREE_OPERAND (rhs, 1);
 
-       member = instantiate_type (lhstype, member, flags);
+       member = instantiate_type (lhstype, member, complain);
        if (member != error_mark_node
            && TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))
          /* Do not lose object's side effects.  */
@@ -7756,7 +7880,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     case OFFSET_REF:
       rhs = TREE_OPERAND (rhs, 1);
       if (BASELINK_P (rhs))
-       return instantiate_type (lhstype, rhs, flags_in);
+       return instantiate_type (lhstype, rhs, complain_in);
 
       /* This can happen if we are forming a pointer-to-member for a
         member template.  */
@@ -7770,7 +7894,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
        tree args = TREE_OPERAND (rhs, 1);
 
        return
-         resolve_address_of_overloaded_function (lhstype, fns, flags_in,
+         resolve_address_of_overloaded_function (lhstype, fns, complain_in,
                                                  /*template_only=*/true,
                                                  args, access_path);
       }
@@ -7778,7 +7902,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     case OVERLOAD:
     case FUNCTION_DECL:
       return
-       resolve_address_of_overloaded_function (lhstype, rhs, flags_in,
+       resolve_address_of_overloaded_function (lhstype, rhs, complain_in,
                                                /*template_only=*/false,
                                                /*explicit_targs=*/NULL_TREE,
                                                access_path);
@@ -7786,9 +7910,9 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
     case ADDR_EXPR:
     {
       if (PTRMEM_OK_P (rhs))
-       flags |= tf_ptrmem_ok;
+       complain |= tf_ptrmem_ok;
 
-      return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
+      return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
     }
 
     case ERROR_MARK: