aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/typeck.c15
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C14
-rw-r--r--gcc/testsuite/g++.dg/template/crash106.C4
4 files changed, 31 insertions, 4 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c73e035..288625e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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". */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 63a0eae..84dcb6f 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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
diff --git a/gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C b/gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C
new file mode 100644
index 0000000..6096a98
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/ptrtomem3.C
@@ -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" }
+}
diff --git a/gcc/testsuite/g++.dg/template/crash106.C b/gcc/testsuite/g++.dg/template/crash106.C
index f904bd4..35cedb5 100644
--- a/gcc/testsuite/g++.dg/template/crash106.C
+++ b/gcc/testsuite/g++.dg/template/crash106.C
@@ -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 } }