public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-modules] Local extern fns do not get template header
@ 2020-09-14 12:54 Nathan Sidwell
0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2020-09-14 12:54 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:33be02f91858a4a2a5effdc1ee9c0e4506bc0be2
commit 33be02f91858a4a2a5effdc1ee9c0e4506bc0be2
Author: Nathan Sidwell <nathan@acm.org>
Date: Fri Sep 11 08:50:16 2020 -0700
Local extern fns do not get template header
gcc/cp/
* module.cc (trees_out::chained_decls): Also mark local fns for
by-value walking.
(trees_out::decl_node): Assert we don't meet a local var or fn.
(trees_out::get_merge_kind): Local fns are also unique.
* pt.c (push_template_decl_real): Local fns also lack a header.
(tsubst_function_decl): Cope with local fns.
(tsubst_decl): Adjust VAR_DECL tsubsting.
gcc/testsuite/
* g++.dg/modules/tpl-extern-{var,fn}-1_{a.H,b.C}: New.
Diff:
---
ChangeLog.modules | 14 +++++++
gcc/cp/module.cc | 14 ++++++-
gcc/cp/pt.c | 50 ++++++++++++-----------
gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_a.H | 16 ++++++++
gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_b.C | 8 ++++
gcc/testsuite/g++.dg/modules/tpl-extern-var-1_a.H | 19 +++++++++
gcc/testsuite/g++.dg/modules/tpl-extern-var-1_b.C | 8 ++++
7 files changed, 103 insertions(+), 26 deletions(-)
diff --git a/ChangeLog.modules b/ChangeLog.modules
index a96a88c9747..9801ec197a9 100644
--- a/ChangeLog.modules
+++ b/ChangeLog.modules
@@ -1,3 +1,17 @@
+2020-09-11 Nathan Sidwell <nathan@acm.org>
+
+ Local extern fns do not get template header
+ gcc/cp/
+ * module.cc (trees_out::chained_decls): Also mark local fns for
+ by-value walking.
+ (trees_out::decl_node): Assert we don't meet a local var or fn.
+ (trees_out::get_merge_kind): Local fns are also unique.
+ * pt.c (push_template_decl_real): Local fns also lack a header.
+ (tsubst_function_decl): Cope with local fns.
+ (tsubst_decl): Adjust VAR_DECL tsubsting.
+ gcc/testsuite/
+ * g++.dg/modules/tpl-extern-{var,fn}-1_{a.H,b.C}: New.
+
2020-09-09 Nathan Sidwell <nathan@acm.org>
Local extern vars do not get template header
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index cb8db32de51..af13b45b0c7 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -4853,7 +4853,9 @@ trees_out::chained_decls (tree decls)
{
for (; decls; decls = DECL_CHAIN (decls))
{
- if (TREE_CODE (decls) == VAR_DECL && DECL_LOCAL_DECL_P (decls))
+ if ((TREE_CODE (decls) == VAR_DECL
+ || TREE_CODE (decls) == FUNCTION_DECL)
+ && DECL_LOCAL_DECL_P (decls))
{
/* Make sure this is the first encounter, and mark for
walk-by-value. */
@@ -8087,6 +8089,10 @@ trees_out::decl_node (tree decl, walk_kind ref)
default:
break;
+ case FUNCTION_DECL:
+ gcc_checking_assert (!DECL_LOCAL_DECL_P (decl));
+ break;
+
case RESULT_DECL:
// FIXME: Like a parm?
return true;
@@ -8185,6 +8191,7 @@ trees_out::decl_node (tree decl, walk_kind ref)
break;
case VAR_DECL:
+ gcc_checking_assert (!DECL_LOCAL_DECL_P (decl));
if (DECL_VTABLE_OR_VTT_P (decl))
{
/* VTT or VTABLE, they are all on the vtables list. */
@@ -9853,7 +9860,8 @@ trees_out::get_merge_kind (tree decl, depset *dep)
{
if (!dep)
{
- if (TREE_CODE (decl) == VAR_DECL
+ if ((TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == FUNCTION_DECL)
&& DECL_LOCAL_DECL_P (decl))
return MK_unique;
@@ -12517,6 +12525,8 @@ specialization_add (bool decl_p, spec_entry *entry, void *data_)
gcc_checking_assert (!check_mergeable_specialization (true, entry)
== (decl_p || !DECL_ALIAS_TEMPLATE_P (entry->tmpl)));
}
+ else if (VAR_P (entry->spec) || TREE_CODE (entry->spec) == FUNCTION_DECL)
+ gcc_checking_assert (!DECL_LOCAL_DECL_P (entry->spec));
data->safe_push (entry);
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bba24421f2d..484f697dc3d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6095,8 +6095,10 @@ 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
- || !ctx || !DECL_LOCAL_DECL_P (decl)))
+ && ((TREE_CODE (decl) != VAR_DECL
+ && TREE_CODE (decl) != FUNCTION_DECL)
+ || !ctx
+ || !DECL_LOCAL_DECL_P (decl)))
DECL_TEMPLATE_INFO (decl) = info;
}
@@ -13750,14 +13752,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))
@@ -14008,6 +14016,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;
@@ -14574,11 +14587,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);
@@ -14600,19 +14610,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,
@@ -14633,8 +14637,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
&& DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
spec = t;
}
- else if (!DECL_TEMPLATE_INFO (t))
- goto local;
if (!spec)
{
@@ -14654,9 +14656,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
}
else
{
- /* Subsequent calls to pushdecl will fill this in. */
- ctx = NULL_TREE;
- local:
+ 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;
/* Unless this is a reference to a static variable from an
diff --git a/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_a.H b/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_a.H
new file mode 100644
index 00000000000..f0aba549dfd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_a.H
@@ -0,0 +1,16 @@
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+template<typename T>
+inline void Foo ()
+{
+ {
+ void Frob ();
+ }
+ {
+ void Frob ();
+ }
+ {
+ void Frob ();
+ }
+}
diff --git a/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_b.C b/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_b.C
new file mode 100644
index 00000000000..8b093d4e15a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-extern-fn-1_b.C
@@ -0,0 +1,8 @@
+// { dg-additional-options -fmodules-ts }
+
+import "tpl-extern-fn-1_a.H";
+
+int main ()
+{
+ Foo<int> ();
+}
diff --git a/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_a.H b/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_a.H
new file mode 100644
index 00000000000..4a6437a85e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_a.H
@@ -0,0 +1,19 @@
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+template<typename T>
+inline void Foo ()
+{
+ {
+ extern int EXTERN_;
+ EXTERN_++;
+ }
+ {
+ extern int EXTERN_;
+ EXTERN_++;
+ }
+ {
+ extern int EXTERN_;
+ EXTERN_++;
+ }
+}
diff --git a/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_b.C b/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_b.C
new file mode 100644
index 00000000000..222418128be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-extern-var-1_b.C
@@ -0,0 +1,8 @@
+// { dg-additional-options -fmodules-ts }
+
+import "tpl-extern-var-1_a.H";
+
+int main ()
+{
+ Foo<int> ();
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-09-14 12:54 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-14 12:54 [gcc/devel/c++-modules] Local extern fns do not get template header 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).