[gcc r9-9264] c++: C++17 and decltype of multi-operator expression [PR95675]

Jason Merrill jason@gcc.gnu.org
Thu Mar 4 05:13:45 GMT 2021


https://gcc.gnu.org/g:e90b052caf74dcc7529e6b2cc0b0688eebf53c74

commit r9-9264-ge90b052caf74dcc7529e6b2cc0b0688eebf53c74
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Mar 2 23:59:00 2021 -0500

    c++: C++17 and decltype of multi-operator expression [PR95675]
    
    A call that is the immediate operand of decltype has special semantics: no
    temporary is produced, so it's OK for the return type to be e.g. incomplete.
    But we were treating (e | f) the same way, which confused overload
    resolution when we then tried to evaluate ... | g.
    
    Fixed by making build_temp do what its name says, and force the C++17
    temporary materialization conversion.
    
    gcc/cp/ChangeLog:
    
            PR c++/95675
            * call.c (build_temp): Wrap a CALL_EXPR in a TARGET_EXPR
            if it didn't get one before.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/95675
            * g++.dg/cpp0x/decltype-call5.C: New test.
            * g++.dg/cpp0x/decltype-call6.C: New test.

Diff:
---
 gcc/cp/call.c                               |  8 ++++++++
 gcc/testsuite/g++.dg/cpp0x/decltype-call5.C |  7 +++++++
 gcc/testsuite/g++.dg/cpp0x/decltype-call6.C | 12 ++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index b8b4ae676fa..7191a4945b1 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6836,6 +6836,14 @@ build_temp (tree expr, tree type, int flags,
       && !type_has_nontrivial_copy_init (TREE_TYPE (expr)))
     return get_target_expr_sfinae (expr, complain);
 
+  /* In decltype, we might have decided not to wrap this call in a TARGET_EXPR.
+     But it turns out to be a subexpression, so perform temporary
+     materialization now.  */
+  if (TREE_CODE (expr) == CALL_EXPR
+      && CLASS_TYPE_P (type)
+      && same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (expr)))
+    expr = build_cplus_new (type, expr, complain);
+
   savew = warningcount + werrorcount, savee = errorcount;
   args = make_tree_vector_single (expr);
   expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-call5.C b/gcc/testsuite/g++.dg/cpp0x/decltype-call5.C
new file mode 100644
index 00000000000..81ef6e6f9c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype-call5.C
@@ -0,0 +1,7 @@
+// PR c++/95675
+// { dg-do compile { target c++11 } }
+
+struct b {};
+b operator|(b, b) { return {}; }
+b e, f, g;
+using h = decltype(e | f | g);
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-call6.C b/gcc/testsuite/g++.dg/cpp0x/decltype-call6.C
new file mode 100644
index 00000000000..4173b607689
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype-call6.C
@@ -0,0 +1,12 @@
+// PR c++/95675
+// { dg-do compile { target c++11 } }
+
+struct a {};
+template <typename> struct b;
+template <typename bq, typename br> struct b<bq(br)> {
+  decltype(bq()(br())) c;
+};
+struct e {
+  operator a();
+};
+b<e (*(e))(a)> d;


More information about the Gcc-cvs mailing list