aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-06-09 20:40:44 -0400
committerJason Merrill <jason@gcc.gnu.org>2017-06-09 20:40:44 -0400
commit8b8b203a26bdac3dede77e76d06e4e7084f79acc (patch)
tree17fc780673ab6af72b41232e6ed5191e0b849c1d /gcc/cp/pt.c
parent52486891929862f8272e1c602957f5cb3b5d6e2a (diff)
downloadgcc-8b8b203a26bdac3dede77e76d06e4e7084f79acc.zip
gcc-8b8b203a26bdac3dede77e76d06e4e7084f79acc.tar.gz
gcc-8b8b203a26bdac3dede77e76d06e4e7084f79acc.tar.bz2
Overhaul pointer-to-member conversion and template argument handling.
* call.c (standard_conversion): Avoid creating ck_pmem when the class type is the same. * cvt.c (can_convert_qual): Split from perform_qualification_conversions. * constexpr.c (cxx_eval_constant_expression): Check it. * typeck.c (convert_ptrmem): Only cplus_expand_constant if adjustment is necessary. * pt.c (check_valid_ptrmem_cst_expr): Compare class types. (convert_nontype_argument): Avoid redundant error. From-SVN: r249088
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c45
1 files changed, 15 insertions, 30 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 40be3c1..b537cb8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6124,8 +6124,14 @@ static bool
check_valid_ptrmem_cst_expr (tree type, tree expr,
tsubst_flags_t complain)
{
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+ tree orig_expr = expr;
STRIP_NOPS (expr);
- if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST))
+ if (null_ptr_cst_p (expr))
+ return true;
+ if (TREE_CODE (expr) == PTRMEM_CST
+ && same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
+ PTRMEM_CST_CLASS (expr)))
return true;
if (cxx_dialect >= cxx11 && null_member_pointer_value_p (expr))
return true;
@@ -6135,9 +6141,12 @@ check_valid_ptrmem_cst_expr (tree type, tree expr,
return true;
if (complain & tf_error)
{
- error ("%qE is not a valid template argument for type %qT",
- expr, type);
- error ("it must be a pointer-to-member of the form %<&X::Y%>");
+ error_at (loc, "%qE is not a valid template argument for type %qT",
+ orig_expr, type);
+ if (TREE_CODE (expr) != PTRMEM_CST)
+ inform (loc, "it must be a pointer-to-member of the form %<&X::Y%>");
+ else
+ inform (loc, "because it is a member of %qT", PTRMEM_CST_CLASS (expr));
}
return false;
}
@@ -6880,36 +6889,12 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
expression must be a pointer-to-member constant. */
if (!value_dependent_expression_p (expr)
&& !check_valid_ptrmem_cst_expr (type, expr, complain))
- return error_mark_node;
+ return NULL_TREE;
/* Repeated conversion can't deal with a conversion that turns PTRMEM_CST
into a CONSTRUCTOR, so build up a new PTRMEM_CST instead. */
if (fnptr_conv_p (type, TREE_TYPE (expr)))
expr = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr));
-
- /* There is no way to disable standard conversions in
- resolve_address_of_overloaded_function (called by
- instantiate_type). It is possible that the call succeeded by
- converting &B::I to &D::I (where B is a base of D), so we need
- to reject this conversion here.
-
- Actually, even if there was a way to disable standard conversions,
- it would still be better to reject them here so that we can
- provide a superior diagnostic. */
- if (!same_type_p (TREE_TYPE (expr), type))
- {
- if (complain & tf_error)
- {
- error ("%qE is not a valid template argument for type %qT "
- "because it is of type %qT", expr, type,
- TREE_TYPE (expr));
- /* If we are just one standard conversion off, explain. */
- if (can_convert_standard (type, TREE_TYPE (expr), complain))
- inform (input_location,
- "standard conversions are not allowed in this context");
- }
- return NULL_TREE;
- }
}
/* [temp.arg.nontype]/5, bullet 7
@@ -6921,7 +6906,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
expression must be a pointer-to-member constant. */
if (!value_dependent_expression_p (expr)
&& !check_valid_ptrmem_cst_expr (type, expr, complain))
- return error_mark_node;
+ return NULL_TREE;
expr = perform_qualification_conversions (type, expr);
if (expr == error_mark_node)