From a38f55dbfdae98511d6e8cf3e6c1cb0e06bb89a6 Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Fri, 13 Nov 2009 09:40:32 -0500
Subject: [PATCH] re PR c++/35075 (ICE with references in templates)

PR c++/35075
	* pt.c (convert_nontype_argument): Give helpful error about
	reference variable argument to reference template parameter.

From-SVN: r154151
---
 gcc/cp/ChangeLog                     |  4 ++++
 gcc/cp/pt.c                          | 21 +++++++++++++++++++++
 gcc/testsuite/ChangeLog              |  3 +++
 gcc/testsuite/g++.dg/template/ref5.C | 11 +++++++++++
 4 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/template/ref5.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b148d23..d4c44a5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
 2009-11-13  Jason Merrill  <jason@redhat.com>
 
+	PR c++/35075
+	* pt.c (convert_nontype_argument): Give helpful error about
+	reference variable argument to reference template parameter.
+
 	PR c++/21008, DR 515
 	* semantics.c (finish_non_static_data_member): Don't check
 	derivation in a template.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 85d9fff..c799368 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4927,6 +4927,27 @@ convert_nontype_argument (tree type, tree expr)
 	 shall be one of: [...]
 
 	 -- the address of an object or function with external linkage.  */
+      if (TREE_CODE (expr) == INDIRECT_REF
+	  && TYPE_REF_OBJ_P (TREE_TYPE (TREE_OPERAND (expr, 0))))
+	{
+	  expr = TREE_OPERAND (expr, 0);
+	  if (DECL_P (expr))
+	    {
+	      error ("%q#D is not a valid template argument for type %qT "
+		     "because a reference variable does not have a constant "
+		     "address", expr, type);
+	      return NULL_TREE;
+	    }
+	}
+
+      if (!DECL_P (expr))
+	{
+	  error ("%qE is not a valid template argument for type %qT "
+		 "because it is not an object with external linkage",
+		 expr, type);
+	  return NULL_TREE;
+	}
+
       if (!DECL_EXTERNAL_LINKAGE_P (expr))
 	{
 	  error ("%qE is not a valid template argument for type %qT "
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 82752b8..e60555a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
 2009-11-13  Jason Merrill  <jason@redhat.com>
 
+	PR c++/35075
+	* g++.dg/template/ref5.C: New.
+
 	PR c++/21008, DR 515
 	* g++.dg/template/inherit4.C: New.
 	* g++.dg/lookup/scoped8.C: Adjust.
diff --git a/gcc/testsuite/g++.dg/template/ref5.C b/gcc/testsuite/g++.dg/template/ref5.C
new file mode 100644
index 0000000..efefbef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ref5.C
@@ -0,0 +1,11 @@
+// PR c++/35075
+
+template<int&> struct A {};
+
+template<typename T> struct B
+{
+  static const T t;
+  A<t> a;			// { dg-error "reference variable" }
+};
+
+B<int&> b;			// { dg-message "instantiated" }
--
libgit2 0.26.0