Hi,
On 04/28/2015 02:59 PM, Jason Merrill wrote:
On 04/28/2015 08:54 AM, Paolo Carlini wrote:
Hi,
On 04/28/2015 02:45 PM, Jason Merrill wrote:
On 04/28/2015 06:59 AM, Paolo Carlini wrote:
&& !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
the name
of the macro seems weird to me: it mentions friends (and friends are
mentioned in its comment too) but isn't used only for DECL_FRIEND_P
true
and indeed it is true for the non-friend 'fn' in the snippet at
issue).
It shouldn't be true for fn, that's a bug.
Ok, but then what? Its definition boils down to very basic macros:
#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \
(DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL))
It could be only matter of adding a DECL_FRIEND_P check at the
beginning?
Sure, that sounds likely.
The simple idea almost works. The below however has an additional
STRIP_TEMPLATE, which I added to avoid ICEs for testcases like
g++.dg/template/friend26.C, where DECL_FRIEND_P of plain tmpl is false,
whereas DECL_FRIEND_P of STRIP_TEMPLATE (tmpl) is true for the use of
DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION in template_for_substitution.
Does that make sense? Then we come to the two *remaining* regressions:
g++.old-deja/g++.pt/friend10.C
g++.old-deja/g++.pt/link1.C
which fail at link time. Those would disappear if I replace the already
mentioned DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION in
template_for_substitution with the old implemention of it, just checking
DECL_TEMPLATE_INFO && !DECL_USE_TEMPLATE. Interestingly, note that with
current (and old) clang too these two tests do nor link. I'm a bit stuck
on this...
Thanks!
Paolo.
/////////////////////
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 222531)
+++ cp/cp-tree.h (working copy)
@@ -4062,7 +4062,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_a
instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be
a DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION. */
#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \
- (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL))
+ (DECL_FRIEND_P (STRIP_TEMPLATE (DECL)) && DECL_TEMPLATE_INFO (DECL) \
+ && !DECL_USE_TEMPLATE (DECL))
/* Nonzero if DECL is a function generated from a function 'temploid',
i.e. template, member of class template, or dependent friend. */
Index: testsuite/g++.dg/diagnostic/bindings1.C
===================================================================
--- testsuite/g++.dg/diagnostic/bindings1.C (revision 222531)
+++ testsuite/g++.dg/diagnostic/bindings1.C (working copy)
@@ -10,7 +10,7 @@ struct x {typedef int type;};
int main()
{
- if (strcmp (foo(x(), 3), "const char* foo(T, typename T::type) "
+ if (strcmp (foo(x(), 3), "const char* foo<T>(T, typename T::type) "
"[with T = x; typename T::type = int]") == 0)
return 0;
else
Index: testsuite/g++.dg/ext/pretty1.C
===================================================================
--- testsuite/g++.dg/ext/pretty1.C (revision 222531)
+++ testsuite/g++.dg/ext/pretty1.C (working copy)
@@ -60,8 +60,8 @@ __assert_fail (const char *cond, const char *file,
abort ();
}
-// { dg-final { scan-assembler "int bar\\(T\\).*with T = int" } }
+// { dg-final { scan-assembler "int bar\\<T\\>\\(T\\).*with T = int" } }
// { dg-final { scan-assembler "top level" } }
// { dg-final { scan-assembler "int main\\(\\)" } }
-// { dg-final { scan-assembler "int bar\\(T\\).*with T = double" } }
-// { dg-final { scan-assembler "int bar\\(T\\).*with T = unsigned char\*" } }
+// { dg-final { scan-assembler "int bar\\<T\\>\\(T\\).*with T = double" } }
+// { dg-final { scan-assembler "int bar\\<T\\>\\(T\\).*with T = unsigned
char\*" } }
Index: testsuite/g++.dg/ext/pretty4.C
===================================================================
--- testsuite/g++.dg/ext/pretty4.C (revision 0)
+++ testsuite/g++.dg/ext/pretty4.C (working copy)
@@ -0,0 +1,19 @@
+// PR c++/39813
+// { dg-do run }
+
+extern "C" int strcmp(const char*, const char*);
+
+struct B
+{
+ template <typename T>
+ const char* fn() { return __PRETTY_FUNCTION__; }
+};
+
+int main()
+{
+ if (strcmp (B().fn<int>(),
+ "const char* B::fn<T>() [with T = int]") == 0)
+ return 0;
+ else
+ return 1;
+}
Index: testsuite/g++.dg/template/local1.C
===================================================================
--- testsuite/g++.dg/template/local1.C (revision 222531)
+++ testsuite/g++.dg/template/local1.C (working copy)
@@ -14,7 +14,7 @@ template<class T> void A::f()
struct B
{
void g() {}
- static int x; // { dg-error "static.*int A::f\\(\\)::B::x" "" }
+ static int x; // { dg-error "static.*int A::f\\<T\\>\\(\\)::B::x" "" }
};
}
Index: testsuite/g++.dg/warn/pr61945.C
===================================================================
--- testsuite/g++.dg/warn/pr61945.C (revision 222531)
+++ testsuite/g++.dg/warn/pr61945.C (working copy)
@@ -7,5 +7,5 @@ class A {
};
class B : A {
template <typename>
- void foo (); // { dg-warning "by .B::foo\\(\\)." }
+ void foo (); // { dg-warning "by .B::foo\\<
\\<template-parameter-1-1\\> \\>\\(\\)." }
};
Index: testsuite/g++.old-deja/g++.ext/pretty3.C
===================================================================
--- testsuite/g++.old-deja/g++.ext/pretty3.C (revision 222531)
+++ testsuite/g++.old-deja/g++.ext/pretty3.C (working copy)
@@ -20,7 +20,7 @@ template<class T> void f1 (T)
if (strcmp (function, "f1"))
bad = true;
- if (strcmp (pretty, "void f1(T) [with T = float]")) // only for float
instantiation
+ if (strcmp (pretty, "void f1<T>(T) [with T = float]")) // only for float
instantiation
bad = true;
}
Index: testsuite/g++.old-deja/g++.pt/memtemp77.C
===================================================================
--- testsuite/g++.old-deja/g++.pt/memtemp77.C (revision 222531)
+++ testsuite/g++.old-deja/g++.pt/memtemp77.C (working copy)
@@ -19,7 +19,7 @@ const char* S3<char>::h(int) { return __PRETTY_FUN
int main()
{
if (strcmp (S3<double>::h(7),
- "static const char* S3<T>::h(U) [with U = int; T = double]") == 0)
+ "static const char* S3<T>::h<U>(U) [with U = int; T = double]")
== 0)
return 0;
else
return 1;