From ef6372557ac1b51cd3564304eff5b1cad351f339 Mon Sep 17 00:00:00 2001
From: Mark Mitchell <mark@codesourcery.com>
Date: Fri, 21 May 1999 09:55:50 +0000
Subject: [PATCH] pt.c (tsubst): Don't issue error messages when we're not
 complaining...

	* pt.c (tsubst): Don't issue error messages when we're not
	complaining, even if we see a qualified function type.
	(check_cv_quals_for_unify): Don't allow a qualified function
	type.

From-SVN: r27080
---
 gcc/cp/ChangeLog                           |  7 ++++
 gcc/cp/pt.c                                | 28 +++++++++++++---
 gcc/testsuite/g++.old-deja/g++.pt/unify6.C | 39 ++++++++++++++++++++++
 3 files changed, 70 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/unify6.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f700c81b2ce8..5337856e5499 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+1999-05-21  Mark Mitchell  <mark@codesourcery.com>
+
+	* pt.c (tsubst): Don't issue error messages when we're not
+	complaining, even if we see a qualified function type.
+	(check_cv_quals_for_unify): Don't allow a qualified function
+	type.
+
 1999-05-20  Jason Merrill  <jason@yorick.cygnus.com>
 
 	* class.c (instantiate_type): Downgrade errors for object-dependent
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e4869201bf75..9698b9651242 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6208,6 +6208,16 @@ tsubst (t, args, complain, in_decl)
 		  {
 		    my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (arg))
 					== 't', 0);
+
+		    /* If we're not COMPLAINing, don't let an attempt
+		       to qualify a FUNCTION_TYPE reach
+		       cp_build_qualified_type.  That will result in
+		       an error message.  */
+		    if (!complain
+			&& TREE_CODE (arg) == FUNCTION_TYPE
+			&& CP_TYPE_QUALS (t) != TYPE_UNQUALIFIED)
+		      return error_mark_node;
+
 		    return cp_build_qualified_type
 		      (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t));
 		  }
@@ -8022,10 +8032,20 @@ check_cv_quals_for_unify (strict, arg, parm)
      tree arg;
      tree parm;
 {
-  return !((!(strict & UNIFY_ALLOW_MORE_CV_QUAL)
-	    && !at_least_as_qualified_p (arg, parm))
-	   || (!(strict & UNIFY_ALLOW_LESS_CV_QUAL)
-	       && (!at_least_as_qualified_p (parm, arg))));
+  if (!(strict & UNIFY_ALLOW_MORE_CV_QUAL)
+      && !at_least_as_qualified_p (arg, parm))
+    return 0;
+
+  if (!(strict & UNIFY_ALLOW_LESS_CV_QUAL)
+      && !at_least_as_qualified_p (parm, arg))
+    return 0;
+
+  /* Don't allow unification to create a qualified function type.  */
+  if (TREE_CODE (arg) == FUNCTION_TYPE 
+      && CP_TYPE_QUALS (parm) != TYPE_UNQUALIFIED)
+    return 0;
+
+  return 1;
 }
 
 /* Takes parameters as for type_unification.  Returns 0 if the
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/unify6.C b/gcc/testsuite/g++.old-deja/g++.pt/unify6.C
new file mode 100644
index 000000000000..34b32e4e36dd
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/unify6.C
@@ -0,0 +1,39 @@
+// Build don't link:
+
+// Copyright (C) 1999 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 21 May 1999 <nathan@acm.org>
+
+// Template deduction and type unification should not issue diagnostics when
+// they're trying to see if it's possible.  Here deduction fails in some cases
+// because you cant cv qualify a function type.
+
+template<class T> void fn(){} // A
+
+template<class T> void fn(T const *){} // B
+
+// these next two specializations need to know if they're specializing A or B.
+// They specialize A, because they can't instantiate B.
+
+template<> void fn<int &>() {} // ok, specialize A
+
+template<> void fn<void ()>() {} // ok, specialize A
+
+// now make sure we moan when we really should
+template<class T> void foo(T const *){}
+
+void f()
+{
+  foo<int &>(); // ERROR - attempt to build int & const *
+  foo<void ()>(); // ERROR - attempt to build void (const *)()
+}
+
+typedef void (*Fptr)();
+
+template<class T> void PV(Fptr const &, T const * const &);
+template<class T1, class T2> void PV(T1 const * const &, T2 const * const &);
+
+void baz()
+{
+  void *t;
+  PV(&baz, t);
+}
-- 
GitLab