aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2025-01-16 16:05:46 -0500
committerPatrick Palka <ppalka@redhat.com>2025-01-16 16:05:46 -0500
commit232d3a73e18d6886f0a5781048a78da293fbb014 (patch)
tree1511512f0ec3a07f00d71b18076f273834b54f7d /gcc
parent37f38b0f97374476a4818b68c8df991886428787 (diff)
downloadgcc-232d3a73e18d6886f0a5781048a78da293fbb014.zip
gcc-232d3a73e18d6886f0a5781048a78da293fbb014.tar.gz
gcc-232d3a73e18d6886f0a5781048a78da293fbb014.tar.bz2
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 <polacek@redhat.com> Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/parser.cc3
-rw-r--r--gcc/cp/pt.cc4
-rw-r--r--gcc/cp/semantics.cc15
-rw-r--r--gcc/testsuite/g++.dg/template/pseudodtor7.C15
5 files changed, 29 insertions, 10 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 269aca5..e229fe0 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 ba2c4db..c030a18 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 961696f..00b61ae 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 2daad2d..e891319 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 0000000..302b8c9
--- /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);
+}