diff mbox

[C++,RFC/Patch] PR 39813

Message ID 553FC704.4060105@oracle.com
State New
Headers show

Commit Message

Paolo Carlini April 28, 2015, 5:44 p.m. UTC
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.

/////////////////////
diff mbox

Patch

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;