From 33dd07ee9d7fe8fb3ff9c0391bc6891c2fbd1b90 Mon Sep 17 00:00:00 2001
From: Mark Mitchell <mark@codesourcery.com>
Date: Mon, 29 Apr 2002 14:56:24 +0000
Subject: [PATCH] re PR c++/6492 (New boost regression (friends))

	PR c++/6492
	* pt.c (tsubst_friend_class): If the friend has an explicit scope,
	enter that scope before name lookup.

	PR c++/6486
	* method.c (do_build_copy_constructor): Avoid building
	cv-qualified reference types.

	PR c++/6486
	* g++.dg/template/friend6.C: New test.

	PR c++/6492
	* g++.dg/init/copy1.C: New test.

From-SVN: r52895
---
 gcc/cp/ChangeLog                        | 10 +++++
 gcc/cp/method.c                         | 13 ++++--
 gcc/testsuite/ChangeLog                 |  8 ++++
 gcc/testsuite/g++.dg/init/copy1.C       | 21 ++++++++++
 gcc/testsuite/g++.dg/template/friend6.C | 53 +++++++++++++++++++++++++
 5 files changed, 102 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/init/copy1.C
 create mode 100644 gcc/testsuite/g++.dg/template/friend6.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e076a34a443b..9ad6e11b0495 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2002-04-29  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/6492
+	* pt.c (tsubst_friend_class): If the friend has an explicit scope,
+	enter that scope before name lookup.
+
+	PR c++/6486
+	* method.c (do_build_copy_constructor): Avoid building
+	cv-qualified reference types.
+  
 2002-04-29  Nathan Sidwell  <nathan@codesourcery.com>
 
 	PR c++/5719
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index b68906782231..b74bd285243f 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -562,6 +562,7 @@ do_build_copy_constructor (fndecl)
 	{
 	  tree init;
 	  tree field = fields;
+	  tree expr_type;
 
 	  if (TREE_CODE (field) != FIELD_DECL)
 	    continue;
@@ -584,9 +585,15 @@ do_build_copy_constructor (fndecl)
 	  else
 	    continue;
 
-	  init = build (COMPONENT_REF,
-	                cp_build_qualified_type (TREE_TYPE (field), cvquals),
-	                init, field);
+	  /* Compute the type of "init->field".  If the copy-constructor
+	     parameter is, for example, "const S&", and the type of
+	     the field is "T", then the type will usually be "const
+	     T".  (There are no cv-qualified variants of reference
+	     types.)  */
+	  expr_type = TREE_TYPE (field);
+	  if (TREE_CODE (expr_type) != REFERENCE_TYPE)
+	    expr_type = cp_build_qualified_type (expr_type, cvquals);
+	  init = build (COMPONENT_REF, expr_type, init, field);
 	  init = build_tree_list (NULL_TREE, init);
 
 	  member_init_list
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0024a9212112..722263a9d990 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2002-04-29  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/6486
+	* g++.dg/template/friend6.C: New test.
+
+	PR c++/6492
+	* g++.dg/init/copy1.C: New test.
+
 2002-04-29  Nathan Sidwell  <nathan@codesourcery.com>
 
 	* g++.dg/warn/effc1.C: New test.
diff --git a/gcc/testsuite/g++.dg/init/copy1.C b/gcc/testsuite/g++.dg/init/copy1.C
new file mode 100644
index 000000000000..91a84ae3e3cc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/copy1.C
@@ -0,0 +1,21 @@
+// { dg-do compile }
+
+class A {
+public:
+    A(){}
+    A( const A& a ){}
+};
+
+class B  : public A
+{
+public:
+  B( int& s) : s_(s){}
+  int& s_;
+};
+
+int main()
+{
+  int i;
+  B x1( i );
+  B x2( x1 );
+}
diff --git a/gcc/testsuite/g++.dg/template/friend6.C b/gcc/testsuite/g++.dg/template/friend6.C
new file mode 100644
index 000000000000..e330d981892c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend6.C
@@ -0,0 +1,53 @@
+// { dg-do compile }
+
+namespace boost_no_member_template_friends{
+
+template <class T>
+class foobar;
+
+template <class T>
+class foo
+{
+private:
+   template<typename Y> friend class foobar;
+   template<typename Y> friend class foo;
+   template<typename Y> friend bool must_be_friend_proc(const foo<Y>& f);
+   int i;
+public:
+   foo(){ i = 0; }
+   template <class U>
+   foo(const foo<U>& f){ i = f.i; }
+};
+
+template <class T>
+class foo;
+
+template <class T>
+bool must_be_friend_proc(const foo<T>& f);
+
+template <class T>
+bool must_be_friend_proc(const foo<T>& f)
+{ return f.i != 0; }
+
+template <class T>
+class foobar
+{
+   int i;
+public:
+   template <class U>
+   foobar(const foo<U>& f)
+   { i = f.i; }
+};
+
+
+int test()
+{
+   foo<int> fi;
+   foo<double> fd(fi);
+   (void) &fd;           // avoid "unused variable" warning
+   foobar<long> fb(fi);
+   (void) &fb;           // avoid "unused variable" warning
+   return 0;
+}
+
+}
-- 
GitLab