public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-1698] c++: unsynthesized defaulted constexpr fn [PR110122]
@ 2023-06-11 15:27 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2023-06-11 15:27 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:59946a4c0c97c842ac5a34de5b1aadb73b738809

commit r14-1698-g59946a4c0c97c842ac5a34de5b1aadb73b738809
Author: Patrick Palka <ppalka@redhat.com>
Date:   Sun Jun 11 11:27:10 2023 -0400

    c++: unsynthesized defaulted constexpr fn [PR110122]
    
    In this other testcase from PR110122, during regeneration of the generic
    lambda with V=Bar{}, substitution followed by coerce_template_parms for
    A<V>'s template argument naturally yields a copy of V in terms of Bar's
    (implicitly) defaulted copy constructor.
    
    This however happens inside a template context so although we introduced
    a use of the copy constructor, mark_used didn't actually synthesize it,
    which causes subsequent constant evaluation of the template argument to
    fail with:
    
      nontype-class59.C: In instantiation of ‘void f() [with Bar V = Bar{Foo()}]’:
      nontype-class59.C:22:11:   required from here
      nontype-class59.C:18:18: error: ‘constexpr Bar::Bar(const Bar&)’ used before its definition
    
    We already make sure to instantiate templated constexpr functions needed
    for constant evaluation (as per P0859R0).  So this patch fixes this by
    making us synthesize defaulted constexpr functions needed for constant
    evaluation as well.
    
            PR c++/110122
    
    gcc/cp/ChangeLog:
    
            * constexpr.cc (cxx_eval_call_expression): Synthesize defaulted
            functions needed for constant evaluation.
            (instantiate_cx_fn_r): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/nontype-class59.C: New test.

Diff:
---
 gcc/cp/constexpr.cc                          | 14 ++++++++++----
 gcc/testsuite/g++.dg/cpp2a/nontype-class59.C | 23 +++++++++++++++++++++++
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 8f7f0b7d325..9122a5efa65 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -2897,7 +2897,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 
   /* We can't defer instantiating the function any longer.  */
   if (!DECL_INITIAL (fun)
-      && DECL_TEMPLOID_INSTANTIATION (fun)
+      && (DECL_TEMPLOID_INSTANTIATION (fun) || DECL_DEFAULTED_FN (fun))
       && !uid_sensitive_constexpr_evaluation_p ())
     {
       location_t save_loc = input_location;
@@ -2905,7 +2905,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
       ++function_depth;
       if (ctx->manifestly_const_eval == mce_true)
 	FNDECL_MANIFESTLY_CONST_EVALUATED (fun) = true;
-      instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
+      if (DECL_TEMPLOID_INSTANTIATION (fun))
+	instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
+      else
+	synthesize_method (fun);
       --function_depth;
       input_location = save_loc;
     }
@@ -8110,11 +8113,14 @@ instantiate_cx_fn_r (tree *tp, int *walk_subtrees, void */*data*/)
       && DECL_DECLARED_CONSTEXPR_P (*tp)
       && !DECL_INITIAL (*tp)
       && !trivial_fn_p (*tp)
-      && DECL_TEMPLOID_INSTANTIATION (*tp)
+      && (DECL_TEMPLOID_INSTANTIATION (*tp) || DECL_DEFAULTED_FN (*tp))
       && !uid_sensitive_constexpr_evaluation_p ())
     {
       ++function_depth;
-      instantiate_decl (*tp, /*defer_ok*/false, /*expl_inst*/false);
+      if (DECL_TEMPLOID_INSTANTIATION (*tp))
+	instantiate_decl (*tp, /*defer_ok*/false, /*expl_inst*/false);
+      else
+	synthesize_method (*tp);
       --function_depth;
     }
   else if (TREE_CODE (*tp) == CALL_EXPR
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class59.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class59.C
new file mode 100644
index 00000000000..6e40698da2f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class59.C
@@ -0,0 +1,23 @@
+// PR c++/110122
+// { dg-do compile { target c++20 } }
+
+struct Foo {
+  Foo() = default;
+  constexpr Foo(const Foo&) { }
+};
+
+struct Bar {
+  Foo _;
+};
+
+template<Bar V>
+struct A { };
+
+template<Bar V>
+void f() {
+  [](auto){ A<V> d; }(0); // { dg-bogus "used before its definition" }
+};
+
+int main() {
+  f<Bar{}>();
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-11 15:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-11 15:27 [gcc r14-1698] c++: unsynthesized defaulted constexpr fn [PR110122] Patrick Palka

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