public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* c++: local externs in templates do not get template head
@ 2020-09-14 16:45 Nathan Sidwell
  2020-09-14 16:49 ` Marek Polacek
  2020-09-14 22:47 ` Tobias Burnus
  0 siblings, 2 replies; 6+ messages in thread
From: Nathan Sidwell @ 2020-09-14 16:45 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 603 bytes --]

Now we consistently mark local externs with DECL_LOCAL_DECL_P, we can
teach the template machinery not to give them a TEMPLATE_DECL head,
and the instantiation machinery treat them as the local specialiations
they are.  (openmp UDRs also fall into this category, and are dealt
with similarly.)

         gcc/cp/
         * pt.c (push_template_decl_real): Don't attach a template head to
         local externs.
         (tsubst_function_decl): Add support for headless local extern
         decls.
         (tsubst_decl): Add support for headless local extern decls.

pushed to trunk
-- 
Nathan Sidwell

[-- Attachment #2: local-extern-tpl.diff --]
[-- Type: text/x-patch, Size: 3432 bytes --]

diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c
index 0f52a9ed77d..8124efcbe24 100644
--- i/gcc/cp/pt.c
+++ w/gcc/cp/pt.c
@@ -6071,7 +6071,11 @@ push_template_decl_real (tree decl, bool is_friend)
     {
       if (is_primary)
 	retrofit_lang_decl (decl);
-      if (DECL_LANG_SPECIFIC (decl))
+      if (DECL_LANG_SPECIFIC (decl)
+	  && ((TREE_CODE (decl) != VAR_DECL
+	       && TREE_CODE (decl) != FUNCTION_DECL)
+	      || !ctx
+	      || !DECL_LOCAL_DECL_P (decl)))
 	DECL_TEMPLATE_INFO (decl) = info;
     }
 
@@ -13701,14 +13705,20 @@ static tree
 tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
 		      tree lambda_fntype)
 {
-  tree gen_tmpl, argvec;
+  tree gen_tmpl = NULL_TREE, argvec = NULL_TREE;
   hashval_t hash = 0;
   tree in_decl = t;
 
   /* Nobody should be tsubst'ing into non-template functions.  */
-  gcc_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE);
+  gcc_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE
+	      || DECL_LOCAL_DECL_P (t));
 
-  if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL)
+  if (DECL_LOCAL_DECL_P (t))
+    {
+      if (tree spec = retrieve_local_specialization (t))
+	return spec;
+    }
+  else if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL)
     {
       /* If T is not dependent, just return it.  */
       if (!uses_template_parms (DECL_TI_ARGS (t))
@@ -13958,6 +13968,11 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
 	  && !uses_template_parms (argvec))
 	tsubst_default_arguments (r, complain);
     }
+  else if (DECL_LOCAL_DECL_P (r))
+    {
+      if (!cp_unevaluated_operand)
+	register_local_specialization (r, t);
+    }
   else
     DECL_TEMPLATE_INFO (r) = NULL_TREE;
 
@@ -14503,11 +14518,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
       {
 	tree argvec = NULL_TREE;
 	tree gen_tmpl = NULL_TREE;
-	tree spec;
 	tree tmpl = NULL_TREE;
-	tree ctx;
 	tree type = NULL_TREE;
-	bool local_p;
 
 	if (TREE_TYPE (t) == error_mark_node)
 	  RETURN (error_mark_node);
@@ -14529,19 +14541,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 
 	/* Check to see if we already have the specialization we
 	   need.  */
-	spec = NULL_TREE;
-	if (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t))
+	tree spec = NULL_TREE;
+	bool local_p = false;
+	tree ctx = DECL_CONTEXT (t);
+	if (!(VAR_P (t) && DECL_LOCAL_DECL_P (t))
+	    && (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t)))
 	  {
-	    /* T is a static data member or namespace-scope entity.
-	       We have to substitute into namespace-scope variables
-	       (not just variable templates) because of cases like:
-
-	         template <class T> void f() { extern T t; }
-
-	       where the entity referenced is not known until
-	       instantiation time.  */
 	    local_p = false;
-	    ctx = DECL_CONTEXT (t);
 	    if (DECL_CLASS_SCOPE_P (t))
 	      {
 		ctx = tsubst_aggr_type (ctx, args,
@@ -14581,10 +14587,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	  }
 	else
 	  {
+	    if (!(VAR_P (t) && DECL_LOCAL_DECL_P (t)))
+	      /* Subsequent calls to pushdecl will fill this in.  */
+	      ctx = NULL_TREE;
 	    /* A local variable.  */
 	    local_p = true;
-	    /* Subsequent calls to pushdecl will fill this in.  */
-	    ctx = NULL_TREE;
 	    /* Unless this is a reference to a static variable from an
 	       enclosing function, in which case we need to fill it in now.  */
 	    if (TREE_STATIC (t))

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: c++: local externs in templates do not get template head
  2020-09-14 16:45 c++: local externs in templates do not get template head Nathan Sidwell
@ 2020-09-14 16:49 ` Marek Polacek
  2020-09-14 16:53   ` Nathan Sidwell
  2020-09-14 22:47 ` Tobias Burnus
  1 sibling, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2020-09-14 16:49 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On Mon, Sep 14, 2020 at 12:45:33PM -0400, Nathan Sidwell wrote:
> Now we consistently mark local externs with DECL_LOCAL_DECL_P, we can
> teach the template machinery not to give them a TEMPLATE_DECL head,
> and the instantiation machinery treat them as the local specialiations
> they are.  (openmp UDRs also fall into this category, and are dealt
> with similarly.)
> 
>         gcc/cp/
>         * pt.c (push_template_decl_real): Don't attach a template head to
>         local externs.
>         (tsubst_function_decl): Add support for headless local extern
>         decls.
>         (tsubst_decl): Add support for headless local extern decls.
> 
> pushed to trunk
> -- 
> Nathan Sidwell

> diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c
> index 0f52a9ed77d..8124efcbe24 100644
> --- i/gcc/cp/pt.c
> +++ w/gcc/cp/pt.c
> @@ -6071,7 +6071,11 @@ push_template_decl_real (tree decl, bool is_friend)
>      {
>        if (is_primary)
>  	retrofit_lang_decl (decl);
> -      if (DECL_LANG_SPECIFIC (decl))
> +      if (DECL_LANG_SPECIFIC (decl)
> +	  && ((TREE_CODE (decl) != VAR_DECL
> +	       && TREE_CODE (decl) != FUNCTION_DECL)

This is !VAR_OR_FUNCTION_DECL_P.  Want me to "fix" that as obvious?

Marek


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: c++: local externs in templates do not get template head
  2020-09-14 16:49 ` Marek Polacek
@ 2020-09-14 16:53   ` Nathan Sidwell
  2020-09-14 19:04     ` Marek Polacek
  0 siblings, 1 reply; 6+ messages in thread
From: Nathan Sidwell @ 2020-09-14 16:53 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On 9/14/20 12:49 PM, Marek Polacek wrote:
> On Mon, Sep 14, 2020 at 12:45:33PM -0400, Nathan Sidwell wrote:
>> Now we consistently mark local externs with DECL_LOCAL_DECL_P, we can
>> teach the template machinery not to give them a TEMPLATE_DECL head,
>> and the instantiation machinery treat them as the local specialiations
>> they are.  (openmp UDRs also fall into this category, and are dealt
>> with similarly.)
>>
>>          gcc/cp/
>>          * pt.c (push_template_decl_real): Don't attach a template head to
>>          local externs.
>>          (tsubst_function_decl): Add support for headless local extern
>>          decls.
>>          (tsubst_decl): Add support for headless local extern decls.
>>
>> pushed to trunk
>> -- 
>> Nathan Sidwell
> 
>> diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c
>> index 0f52a9ed77d..8124efcbe24 100644
>> --- i/gcc/cp/pt.c
>> +++ w/gcc/cp/pt.c
>> @@ -6071,7 +6071,11 @@ push_template_decl_real (tree decl, bool is_friend)
>>       {
>>         if (is_primary)
>>   	retrofit_lang_decl (decl);
>> -      if (DECL_LANG_SPECIFIC (decl))
>> +      if (DECL_LANG_SPECIFIC (decl)
>> +	  && ((TREE_CODE (decl) != VAR_DECL
>> +	       && TREE_CODE (decl) != FUNCTION_DECL)
> 
> This is !VAR_OR_FUNCTION_DECL_P.  Want me to "fix" that as obvious?

ah, thanks -- great.  I knew of VAR_P and the lack of FUNCTION_P, but 
not that one.  (bah, who needs consistency!)


-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: c++: local externs in templates do not get template head
  2020-09-14 16:53   ` Nathan Sidwell
@ 2020-09-14 19:04     ` Marek Polacek
  0 siblings, 0 replies; 6+ messages in thread
From: Marek Polacek @ 2020-09-14 19:04 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On Mon, Sep 14, 2020 at 12:53:18PM -0400, Nathan Sidwell wrote:
> On 9/14/20 12:49 PM, Marek Polacek wrote:
> > On Mon, Sep 14, 2020 at 12:45:33PM -0400, Nathan Sidwell wrote:
> > > Now we consistently mark local externs with DECL_LOCAL_DECL_P, we can
> > > teach the template machinery not to give them a TEMPLATE_DECL head,
> > > and the instantiation machinery treat them as the local specialiations
> > > they are.  (openmp UDRs also fall into this category, and are dealt
> > > with similarly.)
> > > 
> > >          gcc/cp/
> > >          * pt.c (push_template_decl_real): Don't attach a template head to
> > >          local externs.
> > >          (tsubst_function_decl): Add support for headless local extern
> > >          decls.
> > >          (tsubst_decl): Add support for headless local extern decls.
> > > 
> > > pushed to trunk
> > > -- 
> > > Nathan Sidwell
> > 
> > > diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c
> > > index 0f52a9ed77d..8124efcbe24 100644
> > > --- i/gcc/cp/pt.c
> > > +++ w/gcc/cp/pt.c
> > > @@ -6071,7 +6071,11 @@ push_template_decl_real (tree decl, bool is_friend)
> > >       {
> > >         if (is_primary)
> > >   	retrofit_lang_decl (decl);
> > > -      if (DECL_LANG_SPECIFIC (decl))
> > > +      if (DECL_LANG_SPECIFIC (decl)
> > > +	  && ((TREE_CODE (decl) != VAR_DECL
> > > +	       && TREE_CODE (decl) != FUNCTION_DECL)
> > 
> > This is !VAR_OR_FUNCTION_DECL_P.  Want me to "fix" that as obvious?
> 
> ah, thanks -- great.  I knew of VAR_P and the lack of FUNCTION_P, but not
> that one.  (bah, who needs consistency!)

Yup...  I keep wishing we had ARRAY_TYPE_P, for example.

Anyway, I just pushed this:

gcc/cp/ChangeLog:

	* pt.c (push_template_decl_real): Use VAR_OR_FUNCTION_DECL_P.
---
 gcc/cp/pt.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8124efcbe24..c630ef5a070 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6072,8 +6072,7 @@ push_template_decl_real (tree decl, bool is_friend)
       if (is_primary)
 	retrofit_lang_decl (decl);
       if (DECL_LANG_SPECIFIC (decl)
-	  && ((TREE_CODE (decl) != VAR_DECL
-	       && TREE_CODE (decl) != FUNCTION_DECL)
+	  && (!VAR_OR_FUNCTION_DECL_P (decl)
 	      || !ctx
 	      || !DECL_LOCAL_DECL_P (decl)))
 	DECL_TEMPLATE_INFO (decl) = info;

base-commit: 5bcc0fa05ef713594f6c6d55d5c837e13a9c9803
-- 
2.26.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: c++: local externs in templates do not get template head
  2020-09-14 16:45 c++: local externs in templates do not get template head Nathan Sidwell
  2020-09-14 16:49 ` Marek Polacek
@ 2020-09-14 22:47 ` Tobias Burnus
  2020-09-15 15:00   ` Nathan Sidwell
  1 sibling, 1 reply; 6+ messages in thread
From: Tobias Burnus @ 2020-09-14 22:47 UTC (permalink / raw)
  To: Nathan Sidwell, GCC Patches; +Cc: Jakub Jelinek

This patch cause run-time fails for
   g++ -fopenmp libgomp/testsuite/libgomp.c++/udr-13.C

The follow-up fix does not help.

Namely, in udr-3.C:115:

115             if (t.s != 11 || v.v != 9 || q != 0 || d != 3.0) abort ();
(gdb) p t.s
$1 = 11
(gdb) p v.v
$2 = 4
(gdb) p q
$3 = 0
(gdb) p d
$4 = 3

Could you check?

Thanks,

Tobias

On 9/14/20 6:45 PM, Nathan Sidwell wrote:

> Now we consistently mark local externs with DECL_LOCAL_DECL_P, we can
> teach the template machinery not to give them a TEMPLATE_DECL head,
> and the instantiation machinery treat them as the local specialiations
> they are.  (openmp UDRs also fall into this category, and are dealt
> with similarly.)
>
>         gcc/cp/
>         * pt.c (push_template_decl_real): Don't attach a template head to
>         local externs.
>         (tsubst_function_decl): Add support for headless local extern
>         decls.
>         (tsubst_decl): Add support for headless local extern decls.
>
> pushed to trunk
-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: c++: local externs in templates do not get template head
  2020-09-14 22:47 ` Tobias Burnus
@ 2020-09-15 15:00   ` Nathan Sidwell
  0 siblings, 0 replies; 6+ messages in thread
From: Nathan Sidwell @ 2020-09-15 15:00 UTC (permalink / raw)
  To: Tobias Burnus, GCC Patches; +Cc: Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 814 bytes --]

On 9/14/20 6:47 PM, Tobias Burnus wrote:
> This patch cause run-time fails for
>    g++ -fopenmp libgomp/testsuite/libgomp.c++/udr-13.C
> 
> The follow-up fix does not help.
> 
> Namely, in udr-3.C:115:
> 
> 115             if (t.s != 11 || v.v != 9 || q != 0 || d != 3.0) abort ();
> (gdb) p t.s

oops, I forgot the runtime tests are there -- it was so long ago!  This 
unbreaks it, while I go develop a more robust patch.

Turns out I didn't get OMP reductions correct.  To address those I
need to do some reorganization, so this patch just reverts the
OMP-specific pieces of the local decl changes.

         gcc/cp/
         * pt.c (push_template_decl_real): OMP reductions retain a template
         header.
         (tsubst_function_decl): Likewise.

pushed to trunk

nathan

-- 
Nathan Sidwell

[-- Attachment #2: omp.diff --]
[-- Type: text/x-patch, Size: 1384 bytes --]

diff --git c/gcc/cp/pt.c w/gcc/cp/pt.c
index c630ef5a070..1aea105edd5 100644
--- c/gcc/cp/pt.c
+++ w/gcc/cp/pt.c
@@ -6072,9 +6072,11 @@ push_template_decl_real (tree decl, bool is_friend)
       if (is_primary)
 	retrofit_lang_decl (decl);
       if (DECL_LANG_SPECIFIC (decl)
-	  && (!VAR_OR_FUNCTION_DECL_P (decl)
-	      || !ctx
-	      || !DECL_LOCAL_DECL_P (decl)))
+	  && !(VAR_OR_FUNCTION_DECL_P (decl)
+	       && DECL_LOCAL_DECL_P (decl)
+	       /* OMP reductions still need a template header.  */
+	       && !(TREE_CODE (decl) == FUNCTION_DECL
+		    && DECL_OMP_DECLARE_REDUCTION_P (decl))))
 	DECL_TEMPLATE_INFO (decl) = info;
     }
 
@@ -13712,7 +13714,8 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
   gcc_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE
 	      || DECL_LOCAL_DECL_P (t));
 
-  if (DECL_LOCAL_DECL_P (t))
+  if (DECL_LOCAL_DECL_P (t)
+      && !DECL_OMP_DECLARE_REDUCTION_P (t))
     {
       if (tree spec = retrieve_local_specialization (t))
 	return spec;
@@ -13967,7 +13970,8 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
 	  && !uses_template_parms (argvec))
 	tsubst_default_arguments (r, complain);
     }
-  else if (DECL_LOCAL_DECL_P (r))
+  else if (DECL_LOCAL_DECL_P (r)
+	   && !DECL_OMP_DECLARE_REDUCTION_P (r))
     {
       if (!cp_unevaluated_operand)
 	register_local_specialization (r, t);

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-09-15 15:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-14 16:45 c++: local externs in templates do not get template head Nathan Sidwell
2020-09-14 16:49 ` Marek Polacek
2020-09-14 16:53   ` Nathan Sidwell
2020-09-14 19:04     ` Marek Polacek
2020-09-14 22:47 ` Tobias Burnus
2020-09-15 15:00   ` Nathan Sidwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).