c++: remember pointer-to-member location
Jakub recently mentioned that a PTRMEM_CST has no location; let's give it a location wrapper. gcc/cp/ChangeLog: * typeck.c (build_x_unary_op): Set address location. (convert_member_func_to_ptr): Handle location wrapper. * pt.c (convert_nontype_argument): Likewise. gcc/testsuite/ChangeLog: * g++.dg/template/crash106.C: Adjust. * g++.dg/diagnostic/ptrtomem3.C: New test.
This commit is contained in:
parent
5440c88e61
commit
1df539fd19
4 changed files with 31 additions and 4 deletions
|
@ -7267,6 +7267,8 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
|
|||
const bool val_dep_p = value_dependent_expression_p (expr);
|
||||
if (val_dep_p)
|
||||
expr = canonicalize_expr_argument (expr, complain);
|
||||
else
|
||||
STRIP_ANY_LOCATION_WRAPPER (expr);
|
||||
|
||||
/* 14.3.2/5: The null pointer{,-to-member} conversion is applied
|
||||
to a non-type argument of "nullptr". */
|
||||
|
|
|
@ -6492,6 +6492,11 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
|
|||
}
|
||||
|
||||
exp = cp_build_addr_expr_strict (xarg, complain);
|
||||
|
||||
if (TREE_CODE (exp) == PTRMEM_CST)
|
||||
exp = maybe_wrap_with_location (exp, loc);
|
||||
else
|
||||
protected_set_expr_location (exp, loc);
|
||||
}
|
||||
|
||||
if (processing_template_decl && exp != error_mark_node)
|
||||
|
@ -8179,10 +8184,14 @@ convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
|
|||
if (!(complain & tf_warning_or_error))
|
||||
return error_mark_node;
|
||||
|
||||
location_t loc = cp_expr_loc_or_input_loc (expr);
|
||||
|
||||
if (pedantic || warn_pmf2ptr)
|
||||
pedwarn (input_location, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
|
||||
pedwarn (loc, pedantic ? OPT_Wpedantic : OPT_Wpmf_conversions,
|
||||
"converting from %qH to %qI", intype, type);
|
||||
|
||||
STRIP_ANY_LOCATION_WRAPPER (expr);
|
||||
|
||||
if (TREE_CODE (intype) == METHOD_TYPE)
|
||||
expr = build_addr_func (expr, complain);
|
||||
else if (TREE_CODE (expr) == PTRMEM_CST)
|
||||
|
@ -8197,7 +8206,9 @@ convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
|
|||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
return build_nop (type, expr);
|
||||
expr = build_nop (type, expr);
|
||||
SET_EXPR_LOCATION (expr, loc);
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Build a NOP_EXPR to TYPE, but mark it as a reinterpret_cast so that
|
||||
|
|
14
gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C
Normal file
14
gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Check that the diagnostic for a pointer-to-member expression has the caret
|
||||
// at the &.
|
||||
|
||||
struct A
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
void f();
|
||||
|
||||
int main()
|
||||
{
|
||||
return &A::i; // { dg-error "10:cannot convert" }
|
||||
}
|
|
@ -7,6 +7,6 @@ struct A
|
|||
template<T> void foo(); // { dg-error "type" "" { target c++17_down } }
|
||||
};
|
||||
|
||||
template<T N = 0.0, void (A::*)() = &A::foo<N> > struct B {}; // { dg-error "type|declared" "" { target c++17_down } }
|
||||
template<T N = 0.0, void (A::*)() = &A::foo<N> > struct B {}; // { dg-error "type|declared|could not convert" "" { target c++17_down } }
|
||||
|
||||
B<> b; // { dg-error "(could not convert|no matches)" "" { target c++17_down } }
|
||||
B<> b; // { dg-message "" "" { target c++17_down } }
|
||||
|
|
Loading…
Add table
Reference in a new issue