Commit 34dda804 by Paolo Carlini Committed by Paolo Carlini

typeck.c (cp_build_addr_expr_1): Use the cp_expr_loc_or_input_loc location in a…

typeck.c (cp_build_addr_expr_1): Use the cp_expr_loc_or_input_loc location in a few additional diagnostics; tidy.

/cp
2019-12-03  Paolo Carlini  <paolo.carlini@oracle.com>

	* typeck.c (cp_build_addr_expr_1): Use the cp_expr_loc_or_input_loc
	location in a few additional diagnostics; tidy.
	(check_return_expr): Likewise.

	* typeck.c (cp_build_addr_expr_1): Use tree_strip_any_location_wrapper
	for the address of main pedwarn.

/testsuite
2019-12-03  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/diagnostic/inconsistent-deduction-1.C: New.
	* g++.dg/diagnostic/returning-a-value-1.C: Likewise.
	* g++.dg/cpp0x/decltype3.C: Check location(s) too.
	* g++.dg/cpp0x/decltype4.C: Likewise.
	* g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C: Likewise.
	* g++.dg/cpp2a/consteval13.C: Likewise.
	* g++.dg/expr/pmf-1.C: Likewise.
	* g++.dg/other/ptrmem2.C: Likewise.
	* g++.dg/template/ptrmem17.C: Likewise.
	* g++.old-deja/g++.bugs/900213_03.C: Likewise.
	* g++.old-deja/g++.other/pmf7.C: Likewise.
	* g++.old-deja/g++.other/ptrmem7.C: Likewise.

	* g++.dg/diagnostic/main2.C: New.

From-SVN: r278947
parent ac0573de
2019-12-03 Paolo Carlini <paolo.carlini@oracle.com>
* typeck.c (cp_build_addr_expr_1): Use the cp_expr_loc_or_input_loc
location in a few additional diagnostics; tidy.
(check_return_expr): Likewise.
* typeck.c (cp_build_addr_expr_1): Use tree_strip_any_location_wrapper
for the address of main pedwarn.
2019-12-03 Jakub Jelinek <jakub@redhat.com> 2019-12-03 Jakub Jelinek <jakub@redhat.com>
PR c++/91369 PR c++/91369
......
...@@ -6070,6 +6070,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) ...@@ -6070,6 +6070,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
return error_mark_node; return error_mark_node;
argtype = lvalue_type (arg); argtype = lvalue_type (arg);
location_t loc = cp_expr_loc_or_input_loc (arg);
gcc_assert (!(identifier_p (arg) && IDENTIFIER_ANY_OP_P (arg))); gcc_assert (!(identifier_p (arg) && IDENTIFIER_ANY_OP_P (arg)));
...@@ -6103,12 +6104,14 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) ...@@ -6103,12 +6104,14 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
else if (current_class_type else if (current_class_type
&& TREE_OPERAND (arg, 0) == current_class_ref) && TREE_OPERAND (arg, 0) == current_class_ref)
/* An expression like &memfn. */ /* An expression like &memfn. */
permerror (input_location, "ISO C++ forbids taking the address of an unqualified" permerror (loc,
"ISO C++ forbids taking the address of an unqualified"
" or parenthesized non-static member function to form" " or parenthesized non-static member function to form"
" a pointer to member function. Say %<&%T::%D%>", " a pointer to member function. Say %<&%T::%D%>",
base, name); base, name);
else else
permerror (input_location, "ISO C++ forbids taking the address of a bound member" permerror (loc,
"ISO C++ forbids taking the address of a bound member"
" function to form a pointer to member function." " function to form a pointer to member function."
" Say %<&%T::%D%>", " Say %<&%T::%D%>",
base, name); base, name);
...@@ -6135,7 +6138,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) ...@@ -6135,7 +6138,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
if (kind == clk_none) if (kind == clk_none)
{ {
if (complain & tf_error) if (complain & tf_error)
lvalue_error (cp_expr_loc_or_input_loc (arg), lv_addressof); lvalue_error (loc, lv_addressof);
return error_mark_node; return error_mark_node;
} }
if (strict_lvalue && (kind & (clk_rvalueref|clk_class))) if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
...@@ -6143,8 +6146,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) ...@@ -6143,8 +6146,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
if (!(complain & tf_error)) if (!(complain & tf_error))
return error_mark_node; return error_mark_node;
/* Make this a permerror because we used to accept it. */ /* Make this a permerror because we used to accept it. */
permerror (cp_expr_loc_or_input_loc (arg), permerror (loc, "taking address of rvalue");
"taking address of rvalue");
} }
} }
...@@ -6154,13 +6156,13 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) ...@@ -6154,13 +6156,13 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
arg = build1 (CONVERT_EXPR, type, arg); arg = build1 (CONVERT_EXPR, type, arg);
return arg; return arg;
} }
else if (pedantic && DECL_MAIN_P (arg)) else if (pedantic && DECL_MAIN_P (tree_strip_any_location_wrapper (arg)))
{ {
/* ARM $3.4 */ /* ARM $3.4 */
/* Apparently a lot of autoconf scripts for C++ packages do this, /* Apparently a lot of autoconf scripts for C++ packages do this,
so only complain if -Wpedantic. */ so only complain if -Wpedantic. */
if (complain & (flag_pedantic_errors ? tf_error : tf_warning)) if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
pedwarn (input_location, OPT_Wpedantic, pedwarn (loc, OPT_Wpedantic,
"ISO C++ forbids taking address of function %<::main%>"); "ISO C++ forbids taking address of function %<::main%>");
else if (flag_pedantic_errors) else if (flag_pedantic_errors)
return error_mark_node; return error_mark_node;
...@@ -6218,7 +6220,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) ...@@ -6218,7 +6220,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
if (TYPE_REF_P (TREE_TYPE (t))) if (TYPE_REF_P (TREE_TYPE (t)))
{ {
if (complain & tf_error) if (complain & tf_error)
error ("cannot create pointer to reference member %qD", t); error_at (loc,
"cannot create pointer to reference member %qD", t);
return error_mark_node; return error_mark_node;
} }
...@@ -6238,8 +6241,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) ...@@ -6238,8 +6241,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
if (bitfield_p (arg)) if (bitfield_p (arg))
{ {
if (complain & tf_error) if (complain & tf_error)
error_at (cp_expr_loc_or_input_loc (arg), error_at (loc, "attempt to take address of bit-field");
"attempt to take address of bit-field");
return error_mark_node; return error_mark_node;
} }
...@@ -6254,8 +6256,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) ...@@ -6254,8 +6256,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
|| !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))) || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl)))
{ {
if (complain & tf_error) if (complain & tf_error)
error ("taking address of an immediate function %qD", error_at (loc, "taking address of an immediate function %qD",
stripped_arg); stripped_arg);
return error_mark_node; return error_mark_node;
} }
if (TREE_CODE (stripped_arg) == FUNCTION_DECL if (TREE_CODE (stripped_arg) == FUNCTION_DECL
...@@ -9676,6 +9678,7 @@ check_return_expr (tree retval, bool *no_warning) ...@@ -9676,6 +9678,7 @@ check_return_expr (tree retval, bool *no_warning)
the declared type is incomplete. */ the declared type is incomplete. */
tree functype; tree functype;
int fn_returns_value_p; int fn_returns_value_p;
location_t loc = cp_expr_loc_or_input_loc (retval);
*no_warning = false; *no_warning = false;
...@@ -9689,7 +9692,7 @@ check_return_expr (tree retval, bool *no_warning) ...@@ -9689,7 +9692,7 @@ check_return_expr (tree retval, bool *no_warning)
if (DECL_DESTRUCTOR_P (current_function_decl)) if (DECL_DESTRUCTOR_P (current_function_decl))
{ {
if (retval) if (retval)
error ("returning a value from a destructor"); error_at (loc, "returning a value from a destructor");
return NULL_TREE; return NULL_TREE;
} }
else if (DECL_CONSTRUCTOR_P (current_function_decl)) else if (DECL_CONSTRUCTOR_P (current_function_decl))
...@@ -9700,7 +9703,7 @@ check_return_expr (tree retval, bool *no_warning) ...@@ -9700,7 +9703,7 @@ check_return_expr (tree retval, bool *no_warning)
error ("cannot return from a handler of a function-try-block of a constructor"); error ("cannot return from a handler of a function-try-block of a constructor");
else if (retval) else if (retval)
/* You can't return a value from a constructor. */ /* You can't return a value from a constructor. */
error ("returning a value from a constructor"); error_at (loc, "returning a value from a constructor");
return NULL_TREE; return NULL_TREE;
} }
...@@ -9762,11 +9765,11 @@ check_return_expr (tree retval, bool *no_warning) ...@@ -9762,11 +9765,11 @@ check_return_expr (tree retval, bool *no_warning)
else if (!same_type_p (type, functype)) else if (!same_type_p (type, functype))
{ {
if (LAMBDA_FUNCTION_P (current_function_decl)) if (LAMBDA_FUNCTION_P (current_function_decl))
error ("inconsistent types %qT and %qT deduced for " error_at (loc, "inconsistent types %qT and %qT deduced for "
"lambda return type", functype, type); "lambda return type", functype, type);
else else
error ("inconsistent deduction for auto return type: " error_at (loc, "inconsistent deduction for auto return type: "
"%qT and then %qT", functype, type); "%qT and then %qT", functype, type);
} }
functype = type; functype = type;
} }
...@@ -9800,8 +9803,7 @@ check_return_expr (tree retval, bool *no_warning) ...@@ -9800,8 +9803,7 @@ check_return_expr (tree retval, bool *no_warning)
its side-effects. */ its side-effects. */
finish_expr_stmt (retval); finish_expr_stmt (retval);
else if (retval != error_mark_node) else if (retval != error_mark_node)
permerror (input_location, permerror (loc, "return-statement with a value, in function "
"return-statement with a value, in function "
"returning %qT", valtype); "returning %qT", valtype);
current_function_returns_null = 1; current_function_returns_null = 1;
...@@ -9857,7 +9859,8 @@ check_return_expr (tree retval, bool *no_warning) ...@@ -9857,7 +9859,8 @@ check_return_expr (tree retval, bool *no_warning)
} }
if (warn) if (warn)
warning (OPT_Weffc__, "%<operator=%> should return a reference to %<*this%>"); warning_at (loc, OPT_Weffc__,
"%<operator=%> should return a reference to %<*this%>");
} }
if (dependent_type_p (functype) if (dependent_type_p (functype)
......
2019-12-03 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/diagnostic/inconsistent-deduction-1.C: New.
* g++.dg/diagnostic/returning-a-value-1.C: Likewise.
* g++.dg/cpp0x/decltype3.C: Check location(s) too.
* g++.dg/cpp0x/decltype4.C: Likewise.
* g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C: Likewise.
* g++.dg/cpp2a/consteval13.C: Likewise.
* g++.dg/expr/pmf-1.C: Likewise.
* g++.dg/other/ptrmem2.C: Likewise.
* g++.dg/template/ptrmem17.C: Likewise.
* g++.old-deja/g++.bugs/900213_03.C: Likewise.
* g++.old-deja/g++.other/pmf7.C: Likewise.
* g++.old-deja/g++.other/ptrmem7.C: Likewise.
* g++.dg/diagnostic/main2.C: New.
2019-12-03 Jakub Jelinek <jakub@redhat.com> 2019-12-03 Jakub Jelinek <jakub@redhat.com>
PR c++/91369 PR c++/91369
......
...@@ -54,7 +54,7 @@ public: ...@@ -54,7 +54,7 @@ public:
}; };
CHECK_DECLTYPE(decltype(aa.*&A::a), int&); CHECK_DECLTYPE(decltype(aa.*&A::a), int&);
decltype(aa.*&A::b) zz; // { dg-error "cannot create pointer to reference member" "cannot" } decltype(aa.*&A::b) zz; // { dg-error "18:cannot create pointer to reference member" "cannot" }
CHECK_DECLTYPE(decltype(caa.*&A::a), const int&); CHECK_DECLTYPE(decltype(caa.*&A::a), const int&);
......
...@@ -23,7 +23,7 @@ struct A { ...@@ -23,7 +23,7 @@ struct A {
}; };
CHECK_DECLTYPE(decltype(&A::x), int A::*); CHECK_DECLTYPE(decltype(&A::x), int A::*);
decltype(&A::y) Ay; // { dg-error "cannot create pointer to reference member|invalid type" } decltype(&A::y) Ay; // { dg-error "14:cannot create pointer to reference member|invalid type" }
CHECK_DECLTYPE(decltype(&A::foo), int (A::*) (char)); CHECK_DECLTYPE(decltype(&A::foo), int (A::*) (char));
CHECK_DECLTYPE(decltype(&A::bar), int& (A::*) () const); CHECK_DECLTYPE(decltype(&A::bar), int& (A::*) () const);
......
...@@ -11,7 +11,7 @@ template <class T> int f (T t) { ...@@ -11,7 +11,7 @@ template <class T> int f (T t) {
if (b) if (b)
return t.fn1(); return t.fn1();
else else
return t.fn2(); // { dg-error "inconsistent types" } return t.fn2(); // { dg-error "19:inconsistent types" }
}(t); }(t);
} }
......
...@@ -10,8 +10,8 @@ void ...@@ -10,8 +10,8 @@ void
foo () foo ()
{ {
auto qux = [] (fnptr a = quux ()) consteval { return a (); }; auto qux = [] (fnptr a = quux ()) consteval { return a (); };
constexpr auto c = qux (baz); // { dg-error "taking address of an immediate function" } constexpr auto c = qux (baz); // { dg-error "28:taking address of an immediate function" }
constexpr auto d = qux (bar); // { dg-error "taking address of an immediate function" } constexpr auto d = qux (bar); // { dg-error "28:taking address of an immediate function" }
static_assert (c == 1); static_assert (c == 1);
static_assert (d == 42); static_assert (d == 42);
} }
// { dg-do compile { target c++14 } }
void foo();
auto bar(bool b)
{
if (b)
return 0;
return foo(); // { dg-error "13:inconsistent deduction for auto return type: .int. and then .void." }
}
int main ();
typedef int (*fptr) ();
void foo (fptr);
fptr bar ()
{
foo (main); // { dg-error "8:ISO C\\+\\+ forbids taking address of function" }
return main; // { dg-error "10:ISO C\\+\\+ forbids taking address of function" }
}
int foo();
struct A
{
A() { return foo(); } // { dg-error "19:returning a value" }
~A() { return foo(); } // { dg-error "20:returning a value" }
void bar() { return foo(); } // { dg-error "26:return-statement with a value" }
};
...@@ -13,7 +13,7 @@ struct A ...@@ -13,7 +13,7 @@ struct A
void h() void h()
{ {
void (A::*p)() = &A::f; void (A::*p)() = &A::f;
void (A::*q)() = &(A::f); // { dg-error "parenthesized" } void (A::*q)() = &(A::f); // { dg-error "27:ISO C\\+\\+ forbids taking the address of an unqualified or parenthesized" }
foo(&g<int>); // { dg-error "cannot convert" } foo(&g<int>); // { dg-error "cannot convert" }
} }
}; };
...@@ -19,7 +19,7 @@ template<class T> int f2(T x); ...@@ -19,7 +19,7 @@ template<class T> int f2(T x);
int D::Foo () int D::Foo ()
{ {
f1( &D::m); // { dg-error "cannot create pointer to ref" } f1( &D::m); // { dg-error "11:cannot create pointer to ref" }
f1( &(D::m)); // ok f1( &(D::m)); // ok
f2( &D::s); // ok f2( &D::s); // ok
f2( &(D::s)); // ok f2( &(D::s)); // ok
...@@ -28,7 +28,7 @@ int D::Foo () ...@@ -28,7 +28,7 @@ int D::Foo ()
int Foo () int Foo ()
{ {
f1( &D::m); // { dg-error "cannot create pointer to ref" } f1( &D::m); // { dg-error "11:cannot create pointer to ref" }
f1( &(D::m)); // { dg-error "non-static" } f1( &(D::m)); // { dg-error "non-static" }
f2( &D::s); // ok f2( &D::s); // ok
f2( &(D::s)); // ok f2( &(D::s)); // ok
......
...@@ -4,7 +4,7 @@ template<int> struct A ...@@ -4,7 +4,7 @@ template<int> struct A
{ {
int& i; int& i;
A(); A();
~A() { &A::i; } // { dg-error "reference" } ~A() { &A::i; } // { dg-error "14:cannot create pointer to reference" }
}; };
A<0> a; A<0> a;
...@@ -21,7 +21,7 @@ struct0 *ptr; ...@@ -21,7 +21,7 @@ struct0 *ptr;
void global_function_0 () void global_function_0 ()
{ {
fmp = &ptr->function_member; // { dg-error "" } fmp = &ptr->function_member; // { dg-error "15:ISO C\\+\\+ forbids taking the address of a bound member function" }
//dmp = &ptr->data_member; // caught by g++, missed by cfront //dmp = &ptr->data_member; // caught by g++, missed by cfront
} }
......
...@@ -12,5 +12,5 @@ int main () ...@@ -12,5 +12,5 @@ int main ()
{ {
A a; A a;
&a.f; // { dg-error "" } overloaded &a.f; // { dg-error "" } overloaded
&a.g; // { dg-error "" } can't write a pmf like this &a.g; // { dg-error "6:ISO C\\+\\+ forbids taking the address of a bound member function" } can't write a pmf like this
} }
...@@ -36,7 +36,7 @@ void A::foo () ...@@ -36,7 +36,7 @@ void A::foo ()
int (A::*ptr14) (int) = single; // { dg-error "cannot convert" } int (A::*ptr14) (int) = single; // { dg-error "cannot convert" }
int (A::*ptr20) (int) = &(A::ns); // { dg-error "pointer to member" } int (A::*ptr20) (int) = &(A::ns); // { dg-error "pointer to member" }
int (A::*ptr21) (int) = &(A::single); // { dg-error "pointer to member" } int (A::*ptr21) (int) = &(A::single); // { dg-error "32:ISO C\\+\\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member" }
int (*ptr31) (short) = &A::sole; int (*ptr31) (short) = &A::sole;
int (*ptr32) (short) = A::sole; int (*ptr32) (short) = A::sole;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment