Re: c++: local externs in templates do not get template head

2020-09-15 Thread Nathan Sidwell

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
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);


Re: c++: local externs in templates do not get template head

2020-09-14 Thread Tobias Burnus

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


Re: c++: local externs in templates do not get template head

2020-09-14 Thread Marek Polacek via 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



Re: c++: local externs in templates do not get template head

2020-09-14 Thread Nathan Sidwell

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


Re: c++: local externs in templates do not get template head

2020-09-14 Thread Marek Polacek via 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



c++: local externs in templates do not get template head

2020-09-14 Thread Nathan Sidwell

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)
+	  || !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  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))