Author: pfg
Date: Sun Jan  5 20:33:44 2014
New Revision: 260332
URL: http://svnweb.freebsd.org/changeset/base/260332

Log:
  gcc: backport some fixes from llvm-gcc
  
  llvm-gcc backported some patches from gcc trunk:
  
  http://gcc.gnu.org/ml/gcc-cvs/2007-05/msg00662.html
  http://gcc.gnu.org/ml/gcc-cvs/2007-07/msg00019.html
  http://gcc.gnu.org/ml/gcc-cvs/2007-08/msg00240.html
  http://gcc.gnu.org/ml/gcc-cvs/2007-08/msg00493.html
  
  The first two were always GPL2. The last two were
  added after the GPL3 transition, but were written
  by a...@google.com and Rafael EspĂ­ndola got permission
  to relicense them under the GPL2 for inclusion in
  llvm-gcc.
  
  This fixes GCC-PR c++/31749
  
  Obtained from:        llvm-gcc (rev. 75463; GPLv2)
  MFC after:    2 weeks

Modified:
  head/contrib/gcc/cp/ChangeLog.gcc43
  head/contrib/gcc/cp/decl.c
  head/contrib/gcc/cp/name-lookup.c
  head/contrib/gcc/cp/parser.c

Modified: head/contrib/gcc/cp/ChangeLog.gcc43
==============================================================================
--- head/contrib/gcc/cp/ChangeLog.gcc43 Sun Jan  5 20:09:51 2014        
(r260331)
+++ head/contrib/gcc/cp/ChangeLog.gcc43 Sun Jan  5 20:33:44 2014        
(r260332)
@@ -7,6 +7,17 @@
        * typeck.c (cxx_alignof_expr): When alignof is used on a plain
        FUNCTION_DECL, return its alignment.
 
+2007-07-01  Ollie Wild  <a...@google.com> (r126177)
+
+       * name-lookup.c (ambiguous_decl): Fix case when new->value is hidden.
+       (select_decl): Remove function.
+       (unqualified_namespace_lookup): Populate binding by calling
+       ambiguous_decl.  Remove select_decl call.
+       (lookup_qualified_name): Remove select_decl call.
+       * decl.c (lookup_and_check_tag): Check for ambiguous references.
+       * parser.c (cp_parser_elaborated_type_specifier): Skip redundant error
+       generation when name lookup is ambiguous.
+
 2007-06-28  Geoffrey Keating  <geo...@apple.com> (r126088)
 
        * decl2.c (determine_visibility): Implement
@@ -29,6 +40,11 @@
 
        * typeck.c (build_binary_op): Include types in error.
 
+2007-05-22  Ollie Wild  <a...@google.com> (r124963)
+ 
+       * name-lookup.c (ambiguous_decl): Adds check for hidden types.
+       (unqualified_namespace_lookup): Adds check for hidden types.
+
 2007-05-18  Geoffrey Keating  <geo...@apple.com> (r124839)
 
        * mangle.c (write_real_cst): Use 'unsigned long' for %lx.

Modified: head/contrib/gcc/cp/decl.c
==============================================================================
--- head/contrib/gcc/cp/decl.c  Sun Jan  5 20:09:51 2014        (r260331)
+++ head/contrib/gcc/cp/decl.c  Sun Jan  5 20:33:44 2014        (r260332)
@@ -10253,6 +10253,12 @@ lookup_and_check_tag (enum tag_types tag
                                           | DECL_SELF_REFERENCE_P (decl));
       return t;
     }
+  else if (decl && TREE_CODE (decl) == TREE_LIST)
+    {
+      error ("reference to %qD is ambiguous", name);
+      print_candidates (decl);
+      return error_mark_node;
+    }
   else
     return NULL_TREE;
 }

Modified: head/contrib/gcc/cp/name-lookup.c
==============================================================================
--- head/contrib/gcc/cp/name-lookup.c   Sun Jan  5 20:09:51 2014        
(r260331)
+++ head/contrib/gcc/cp/name-lookup.c   Sun Jan  5 20:33:44 2014        
(r260332)
@@ -42,7 +42,6 @@ struct scope_binding {
 #define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
 
 static cxx_scope *innermost_nonclass_level (void);
-static tree select_decl (const struct scope_binding *, int);
 static cxx_binding *binding_for_name (cxx_scope *, tree);
 static tree lookup_name_innermost_nonclass_level (tree);
 static tree push_overloaded_decl (tree, int, bool);
@@ -2104,6 +2103,22 @@ do_nonmember_using_decl (tree scope, tre
       return;
     }
 
+  /* LLVM LOCAL begin mainline */
+  /* Shift the old and new bindings around so we're comparing class and
+     enumeration names to each other.  */
+  if (oldval && DECL_IMPLICIT_TYPEDEF_P (oldval))
+    {
+      oldtype = oldval;
+      oldval = NULL_TREE;
+    }
+
+  if (decls.value && DECL_IMPLICIT_TYPEDEF_P (decls.value))
+    {
+      decls.type = decls.value;
+      decls.value = NULL_TREE;
+    }
+  /* LLVM LOCAL end mainline */
+
   /* It is impossible to overload a built-in function; any explicit
      declaration eliminates the built-in declaration.  So, if OLDVAL
      is a built-in, then we can just pretend it isn't there.  */
@@ -2113,95 +2128,112 @@ do_nonmember_using_decl (tree scope, tre
       && !DECL_HIDDEN_FRIEND_P (oldval))
     oldval = NULL_TREE;
 
-  /* Check for using functions.  */
-  if (decls.value && is_overloaded_fn (decls.value))
+  /* LLVM LOCAL begin mainline */
+  if (decls.value)
     {
-      tree tmp, tmp1;
-
-      if (oldval && !is_overloaded_fn (oldval))
-       {
-         if (!DECL_IMPLICIT_TYPEDEF_P (oldval))
-           error ("%qD is already declared in this scope", name);
-         oldval = NULL_TREE;
-       }
-
-      *newval = oldval;
-      for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
+      /* Check for using functions.  */
+      if (is_overloaded_fn (decls.value))
        {
-         tree new_fn = OVL_CURRENT (tmp);
+         tree tmp, tmp1;
 
-         /* [namespace.udecl]
+         if (oldval && !is_overloaded_fn (oldval))
+           {
+             error ("%qD is already declared in this scope", name);
+             oldval = NULL_TREE;
+           }
 
-            If a function declaration in namespace scope or block
-            scope has the same name and the same parameter types as a
-            function introduced by a using declaration the program is
-            ill-formed.  */
-         for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
+         *newval = oldval;
+         for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
            {
-             tree old_fn = OVL_CURRENT (tmp1);
+             tree new_fn = OVL_CURRENT (tmp);
 
-             if (new_fn == old_fn)
-               /* The function already exists in the current namespace.  */
-               break;
-             else if (OVL_USED (tmp1))
-               continue; /* this is a using decl */
-             else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
-                                 TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+             /* [namespace.udecl]
+
+                If a function declaration in namespace scope or block
+                scope has the same name and the same parameter types as a
+                function introduced by a using declaration the program is
+                ill-formed.  */
+             for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
                {
-                 gcc_assert (!DECL_ANTICIPATED (old_fn)
-                             || DECL_HIDDEN_FRIEND_P (old_fn));
+                 tree old_fn = OVL_CURRENT (tmp1);
 
-                 /* There was already a non-using declaration in
-                    this scope with the same parameter types. If both
-                    are the same extern "C" functions, that's ok.  */
-                 if (decls_match (new_fn, old_fn))
+                 if (new_fn == old_fn)
+                   /* The function already exists in the current namespace.  */
                    break;
-                 else
+                 else if (OVL_USED (tmp1))
+                   continue; /* this is a using decl */
+                 else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+                                     TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
                    {
-                     error ("%qD is already declared in this scope", name);
-                     break;
+                     gcc_assert (!DECL_ANTICIPATED (old_fn)
+                                 || DECL_HIDDEN_FRIEND_P (old_fn));
+
+                     /* There was already a non-using declaration in
+                        this scope with the same parameter types. If both
+                        are the same extern "C" functions, that's ok.  */
+                     if (decls_match (new_fn, old_fn))
+                       break;
+                     else
+                       {
+                         error ("%qD is already declared in this scope", name);
+                         break;
+                       }
                    }
                }
-           }
 
-         /* If we broke out of the loop, there's no reason to add
-            this function to the using declarations for this
-            scope.  */
-         if (tmp1)
-           continue;
-
-         /* If we are adding to an existing OVERLOAD, then we no
-            longer know the type of the set of functions.  */
-         if (*newval && TREE_CODE (*newval) == OVERLOAD)
-           TREE_TYPE (*newval) = unknown_type_node;
-         /* Add this new function to the set.  */
-         *newval = build_overload (OVL_CURRENT (tmp), *newval);
-         /* If there is only one function, then we use its type.  (A
-            using-declaration naming a single function can be used in
-            contexts where overload resolution cannot be
-            performed.)  */
-         if (TREE_CODE (*newval) != OVERLOAD)
-           {
-             *newval = ovl_cons (*newval, NULL_TREE);
-             TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+             /* If we broke out of the loop, there's no reason to add
+                this function to the using declarations for this
+                scope.  */
+             if (tmp1)
+               continue;
+
+             /* If we are adding to an existing OVERLOAD, then we no
+                longer know the type of the set of functions.  */
+             if (*newval && TREE_CODE (*newval) == OVERLOAD)
+               TREE_TYPE (*newval) = unknown_type_node;
+             /* Add this new function to the set.  */
+             *newval = build_overload (OVL_CURRENT (tmp), *newval);
+             /* If there is only one function, then we use its type.  (A
+                using-declaration naming a single function can be used in
+                contexts where overload resolution cannot be
+                performed.)  */
+             if (TREE_CODE (*newval) != OVERLOAD)
+               {
+                 *newval = ovl_cons (*newval, NULL_TREE);
+                 TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+               }
+             OVL_USED (*newval) = 1;
            }
-         OVL_USED (*newval) = 1;
+       }
+      else
+       {
+         *newval = decls.value;
+         if (oldval && !decls_match (*newval, oldval))
+           error ("%qD is already declared in this scope", name);
        }
     }
   else
+    *newval = oldval;
+
+  if (decls.type && TREE_CODE (decls.type) == TREE_LIST)
     {
-      *newval = decls.value;
-      if (oldval && !decls_match (*newval, oldval))
-       error ("%qD is already declared in this scope", name);
+      error ("reference to %qD is ambiguous", name);
+      print_candidates (decls.type);
     }
-
-  *newtype = decls.type;
-  if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
+  else
     {
-      error ("using declaration %qD introduced ambiguous type %qT",
-            name, oldtype);
-      return;
+      *newtype = decls.type;
+      if (oldtype && *newtype && !decls_match (oldtype, *newtype))
+       error ("%qD is already declared in this scope", name);
     }
+
+    /* If *newval is empty, shift any class or enumeration name down.  */
+    if (!*newval)
+      {
+       *newval = *newtype;
+       *newtype = NULL_TREE;
+      }
+  /* LLVM LOCAL end mainline */
 }
 
 /* Process a using-declaration at function scope.  */
@@ -3495,43 +3527,63 @@ merge_functions (tree s1, tree s2)
    XXX In what way should I treat extern declarations?
    XXX I don't want to repeat the entire duplicate_decls here */
 
+/* LLVM LOCAL begin mainline */
 static void
-ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
-               int flags)
+ambiguous_decl (struct scope_binding *old, cxx_binding *new, int flags)
 {
   tree val, type;
   gcc_assert (old != NULL);
+
+  /* Copy the type.  */
+  type = new->type;
+  if (LOOKUP_NAMESPACES_ONLY (flags)
+      || (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN)))
+    type = NULL_TREE;
+
   /* Copy the value.  */
   val = new->value;
   if (val)
-    switch (TREE_CODE (val))
-      {
-      case TEMPLATE_DECL:
-       /* If we expect types or namespaces, and not templates,
-          or this is not a template class.  */
-       if ((LOOKUP_QUALIFIERS_ONLY (flags)
-            && !DECL_CLASS_TEMPLATE_P (val))
-           || hidden_name_p (val))
-         val = NULL_TREE;
-       break;
-      case TYPE_DECL:
-       if (LOOKUP_NAMESPACES_ONLY (flags) || hidden_name_p (val))
-         val = NULL_TREE;
-       break;
-      case NAMESPACE_DECL:
-       if (LOOKUP_TYPES_ONLY (flags))
-         val = NULL_TREE;
-       break;
-      case FUNCTION_DECL:
-       /* Ignore built-in functions that are still anticipated.  */
-       if (LOOKUP_QUALIFIERS_ONLY (flags) || hidden_name_p (val))
-         val = NULL_TREE;
-       break;
-      default:
-       if (LOOKUP_QUALIFIERS_ONLY (flags))
-         val = NULL_TREE;
-      }
+    {
+      if (hidden_name_p (val) && !(flags & LOOKUP_HIDDEN))
+       val = NULL_TREE;
+      else
+       switch (TREE_CODE (val))
+         {
+         case TEMPLATE_DECL:
+           /* If we expect types or namespaces, and not templates,
+              or this is not a template class.  */
+           if ((LOOKUP_QUALIFIERS_ONLY (flags)
+                && !DECL_CLASS_TEMPLATE_P (val)))
+             val = NULL_TREE;
+           break;
+         case TYPE_DECL:
+           if (LOOKUP_NAMESPACES_ONLY (flags)
+               || (type && (flags & LOOKUP_PREFER_TYPES)))
+             val = NULL_TREE;
+           break;
+         case NAMESPACE_DECL:
+           if (LOOKUP_TYPES_ONLY (flags))
+             val = NULL_TREE;
+           break;
+         case FUNCTION_DECL:
+           /* Ignore built-in functions that are still anticipated.  */
+           if (LOOKUP_QUALIFIERS_ONLY (flags))
+             val = NULL_TREE;
+           break;
+         default:
+           if (LOOKUP_QUALIFIERS_ONLY (flags))
+             val = NULL_TREE;
+         }
+    }
+
+  /* If val is hidden, shift down any class or enumeration name.  */
+  if (!val)
+    {
+      val = type;
+      type = NULL_TREE;
+    }
 
+/* LLVM LOCAL end mainline */
   if (!old->value)
     old->value = val;
   else if (val && val != old->value)
@@ -3541,25 +3593,21 @@ ambiguous_decl (tree name, struct scope_
       else
        {
          old->value = tree_cons (NULL_TREE, old->value,
-                                 build_tree_list (NULL_TREE, new->value));
+                                 build_tree_list (NULL_TREE, val));
          TREE_TYPE (old->value) = error_mark_node;
        }
     }
-  /* ... and copy the type.  */
-  type = new->type;
-  if (LOOKUP_NAMESPACES_ONLY (flags))
-    type = NULL_TREE;
+
+  /* LLVM LOCAL begin mainline */
   if (!old->type)
     old->type = type;
   else if (type && old->type != type)
     {
-      if (flags & LOOKUP_COMPLAIN)
-       {
-         error ("%qD denotes an ambiguous type",name);
-         error ("%J  first type here", TYPE_MAIN_DECL (old->type));
-         error ("%J  other type here", TYPE_MAIN_DECL (type));
-       }
+      old->type = tree_cons (NULL_TREE, old->type,
+                            build_tree_list (NULL_TREE, type));
+      TREE_TYPE (old->type) = error_mark_node;
     }
+  /* LLVM LOCAL end mainline */
 }
 
 /* Return the declarations that are members of the namespace NS.  */
@@ -3648,36 +3696,6 @@ remove_hidden_names (tree fns)
   return fns;
 }
 
-/* Select the right _DECL from multiple choices.  */
-
-static tree
-select_decl (const struct scope_binding *binding, int flags)
-{
-  tree val;
-  val = binding->value;
-
-  timevar_push (TV_NAME_LOOKUP);
-  if (LOOKUP_NAMESPACES_ONLY (flags))
-    {
-      /* We are not interested in types.  */
-      if (val && (TREE_CODE (val) == NAMESPACE_DECL
-                 || TREE_CODE (val) == TREE_LIST))
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-    }
-
-  /* If looking for a type, or if there is no non-type binding, select
-     the value binding.  */
-  if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES)))
-    val = binding->type;
-  /* Don't return non-types if we really prefer types.  */
-  else if (val && LOOKUP_TYPES_ONLY (flags)
-          && ! DECL_DECLARES_TYPE_P (val))
-    val = NULL_TREE;
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-}
-
 /* Unscoped lookup of a global: iterate over current namespaces,
    considering using-directives.  */
 
@@ -3689,22 +3707,18 @@ unqualified_namespace_lookup (tree name,
   tree siter;
   struct cp_binding_level *level;
   tree val = NULL_TREE;
-  struct scope_binding binding = EMPTY_SCOPE_BINDING;
 
   timevar_push (TV_NAME_LOOKUP);
 
   for (; !val; scope = CP_DECL_CONTEXT (scope))
     {
+      struct scope_binding binding = EMPTY_SCOPE_BINDING;
       cxx_binding *b =
         cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
 
       if (b)
-       {
-         if (b->value
-             && ((flags & LOOKUP_HIDDEN) || !hidden_name_p (b->value)))
-           binding.value = b->value;
-         binding.type = b->type;
-       }
+       /* LLVM LOCAL mainline */
+       ambiguous_decl (&binding, b, flags);
 
       /* Add all _DECLs seen through local using-directives.  */
       for (level = current_binding_level;
@@ -3729,7 +3743,7 @@ unqualified_namespace_lookup (tree name,
          siter = CP_DECL_CONTEXT (siter);
        }
 
-      val = select_decl (&binding, flags);
+      val = binding.value;
       if (scope == global_namespace)
        break;
     }
@@ -3759,7 +3773,7 @@ lookup_qualified_name (tree scope, tree 
       if (is_type_p)
        flags |= LOOKUP_PREFER_TYPES;
       if (qualified_lookup_using_namespace (name, scope, &binding, flags))
-       t = select_decl (&binding, flags);
+       t = binding.value;
     }
   else if (is_aggr_type (scope, complain))
     t = lookup_member (scope, name, 2, is_type_p);
@@ -3792,7 +3806,8 @@ lookup_using_namespace (tree name, struc
          cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
        /* Resolve ambiguities.  */
        if (val1)
-         ambiguous_decl (name, val, val1, flags);
+         /* LLVM LOCAL mainline */
+         ambiguous_decl (val, val1, flags);
       }
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
 }
@@ -3821,7 +3836,8 @@ qualified_lookup_using_namespace (tree n
        cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
       seen = tree_cons (scope, NULL_TREE, seen);
       if (binding)
-       ambiguous_decl (name, result, binding, flags);
+       /* LLVM LOCAL mainline */
+       ambiguous_decl (result, binding, flags);
 
       /* Consider strong using directives always, and non-strong ones
         if we haven't found a binding yet.  ??? Shouldn't we consider

Modified: head/contrib/gcc/cp/parser.c
==============================================================================
--- head/contrib/gcc/cp/parser.c        Sun Jan  5 20:09:51 2014        
(r260331)
+++ head/contrib/gcc/cp/parser.c        Sun Jan  5 20:33:44 2014        
(r260332)
@@ -10675,13 +10675,19 @@ cp_parser_elaborated_type_specifier (cp_
       if (parser->scope)
        {
          tree decl;
+         tree ambiguous_decls;
 
          decl = cp_parser_lookup_name (parser, identifier,
                                        tag_type,
                                        /*is_template=*/false,
                                        /*is_namespace=*/false,
                                        /*check_dependency=*/true,
-                                       /*ambiguous_decls=*/NULL);
+                                       &ambiguous_decls);
+
+         /* If the lookup was ambiguous, an error will already have been
+            issued.  */
+         if (ambiguous_decls)
+           return error_mark_node;
 
          /* If we are parsing friend declaration, DECL may be a
             TEMPLATE_DECL tree node here.  However, we need to check
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to