[pushed] c++: Fix deferred noexcept on constructor [PR93901].

2020-05-14 Thread Jason Merrill via Gcc-patches
My change in r10-4394 to only update clones when we actually instantiate a
deferred noexcept-spec broke this because deferred parsing updates the
primary function but not the clones.  For GCC 10 I just reverted that
change; this patch adjusts maybe_instantiate_noexcept to update only the
clone passed as the argument.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog
2020-05-14  Jason Merrill  

PR c++/93901
* pt.c (maybe_instantiate_noexcept): Change clone handling.
---
 gcc/cp/pt.c | 55 ++---
 1 file changed, 27 insertions(+), 28 deletions(-)

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 61e6fa7484d..2a0b18f5517 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -25174,7 +25174,7 @@ always_instantiate_p (tree decl)
 bool
 maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
 {
-  tree fntype, spec, noex, clone;
+  tree fntype, spec, noex;
 
   /* Don't instantiate a noexcept-specification from template context.  */
   if (processing_template_decl
@@ -25193,8 +25193,16 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t 
complain)
   return !DECL_MAYBE_DELETED (fn);
 }
 
-  if (DECL_CLONED_FUNCTION_P (fn))
-fn = DECL_CLONED_FUNCTION (fn);
+  fntype = TREE_TYPE (fn);
+  spec = TYPE_RAISES_EXCEPTIONS (fntype);
+
+  if (!spec || !TREE_PURPOSE (spec))
+return true;
+
+  noex = TREE_PURPOSE (spec);
+  if (TREE_CODE (noex) != DEFERRED_NOEXCEPT
+  && TREE_CODE (noex) != DEFERRED_PARSE)
+return true;
 
   tree orig_fn = NULL_TREE;
   /* For a member friend template we can get a TEMPLATE_DECL.  Let's use
@@ -25206,15 +25214,14 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t 
complain)
   fn = DECL_TEMPLATE_RESULT (fn);
 }
 
-  fntype = TREE_TYPE (fn);
-  spec = TYPE_RAISES_EXCEPTIONS (fntype);
-
-  if (!spec || !TREE_PURPOSE (spec))
-return true;
-
-  noex = TREE_PURPOSE (spec);
-
-  if (TREE_CODE (noex) == DEFERRED_NOEXCEPT)
+  if (DECL_CLONED_FUNCTION_P (fn))
+{
+  tree prime = DECL_CLONED_FUNCTION (fn);
+  if (!maybe_instantiate_noexcept (prime, complain))
+   return false;
+  spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (prime));
+}
+  else if (TREE_CODE (noex) == DEFERRED_NOEXCEPT)
 {
   static hash_set* fns = new hash_set;
   bool added = false;
@@ -25284,27 +25291,19 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t 
complain)
 
   if (added)
fns->remove (fn);
-
-  if (spec == error_mark_node)
-   {
- /* This failed with a hard error, so let's go with false.  */
- gcc_assert (seen_error ());
- spec = noexcept_false_spec;
-   }
-
-  TREE_TYPE (fn) = build_exception_variant (fntype, spec);
-  if (orig_fn)
-   TREE_TYPE (orig_fn) = TREE_TYPE (fn);
 }
 
-  FOR_EACH_CLONE (clone, fn)
+  if (spec == error_mark_node)
 {
-  if (TREE_TYPE (clone) == fntype)
-   TREE_TYPE (clone) = TREE_TYPE (fn);
-  else
-   TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
+  /* This failed with a hard error, so let's go with false.  */
+  gcc_assert (seen_error ());
+  spec = noexcept_false_spec;
 }
 
+  TREE_TYPE (fn) = build_exception_variant (fntype, spec);
+  if (orig_fn)
+TREE_TYPE (orig_fn) = TREE_TYPE (fn);
+
   return true;
 }
 

base-commit: 3a36428b5fbc825e2d3455f5770b5d6e71c63413
-- 
2.18.1



[pushed] c++: Fix deferred noexcept on constructor [PR93901].

2020-03-10 Thread Jason Merrill via Gcc-patches
My change in r10-4394 to only update clones when we actually instantiate a
deferred noexcept-spec broke this because deferred parsing updates the
primary function but not the clones.  For GCC 10, let's just revert it.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog
2020-03-10  Jason Merrill  

PR c++/93901
* pt.c (maybe_instantiate_noexcept): Always update clones.
---
 gcc/cp/pt.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 179716b5680..cb237ba0d9d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -25097,14 +25097,14 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t 
complain)
   TREE_TYPE (fn) = build_exception_variant (fntype, spec);
   if (orig_fn)
TREE_TYPE (orig_fn) = TREE_TYPE (fn);
+}
 
-  FOR_EACH_CLONE (clone, fn)
-   {
- if (TREE_TYPE (clone) == fntype)
-   TREE_TYPE (clone) = TREE_TYPE (fn);
- else
-   TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), 
spec);
-   }
+  FOR_EACH_CLONE (clone, fn)
+{
+  if (TREE_TYPE (clone) == fntype)
+   TREE_TYPE (clone) = TREE_TYPE (fn);
+  else
+   TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
 }
 
   return true;

base-commit: b269a014771776f860730874095dffb34839a466
-- 
2.18.1