This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]