Improve various diagnostic issues.
authorJason Merrill <jason@redhat.com>
Mon, 14 Nov 2016 04:58:45 +0000 (23:58 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 14 Nov 2016 04:58:45 +0000 (23:58 -0500)
* call.c (build_new_method_call_1): Include template arguments in
error message.
(print_error_for_call_failure): Likewise.
(build_new_function_call): Pass them in.
* name-lookup.c (supplement_binding_1): Don't complain about a
conflict with an erroneous declaration.
* error.c (dump_decl): Fix printing of alias declaration.
* decl.c (make_typename_type): Call cxx_incomplete_type_error.
* parser.c (cp_parser_diagnose_invalid_type_name): Likewise.
* semantics.c (perform_koenig_lookup): Don't wrap an error in
TEMPLATE_ID_EXPR.

From-SVN: r242376

14 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp0x/alias-decl-56.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/crash7.C
gcc/testsuite/g++.dg/template/error56.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/forward-inner.C
gcc/testsuite/g++.old-deja/g++.other/decl5.C
libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc
libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc

index 8683744..daeb517 100644 (file)
@@ -1,3 +1,17 @@
+2016-11-13  Jason Merrill  <jason@redhat.com>
+
+       * call.c (build_new_method_call_1): Include template arguments in
+       error message.
+       (print_error_for_call_failure): Likewise.
+       (build_new_function_call): Pass them in.
+       * name-lookup.c (supplement_binding_1): Don't complain about a
+       conflict with an erroneous declaration.
+       * error.c (dump_decl): Fix printing of alias declaration.
+       * decl.c (make_typename_type): Call cxx_incomplete_type_error.
+       * parser.c (cp_parser_diagnose_invalid_type_name): Likewise.
+       * semantics.c (perform_koenig_lookup): Don't wrap an error in
+       TEMPLATE_ID_EXPR.
+
 2016-11-12  Jason Merrill  <jason@redhat.com>
 
        CWG 2233
index 0dcf322..f6f4590 100644 (file)
@@ -4146,8 +4146,16 @@ static void
 print_error_for_call_failure (tree fn, vec<tree, va_gc> *args,
                              struct z_candidate *candidates)
 {
+  tree targs = NULL_TREE;
+  if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+    {
+      targs = TREE_OPERAND (fn, 1);
+      fn = TREE_OPERAND (fn, 0);
+    }
   tree name = DECL_NAME (OVL_CURRENT (fn));
   location_t loc = location_of (name);
+  if (targs)
+    name = lookup_template_function (name, targs);
 
   if (!any_strictly_viable (candidates))
     error_at (loc, "no matching function for call to %<%D(%A)%>",
@@ -4215,8 +4223,6 @@ build_new_function_call (tree fn, vec<tree, va_gc> **args, bool koenig_p,
            return cp_build_function_call_vec (candidates->fn, args, complain);
 
          // Otherwise, emit notes for non-viable candidates.
-         if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
-           fn = TREE_OPERAND (fn, 0);
          print_error_for_call_failure (fn, *args, candidates);
        }
       result = error_mark_node;
@@ -8649,19 +8655,20 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
                   TREE_TYPE (instance));
          else
            {
-             char *pretty_name;
-             bool free_p;
-             tree arglist;
-
-             pretty_name = name_as_c_string (name, basetype, &free_p);
-             arglist = build_tree_list_vec (user_args);
+             tree arglist = build_tree_list_vec (user_args);
+             tree errname = name;
+             if (IDENTIFIER_CTOR_OR_DTOR_P (errname))
+               {
+                 tree fn = DECL_ORIGIN (get_first_fn (fns));
+                 errname = DECL_NAME (fn);
+               }
+             if (explicit_targs)
+               errname = lookup_template_function (errname, explicit_targs);
              if (skip_first_for_error)
                arglist = TREE_CHAIN (arglist);
-             error ("no matching function for call to %<%T::%s(%A)%#V%>",
-                    basetype, pretty_name, arglist,
+             error ("no matching function for call to %<%T::%E(%A)%#V%>",
+                    basetype, errname, arglist,
                     TREE_TYPE (instance));
-             if (free_p)
-               free (pretty_name);
            }
          print_z_candidates (location_of (name), candidates);
        }
index 6101504..ccd65b1 100644 (file)
@@ -3756,8 +3756,13 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   if (!t)
     {
       if (complain & tf_error)
-       error (want_template ? G_("no class template named %q#T in %q#T")
-              : G_("no type named %q#T in %q#T"), name, context);
+       {
+         if (!COMPLETE_TYPE_P (context))
+           cxx_incomplete_type_error (NULL_TREE, context);
+         else
+           error (want_template ? G_("no class template named %q#T in %q#T")
+                  : G_("no type named %q#T in %q#T"), name, context);
+       }
       return error_mark_node;
     }
   
index aa92a7e..fe1f751 100644 (file)
@@ -1049,7 +1049,9 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
          pp_cxx_whitespace (pp);
          pp_cxx_ws_string (pp, "=");
          pp_cxx_whitespace (pp);
-         dump_type (pp, DECL_ORIGINAL_TYPE (t), flags);
+         dump_type (pp, (DECL_ORIGINAL_TYPE (t)
+                         ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t)),
+                    flags);
          break;
        }
       if ((flags & TFF_DECL_SPECIFIERS)
index 8db6cfd..172ec82 100644 (file)
@@ -565,7 +565,8 @@ supplement_binding_1 (cxx_binding *binding, tree decl)
     }
   else
     {
-      diagnose_name_conflict (decl, bval);
+      if (!error_operand_p (bval))
+       diagnose_name_conflict (decl, bval);
       ok = false;
     }
 
index 1efe4ea..e669c0d 100644 (file)
@@ -3272,7 +3272,10 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
                  parser->scope, id, parser->scope);
       else if (TYPE_P (parser->scope))
        {
-         if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+         if (!COMPLETE_TYPE_P (parser->scope))
+           cxx_incomplete_type_error (location_of (id), NULL_TREE,
+                                      parser->scope);
+         else if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
            error_at (location_of (id),
                      "%qE in %q#T does not name a template type",
                      id, parser->scope);
index 1a7c478..d390bf4 100644 (file)
@@ -2259,7 +2259,7 @@ perform_koenig_lookup (cp_expr fn, vec<tree, va_gc> *args,
        }
     }
 
-  if (fn && template_id)
+  if (fn && template_id && fn != error_mark_node)
     fn = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fn, tmpl_args);
   
   return fn;
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-56.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-56.C
new file mode 100644 (file)
index 0000000..7e894cd
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do compile { target c++11 } }
+
+using I = int;                 // { dg-message "int" }
+using I = float;               // { dg-error "float" }
index 5bd275e..691628e 100644 (file)
@@ -7,7 +7,7 @@
 
 template <typename> struct A
 {
-    template <typename> A(typename A::X) {} // { dg-error "no type" }
+    template <typename> A(typename A::X) {} // { dg-error "incomplete" }
 };
 
 // We currently don't give the "no match" error because we don't add the
diff --git a/gcc/testsuite/g++.dg/template/error56.C b/gcc/testsuite/g++.dg/template/error56.C
new file mode 100644 (file)
index 0000000..3eda04c
--- /dev/null
@@ -0,0 +1,12 @@
+// Test that the error message mentions the template arguments.
+
+struct A
+{
+  template <class T> void f(T);
+  void f();
+};
+
+int main()
+{
+  A().f<1>();                  // { dg-error "f<1>" }
+}
index dae9948..5336d4e 100644 (file)
@@ -3,13 +3,13 @@
 
 // Verify warnings for and within classes, and by extension, struct and union.
 class C1;
-class C1::C2;      // { dg-error "does not name a type" }
+class C1::C2;      // { dg-error "incomplete" }
 class C1::C2::C3;  // { dg-error "has not been declared" }
 
 class C1 {
  public:
   class C2;
-  class C2::C3;    // { dg-error "does not name a type" }
+  class C2::C3;    // { dg-error "incomplete" }
   class C2 {
    public:
     class C3;
index 2a7a5f2..aa2acf8 100644 (file)
@@ -19,7 +19,7 @@ struct A {
   struct Z;
   expand me;          // { dg-error "'expand' does not name a type" }
   void foo(struct A::e);
-  void foo(struct A::z);  // { dg-error "does not name a type" }
+  void foo(struct A::z);  // { dg-error "incomplete" }
 };
 
 struct Q;
index 4f0720a..a659716 100644 (file)
@@ -41,7 +41,7 @@ void test01()
   typedef make_signed<float>::type     test5_type;
 }
 
-// { dg-error "does not name a type" "" { target *-*-* } 32 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 32 }
 // { dg-error "required from here" "" { target *-*-* } 34 }
 // { dg-error "required from here" "" { target *-*-* } 36 }
 // { dg-error "required from here" "" { target *-*-* } 39 }
index 8eea6b9..6a93e2f 100644 (file)
@@ -41,7 +41,7 @@ void test01()
   typedef make_unsigned<float>::type           test5_type;
 }
 
-// { dg-error "does not name a type" "" { target *-*-* } 32 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 32 }
 // { dg-error "required from here" "" { target *-*-* } 34 }
 // { dg-error "required from here" "" { target *-*-* } 36 }
 // { dg-error "required from here" "" { target *-*-* } 39 }