re PR c++/16965 (Confusing mismatch in error messages)
authorMark Mitchell <mark@codesourcery.com>
Tue, 17 Aug 2004 17:32:37 +0000 (17:32 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 17 Aug 2004 17:32:37 +0000 (17:32 +0000)
PR c++/16965
* cp-tree.h (qualified_name_lookup_error): Add parameter.
* name-lookup.c (do_class_using_decl): Restrict set of entities
passed to cp_emit_debug_info_for_using more carefully.
(lookup_qualified_name): Allow lookup_member to return sets of
ambiguous entries.
* parser.c (cp_parser_lookup_name): Add ambiguous_p parameter.
(cp_parser_primary_expression): Handle ambiguous lookups.
(cp_parser_template_name): Adjust use of cp_parser_lookup_name.
(cp_parser_template_argument): Likewise.
(cp_parser_elaborate_type_specifier): Likewise.
(cp_parser_namespace_name): Likewise.
(cp_parser_class_name): Likewise.
(cp_parser_lookup_name_simple): Likewise.
* pt.c (tsubst_qualified_id): Handle ambiguous results.
(tsubst_expr): Likewise.
* semantics.c (qualified_name_lookup_error): Add decl paramter.
For ambiguous lookups, print candidates.

PR c++/16965
* g++.dg/parse/error17.C: New test.

From-SVN: r86137

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/error17.C [new file with mode: 0644]

index 2946db7567173eee294970b9499d918f695018ea..7ccf881bd5417ed3afca783dbfc339aa9b6a9b8b 100644 (file)
@@ -1,3 +1,24 @@
+2004-08-17  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/16965
+       * cp-tree.h (qualified_name_lookup_error): Add parameter.
+       * name-lookup.c (do_class_using_decl): Restrict set of entities
+       passed to cp_emit_debug_info_for_using more carefully.
+       (lookup_qualified_name): Allow lookup_member to return sets of
+       ambiguous entries.
+       * parser.c (cp_parser_lookup_name): Add ambiguous_p parameter.
+       (cp_parser_primary_expression): Handle ambiguous lookups.
+       (cp_parser_template_name): Adjust use of cp_parser_lookup_name.
+       (cp_parser_template_argument): Likewise.
+       (cp_parser_elaborate_type_specifier): Likewise.
+       (cp_parser_namespace_name): Likewise.
+       (cp_parser_class_name): Likewise.
+       (cp_parser_lookup_name_simple): Likewise.
+       * pt.c (tsubst_qualified_id): Handle ambiguous results.
+       (tsubst_expr): Likewise.
+       * semantics.c (qualified_name_lookup_error): Add decl paramter.
+       For ambiguous lookups, print candidates.
+
 2004-08-16  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        PR c++/6749
index 72011f7356fbd8b611b12c8e5ebc6283b1fae9f8..04a39b7d08b81575d4037600435bc577388b485b 100644 (file)
@@ -4166,7 +4166,7 @@ extern tree finish_template_type                (tree, tree, int);
 extern tree finish_base_specifier               (tree, tree, bool);
 extern void finish_member_declaration           (tree);
 extern void check_multiple_declarators          (void);
-extern void qualified_name_lookup_error                (tree, tree);
+extern void qualified_name_lookup_error                (tree, tree, tree);
 extern tree finish_id_expression                (tree, tree, tree,
                                                 cp_id_kind *, tree *,
                                                 bool, bool, bool *, 
index 2859d8035b9fd95ff6887290f3f4c817ed96866d..ccef113b5bcb5a66133b827a05b9c4d37691f4fd 100644 (file)
@@ -2953,7 +2953,7 @@ do_class_using_decl (tree decl)
       tree r;
 
       r = lookup_qualified_name (scope, name, false, false);
-      if (r && TREE_CODE (r) != ERROR_MARK)
+      if (r && (DECL_P (r) || TREE_CODE (r) == OVERLOAD))
        cp_emit_debug_info_for_using (r, scope);
     }
   return value;
@@ -3813,7 +3813,7 @@ unqualified_namespace_lookup (tree name, int flags)
 
    Returns a DECL (or OVERLOAD, or BASELINK) representing the
    declaration found.  If no suitable declaration can be found,
-   ERROR_MARK_NODE is returned.  Iif COMPLAIN is true and SCOPE is
+   ERROR_MARK_NODE is returned.  If COMPLAIN is true and SCOPE is
    neither a class-type nor a namespace a diagnostic is issued.  */
 
 tree
@@ -3834,7 +3834,7 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
   else if (is_aggr_type (scope, complain))
     {
       tree t;
-      t = lookup_member (scope, name, 0, is_type_p);
+      t = lookup_member (scope, name, 2, is_type_p);
       if (t)
        return t;
     }
index 2193bacc3e6c802a6d6d7736d6e2325f790aa55f..fa41ce6b00d083e2a4e441efed35124988790fd5 100644 (file)
@@ -1831,7 +1831,7 @@ static void cp_parser_label_declaration
 /* Utility Routines */
 
 static tree cp_parser_lookup_name
-  (cp_parser *, tree, bool, bool, bool, bool);
+  (cp_parser *, tree, bool, bool, bool, bool, bool *);
 static tree cp_parser_lookup_name_simple
   (cp_parser *, tree);
 static tree cp_parser_maybe_treat_template_as_class
@@ -2905,7 +2905,18 @@ cp_parser_primary_expression (cp_parser *parser,
        /* Look up the name.  */
        else
          {
-           decl = cp_parser_lookup_name_simple (parser, id_expression);
+           bool ambiguous_p;
+
+           decl = cp_parser_lookup_name (parser, id_expression,
+                                         /*is_type=*/false,
+                                         /*is_template=*/false,
+                                         /*is_namespace=*/false,
+                                         /*check_dependency=*/true,
+                                         &ambiguous_p);
+           /* If the lookup was ambiguous, an error will already have
+              been issued.  */
+           if (ambiguous_p)
+             return error_mark_node;
            /* If name lookup gives us a SCOPE_REF, then the
               qualifying scope was dependent.  Just propagate the
               name.  */
@@ -8331,7 +8342,8 @@ cp_parser_type_parameter (cp_parser* parser)
                                        /*is_type=*/false,
                                        /*is_template=*/is_template,
                                        /*is_namespace=*/false,
-                                       /*check_dependency=*/true);
+                                       /*check_dependency=*/true,
+                                       /*ambiguous_p=*/NULL);
            /* See if the default argument is valid.  */
            default_argument
              = check_template_template_default_arg (default_argument);
@@ -8710,7 +8722,8 @@ cp_parser_template_name (cp_parser* parser,
                                /*is_type=*/false,
                                /*is_template=*/false,
                                /*is_namespace=*/false,
-                               check_dependency_p);
+                               check_dependency_p,
+                               /*ambiguous_p=*/NULL);
   decl = maybe_get_template_decl_from_type_decl (decl);
 
   /* If DECL is a template, then the name was a template-name.  */
@@ -8900,7 +8913,8 @@ cp_parser_template_argument (cp_parser* parser)
                                          /*is_type=*/false,
                                          /*is_template=*/template_p,
                                          /*is_namespace=*/false,
-                                         /*check_dependency=*/true);
+                                         /*check_dependency=*/true,
+                                         /*ambiguous_p=*/NULL);
       if (TREE_CODE (argument) != TEMPLATE_DECL
          && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
        cp_parser_error (parser, "expected template-name");
@@ -9753,7 +9767,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
                                        /*is_type=*/true,
                                        /*is_template=*/false,
                                        /*is_namespace=*/false,
-                                       /*check_dependency=*/true);
+                                       /*check_dependency=*/true,
+                                       /*ambiguous_p=*/NULL);
 
          /* If we are parsing friend declaration, DECL may be a
             TEMPLATE_DECL tree node here.  However, we need to check
@@ -10029,7 +10044,8 @@ cp_parser_namespace_name (cp_parser* parser)
                                          /*is_type=*/false,
                                          /*is_template=*/false,
                                          /*is_namespace=*/true,
-                                         /*check_dependency=*/true);
+                                         /*check_dependency=*/true,
+                                         /*ambiguous_p=*/NULL);
   /* If it's not a namespace, issue an error.  */
   if (namespace_decl == error_mark_node
       || TREE_CODE (namespace_decl) != NAMESPACE_DECL)
@@ -12239,7 +12255,8 @@ cp_parser_class_name (cp_parser *parser,
                                        type_p,
                                        /*is_template=*/false,
                                        /*is_namespace=*/false,
-                                       check_dependency_p);
+                                       check_dependency_p,
+                                       /*ambiguous_p=*/NULL);
        }
     }
   else
@@ -14121,16 +14138,24 @@ cp_parser_label_declaration (cp_parser* parser)
    are ignored.
 
    If CHECK_DEPENDENCY is TRUE, names are not looked up in dependent
-   types.  */
+   types.  
+
+   If AMBIGUOUS_P is non-NULL, it is set to true if name-lookup
+   results in an ambiguity, and false otherwise.  */
 
 static tree
 cp_parser_lookup_name (cp_parser *parser, tree name,
                       bool is_type, bool is_template, bool is_namespace,
-                      bool check_dependency)
+                      bool check_dependency,
+                      bool *ambiguous_p)
 {
   tree decl;
   tree object_type = parser->context->object_type;
 
+  /* Assume that the lookup will be unambiguous.  */
+  if (ambiguous_p)
+    *ambiguous_p = false;
+
   /* Now that we have looked up the name, the OBJECT_TYPE (if any) is
      no longer valid.  Note that if we are parsing tentatively, and
      the parse fails, OBJECT_TYPE will be automatically restored.  */
@@ -14278,6 +14303,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
   /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
   if (TREE_CODE (decl) == TREE_LIST)
     {
+      if (ambiguous_p)
+       *ambiguous_p = true;
       /* The error message we have to print is too complicated for
         cp_parser_error, so we incorporate its actions directly.  */
       if (!cp_parser_simulate_error (parser))
@@ -14319,7 +14346,8 @@ cp_parser_lookup_name_simple (cp_parser* parser, tree name)
                                /*is_type=*/false,
                                /*is_template=*/false,
                                /*is_namespace=*/false,
-                               /*check_dependency=*/true);
+                               /*check_dependency=*/true,
+                               /*ambiguous_p=*/NULL);
 }
 
 /* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in
index d3d5267dcefcb06a48c41f5b2447732db09e7ed1..74322df0663d16a8cc1342a3caa4d918e071fc87 100644 (file)
@@ -7396,18 +7396,28 @@ tsubst_qualified_id (tree qualified_id, tree args,
     }
   
   if (DECL_P (expr))
-    check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
-                                        scope);
-  
-  /* Remember that there was a reference to this entity.  */
-  if (DECL_P (expr))
-    mark_used (expr);
+    {
+      check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
+                                          scope);
+      /* Remember that there was a reference to this entity.  */
+      mark_used (expr);
+    }
+
+  if (expr == error_mark_node || TREE_CODE (expr) == TREE_LIST)
+    {
+      if (complain & tf_error)
+       qualified_name_lookup_error (scope, 
+                                    TREE_OPERAND (qualified_id, 1),
+                                    expr);
+      return error_mark_node;
+    }
 
   if (is_template)
     expr = lookup_template_function (expr, template_args);
 
   if (expr == error_mark_node && complain & tf_error)
-    qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1));
+    qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1),
+                                expr);
   else if (TYPE_P (scope))
     {
       expr = (adjust_result_of_qualified_name_lookup 
@@ -7855,8 +7865,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            decl = lookup_qualified_name (scope, name,
                                          /*is_type_p=*/false,
                                          /*complain=*/false);
-           if (decl == error_mark_node)
-             qualified_name_lookup_error (scope, name);
+           if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
+             qualified_name_lookup_error (scope, name, decl);
            else
              do_local_using_decl (decl, scope, name);
          }
@@ -8510,7 +8520,8 @@ tsubst_copy_and_build (tree t,
                            args);
            else
              {
-               qualified_name_lookup_error (TREE_TYPE (object), tmpl);
+               qualified_name_lookup_error (TREE_TYPE (object), tmpl,
+                                            member);
                return error_mark_node;
              }
          }
index 393020f397045c593dbdc688b57e5302dd9d3377..f21c926d1dd2c08f9c37a096a612c45dfb96b556 100644 (file)
@@ -2290,15 +2290,21 @@ check_multiple_declarators (void)
     error ("multiple declarators in template declaration");
 }
 
-/* Issue a diagnostic that NAME cannot be found in SCOPE.  */
+/* Issue a diagnostic that NAME cannot be found in SCOPE.  DECL is
+   what we found when we tried to do the lookup.  */
 
 void
-qualified_name_lookup_error (tree scope, tree name)
+qualified_name_lookup_error (tree scope, tree name, tree decl)
 {
   if (TYPE_P (scope))
     {
       if (!COMPLETE_TYPE_P (scope))
        error ("incomplete type `%T' used in nested name specifier", scope);
+      else if (TREE_CODE (decl) == TREE_LIST)
+       {
+         error ("reference to `%T::%D' is ambiguous", scope, name);
+         print_candidates (decl);
+       }
       else
        error ("`%D' is not a member of `%T'", name, scope);
     }
@@ -2374,7 +2380,7 @@ finish_id_expression (tree id_expression,
              /* If the qualifying type is non-dependent (and the name
                 does not name a conversion operator to a dependent
                 type), issue an error.  */
-             qualified_name_lookup_error (scope, id_expression);
+             qualified_name_lookup_error (scope, id_expression, decl);
              return error_mark_node;
            }
          else if (!scope)
index 64344815c7d9f33c87110119510c294dbb3d1517..cd593ddcc7244ac754ade69a1b5a927dfe590289 100644 (file)
@@ -1,3 +1,8 @@
+2004-08-17  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/16965
+       * g++.dg/parse/error17.C: New test.
+       
 2004-08-17  Dorit Naishlos  <dorit@il.ibm.com>
 
        * gcc.dg/vect: New directory for vectorizer tests.
diff --git a/gcc/testsuite/g++.dg/parse/error17.C b/gcc/testsuite/g++.dg/parse/error17.C
new file mode 100644 (file)
index 0000000..2a8f3f8
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/16965
+
+template <typename T> struct B { 
+  static int Bar(T); // { dg-error "" }
+}; 
+struct D : B<int>, B<char> {}; 
+int i2 = D::Bar(2); // { dg-error "" }