https://gcc.gnu.org/g:232d3a73e18d6886f0a5781048a78da293fbb014

commit r15-6973-g232d3a73e18d6886f0a5781048a78da293fbb014
Author: Patrick Palka <ppa...@redhat.com>
Date:   Thu Jan 16 16:05:46 2025 -0500

    c++: make finish_pseudo_destructor_expr SFINAE-aware [PR116417]
    
            PR c++/116417
    
    gcc/cp/ChangeLog:
    
            * cp-tree.h (finish_pseudo_destructor_expr): Add complain
            parameter.
            * parser.cc (cp_parser_postfix_dot_deref_expression): Pass
            complain=tf_warning_or_error to finish_pseudo_destructor_expr.
            * pt.cc (tsubst_expr): Pass complain to
            finish_pseudo_destructor_expr.
            * semantics.cc (finish_pseudo_destructor_expr): Check complain
            before emitting a diagnostic.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/template/pseudodtor7.C: New test.
    
    Reviewed-by: Marek Polacek <pola...@redhat.com>
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 gcc/cp/cp-tree.h                            |  2 +-
 gcc/cp/parser.cc                            |  3 ++-
 gcc/cp/pt.cc                                |  4 ++--
 gcc/cp/semantics.cc                         | 15 +++++++++------
 gcc/testsuite/g++.dg/template/pseudodtor7.C | 15 +++++++++++++++
 5 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 269aca5d4f40..e229fe02cbb0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7975,7 +7975,7 @@ extern tree lookup_and_finish_template_variable (tree, 
tree, tsubst_flags_t = tf
 extern tree finish_template_variable           (tree, tsubst_flags_t = 
tf_warning_or_error);
 extern cp_expr finish_increment_expr           (cp_expr, enum tree_code);
 extern tree finish_this_expr                   (void);
-extern tree finish_pseudo_destructor_expr       (tree, tree, tree, location_t);
+extern tree finish_pseudo_destructor_expr       (tree, tree, tree, location_t, 
tsubst_flags_t);
 extern cp_expr finish_unary_op_expr            (location_t, enum tree_code, 
cp_expr,
                                                 tsubst_flags_t);
 /* Whether this call to finish_compound_literal represents a C++11 functional
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index ba2c4dbb0538..c030a18689e0 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -8862,7 +8862,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
          pseudo_destructor_p = true;
          postfix_expression
            = finish_pseudo_destructor_expr (postfix_expression,
-                                            s, type, location);
+                                            s, type, location,
+                                            tf_warning_or_error);
        }
     }
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 961696f333ea..00b61aec24ea 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -21669,7 +21669,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
        tree op1 = RECUR (TREE_OPERAND (t, 1));
        tree op2 = tsubst (TREE_OPERAND (t, 2), args, complain, in_decl);
        RETURN (finish_pseudo_destructor_expr (op0, op1, op2,
-                                              input_location));
+                                              input_location, complain));
       }
 
     case TREE_LIST:
@@ -21733,7 +21733,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
                    dtor = TREE_OPERAND (dtor, 0);
                    if (TYPE_P (dtor))
                      RETURN (finish_pseudo_destructor_expr
-                             (object, s, dtor, input_location));
+                             (object, s, dtor, input_location, complain));
                  }
              }
          }
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 2daad2d27bea..e891319f9a99 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -3570,7 +3570,7 @@ finish_this_expr (void)
 
 tree
 finish_pseudo_destructor_expr (tree object, tree scope, tree destructor,
-                              location_t loc)
+                              location_t loc, tsubst_flags_t complain)
 {
   if (object == error_mark_node || destructor == error_mark_node)
     return error_mark_node;
@@ -3581,16 +3581,18 @@ finish_pseudo_destructor_expr (tree object, tree scope, 
tree destructor,
     {
       if (scope == error_mark_node)
        {
-         error_at (loc, "invalid qualifying scope in pseudo-destructor name");
+         if (complain & tf_error)
+           error_at (loc, "invalid qualifying scope in pseudo-destructor 
name");
          return error_mark_node;
        }
       if (is_auto (destructor))
        destructor = TREE_TYPE (object);
       if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor))
        {
-         error_at (loc,
-                   "qualified type %qT does not match destructor name ~%qT",
-                   scope, destructor);
+         if (complain & tf_error)
+           error_at (loc,
+                     "qualified type %qT does not match destructor name ~%qT",
+                     scope, destructor);
          return error_mark_node;
        }
 
@@ -3611,7 +3613,8 @@ finish_pseudo_destructor_expr (tree object, tree scope, 
tree destructor,
       if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object),
                                                      destructor))
        {
-         error_at (loc, "%qE is not of type %qT", object, destructor);
+         if (complain & tf_error)
+           error_at (loc, "%qE is not of type %qT", object, destructor);
          return error_mark_node;
        }
     }
diff --git a/gcc/testsuite/g++.dg/template/pseudodtor7.C 
b/gcc/testsuite/g++.dg/template/pseudodtor7.C
new file mode 100644
index 000000000000..302b8c96625f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pseudodtor7.C
@@ -0,0 +1,15 @@
+// PR c++/116417
+// { dg-do compile { target c++11 } }
+
+template<class T>
+T&& declval();
+
+template<class T, class = decltype(declval<T>().~T())>
+void f(int) = delete;
+
+template<class T>
+void f(...);
+
+int main() {
+  f<int&>(0);
+}

Reply via email to