aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-03-20 23:25:16 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-03-20 23:25:16 -0400
commit9f5d44f495b5ed8dad5890c30ced1b1e3a8128f7 (patch)
tree14e8bdf7468a181a82ae9a0ab9568863c0335a17 /gcc
parent327a1118271129829e9ac0abd894eb29254b93eb (diff)
downloadgcc-9f5d44f495b5ed8dad5890c30ced1b1e3a8128f7.zip
gcc-9f5d44f495b5ed8dad5890c30ced1b1e3a8128f7.tar.gz
gcc-9f5d44f495b5ed8dad5890c30ced1b1e3a8128f7.tar.bz2
re PR c++/17232 ([DR 1640] classes and class template specializations treated differently w.r.t. core issue #337)
PR c++/17232 PR c++/56642 * pt.c (tsubst_decl): Check return value of register_specialization. * typeck2.c (abstract_virtuals_error_sfinae): Re-apply complete_type change. From-SVN: r196849
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/cp/typeck2.c4
-rw-r--r--gcc/testsuite/g++.dg/template/abstract-dr337.C4
-rw-r--r--gcc/testsuite/g++.dg/template/friend54.C18
5 files changed, 39 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b2796b6..4191c86 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2013-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/17232
+ PR c++/56642
+ * pt.c (tsubst_decl): Check return value of register_specialization.
+ * typeck2.c (abstract_virtuals_error_sfinae): Re-apply complete_type
+ change.
+
2013-03-17 Jason Merrill <jason@redhat.com>
PR c++/54359
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4274479..531d860 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10285,7 +10285,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
DECL_TEMPLATE_INFO (r)
= build_template_info (gen_tmpl, argvec);
SET_DECL_IMPLICIT_INSTANTIATION (r);
- register_specialization (r, gen_tmpl, argvec, false, hash);
+
+ tree new_r
+ = register_specialization (r, gen_tmpl, argvec, false, hash);
+ if (new_r != r)
+ /* We instantiated this while substituting into
+ the type earlier (template/friend54.C). */
+ RETURN (new_r);
/* We're not supposed to instantiate default arguments
until they are called, for a template. But, for a
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 24b5593..3bac67c 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -265,6 +265,10 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
return 0;
type = TYPE_MAIN_VARIANT (type);
+ /* In SFINAE context, force instantiation. */
+ if (!(complain & tf_error))
+ complete_type (type);
+
/* If the type is incomplete, we register it within a hash table,
so that we can check again once it is completed. This makes sense
only for objects for which we have a declaration or at least a
diff --git a/gcc/testsuite/g++.dg/template/abstract-dr337.C b/gcc/testsuite/g++.dg/template/abstract-dr337.C
index 4f66c1c..6905262 100644
--- a/gcc/testsuite/g++.dg/template/abstract-dr337.C
+++ b/gcc/testsuite/g++.dg/template/abstract-dr337.C
@@ -6,8 +6,8 @@ class A {
};
template<typename T>
-void g(T (*a)[1]) {} // { dg-error "abstract" "" { xfail *-*-* } }
+void g(T (*a)[1]) {} // { dg-error "abstract" "" }
int main() {
- g<A<int> >(0); // { dg-error "no matching function" "" { xfail *-*-* } }
+ g<A<int> >(0); // { dg-error "no matching function" }
}
diff --git a/gcc/testsuite/g++.dg/template/friend54.C b/gcc/testsuite/g++.dg/template/friend54.C
new file mode 100644
index 0000000..ead7a72
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend54.C
@@ -0,0 +1,18 @@
+// PR c++/56642
+
+template <class T> struct A;
+
+template <class T>
+A<T> f(T*) { return A<T>(); }
+
+template <class T>
+struct A
+{
+ friend A f<T>(T*);
+};
+
+int main()
+{
+ int *p = 0;
+ f(p);
+}