This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] [PR86397] set p_t_decl while canonicalizing eh specs for mangling
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: jason at redhat dot com, nathan at acm dot org
- Date: Thu, 22 Nov 2018 21:40:04 -0200
- Subject: [PATCH] [PR86397] set p_t_decl while canonicalizing eh specs for mangling
Mangling visits the base template function type, prior to template
resolution, and on such types, exception specifications may contain
unresolved noexcept expressions. nothrow_spec_p is called on them
even whe exception specifications are not part of function types, and
it rejects unresolved noexcept expressions if processing_template_decl
is not set.
Setting processing_template_decl while mangling what is indeed the
(generic) type of a function template would solve this problem, but it
would cause others: no_linkage_check, for example, returns early if
processing_template_decl, and this regresses g++.dg/pr79091.C and
g++.dg/abi/no-linkage-expr1.C.
So, instead of setting processing_template_decl throughout, I'm
introducing another flag, processing_template_function_signature, and
using it to set processing_template_decl only while canonicalizing the
exception spec, which is where nothrow_spec_p gets called.
Regstrapped on i686- and x86_64-linux-gnu. Ok to install?
for gcc/cp/ChangeLog
PR c++/86397
* mangle.c (processing_template_function_signature): New var.
(write_encoding): Set it while mangling generic template type.
(canonicalize_for_substitution): Set processing_template_decl
while handling exception specs if
processing_template_function_signature.
for gcc/testsuite/ChangeLog
PR c++/86397
* g++.dg/cpp0x/pr86397-1.C: New.
* g++.dg/cpp0x/pr86397-2.C: New.
---
gcc/cp/mangle.c | 19 +++++++++++++++++++
gcc/testsuite/g++.dg/cpp0x/pr86397-1.C | 4 ++++
gcc/testsuite/g++.dg/cpp0x/pr86397-2.C | 4 ++++
3 files changed, 27 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr86397-1.C
create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr86397-2.C
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 64415894bc57..a499ef97b3c6 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -170,6 +170,17 @@ integer_type_codes[itk_none] =
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};
+/* Exception specifications may carry unresolved noexcept expressions
+ before template substitution, but nothrow_spec_p will fail an
+ assert check if it comes across such a spec while
+ !processing_template_decl. So, when we start processing the
+ signature of a template function, that may contain a such
+ unresolved expressions, we set this variable. Then, as we process
+ the exception spec, we set processing_template_decl. We don't want
+ to set processing_template_decl throughout, becuase this affects
+ other relevant tests, such as no_linkage_check. */
+static int processing_template_function_signature;
+
static int decl_is_template_id (const tree, tree* const);
/* Functions for handling substitutions. */
@@ -418,7 +429,11 @@ canonicalize_for_substitution (tree node)
|| TREE_CODE (node) == METHOD_TYPE)
{
node = build_ref_qualified_type (node, type_memfn_rqual (orig));
+ if (processing_template_function_signature)
+ processing_template_decl++;
tree r = canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (orig));
+ if (processing_template_function_signature)
+ processing_template_decl--;
if (flag_noexcept_type)
node = build_exception_variant (node, r);
else
@@ -836,6 +851,7 @@ write_encoding (const tree decl)
write_bare_function_type -- otherwise, it will get
confused about which artificial parameters to skip. */
d = NULL_TREE;
+ ++processing_template_function_signature;
}
else
{
@@ -846,6 +862,9 @@ write_encoding (const tree decl)
write_bare_function_type (fn_type,
mangle_return_type_p (decl),
d);
+
+ if (tmpl)
+ --processing_template_function_signature;
}
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr86397-1.C b/gcc/testsuite/g++.dg/cpp0x/pr86397-1.C
new file mode 100644
index 000000000000..4f9f5fa7e4c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr86397-1.C
@@ -0,0 +1,4 @@
+// { dg-do compile { target c++11 } }
+void e();
+template <bool> void f(int() noexcept(e)) {}
+template void f<false>(int()); // { dg-error "does not match" "" { target c++17 } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr86397-2.C b/gcc/testsuite/g++.dg/cpp0x/pr86397-2.C
new file mode 100644
index 000000000000..fb43499526e8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr86397-2.C
@@ -0,0 +1,4 @@
+// { dg-do compile { target c++11 } }
+void e();
+template <bool> void f(int() noexcept(e)) {}
+template void f<false>(int() noexcept);
--
Alexandre Oliva, freedom fighter https://FSFLA.org/blogs/lxo
Be the change, be Free! FSF Latin America board member
GNU Toolchain Engineer Free Software Evangelist
Hay que enGNUrecerse, pero sin perder la terGNUra jamás-GNUChe