Hi,
yesterday I didn't notice that grok_op_properties calls a couple of
helpers which are affected by exactly the same location issues. The
below simply forwards the location to the helpers. Tested x86_64-linux.
Thanks, Paolo.
////////////////////////
/cp
2018-06-12 Paolo Carlini <paolo.carl...@oracle.com>
* decl2.c (coerce_new_type, coerce_delete_type): Add location_t
parameter and adjust error_at calls.
* decl.c (grok_op_properties): Adjust calls.
* cp-tree.h (oerce_new_type, coerce_delete_type): Adjust decls.
/testsuite
2018-06-12 Paolo Carlini <paolo.carl...@oracle.com>
* g++.dg/init/delete3.C: New.
* g++.dg/init/new49.C: Likewise.
* g++.dg/init/new25.C: Test locations too.
* g++.dg/template/new4.C: Likewise.
* g++.old-deja/g++.jason/operator.C: Likewise.
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 261457)
+++ cp/cp-tree.h (working copy)
@@ -6346,8 +6346,8 @@ extern bool attributes_naming_typedef_ok (tree);
extern void cplus_decl_attributes (tree *, tree, int);
extern void finish_anon_union (tree);
extern void cxx_post_compilation_parsing_cleanups (void);
-extern tree coerce_new_type (tree);
-extern tree coerce_delete_type (tree);
+extern tree coerce_new_type (tree, location_t);
+extern tree coerce_delete_type (tree, location_t);
extern void comdat_linkage (tree);
extern void determine_visibility (tree);
extern void constrain_class_visibility (tree);
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 261457)
+++ cp/decl.c (working copy)
@@ -13153,11 +13153,11 @@ grok_op_properties (tree decl, bool complain)
}
if (op_flags & OVL_OP_FLAG_DELETE)
- TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
+ TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl), loc);
else
{
DECL_IS_OPERATOR_NEW (decl) = 1;
- TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
+ TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl), loc);
}
return true;
Index: cp/decl2.c
===================================================================
--- cp/decl2.c (revision 261457)
+++ cp/decl2.c (working copy)
@@ -1676,7 +1676,7 @@ finish_anon_union (tree anon_union_decl)
what compiler will be expecting. */
tree
-coerce_new_type (tree type)
+coerce_new_type (tree type, location_t loc)
{
int e = 0;
tree args = TYPE_ARG_TYPES (type);
@@ -1686,7 +1686,8 @@ tree
if (!same_type_p (TREE_TYPE (type), ptr_type_node))
{
e = 1;
- error ("%<operator new%> must return type %qT", ptr_type_node);
+ error_at (loc, "%<operator new%> must return type %qT",
+ ptr_type_node);
}
if (args && args != void_list_node)
@@ -1697,8 +1698,8 @@ tree
The first parameter shall not have an associated default
argument. */
- error ("the first parameter of %<operator new%> cannot "
- "have a default argument");
+ error_at (loc, "the first parameter of %<operator new%> cannot "
+ "have a default argument");
/* Throw away the default argument. */
TREE_PURPOSE (args) = NULL_TREE;
}
@@ -1713,7 +1714,7 @@ tree
e = 2;
if (e == 2)
- permerror (input_location, "%<operator new%> takes type %<size_t%> (%qT) "
+ permerror (loc, "%<operator new%> takes type %<size_t%> (%qT) "
"as first parameter", size_type_node);
switch (e)
@@ -1732,7 +1733,7 @@ tree
}
tree
-coerce_delete_type (tree type)
+coerce_delete_type (tree type, location_t loc)
{
int e = 0;
tree args = TYPE_ARG_TYPES (type);
@@ -1742,7 +1743,8 @@ tree
if (!same_type_p (TREE_TYPE (type), void_type_node))
{
e = 1;
- error ("%<operator delete%> must return type %qT", void_type_node);
+ error_at (loc, "%<operator delete%> must return type %qT",
+ void_type_node);
}
if (!args || args == void_list_node
@@ -1751,8 +1753,8 @@ tree
e = 2;
if (args && args != void_list_node)
args = TREE_CHAIN (args);
- error ("%<operator delete%> takes type %qT as first parameter",
- ptr_type_node);
+ error_at (loc, "%<operator delete%> takes type %qT as first parameter",
+ ptr_type_node);
}
switch (e)
{
Index: testsuite/g++.dg/init/delete3.C
===================================================================
--- testsuite/g++.dg/init/delete3.C (nonexistent)
+++ testsuite/g++.dg/init/delete3.C (working copy)
@@ -0,0 +1 @@
+int operator delete (void*, int); // { dg-error "5:.operator delete. must
return type .void." }
Index: testsuite/g++.dg/init/new25.C
===================================================================
--- testsuite/g++.dg/init/new25.C (revision 261457)
+++ testsuite/g++.dg/init/new25.C (working copy)
@@ -4,14 +4,14 @@
class C
{
public:
- void* operator new(std::size_t = 32) throw (std::bad_alloc); // { dg-error
"first parameter" }
+ void* operator new(std::size_t = 32) throw (std::bad_alloc); // { dg-error
"9:the first parameter of .operator new. cannot have a default argument" }
// { dg-error
"dynamic exception specification" "" { target c++17 } .-1 }
// { dg-warning
"deprecated" "" { target { c++11 && { ! c++17 } } } .-2 }
- void* operator new[](std::size_t = 32) throw (std::bad_alloc); // { dg-error
"first parameter" }
+ void* operator new[](std::size_t = 32) throw (std::bad_alloc); // { dg-error
"9:the first parameter of .operator new. cannot have a default argument" }
// { dg-error
"dynamic exception specification" "" { target c++17 } .-1 }
// {
dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } .-2 }
- void* operator new(std::size_t = 32, const std::nothrow_t&) throw(); // {
dg-error "first parameter" }
- void* operator new[](std::size_t = 32, const std::nothrow_t&) throw(); // {
dg-error "first parameter" }
+ void* operator new(std::size_t = 32, const std::nothrow_t&) throw(); // {
dg-error "9:the first parameter of .operator new. cannot have a default
argument" }
+ void* operator new[](std::size_t = 32, const std::nothrow_t&) throw(); // {
dg-error "9:the first parameter of .operator new. cannot have a default
argument" }
};
class D
@@ -26,8 +26,8 @@ class D
class E
{
public:
- void* operator new(std::size_t = 0,
- const std::nothrow_t& = std::nothrow_t()) throw(); // {
dg-error "first parameter" }
- void* operator new[](std::size_t = 0,
- const std::nothrow_t& = std::nothrow_t()) throw(); // {
dg-error "first parameter" }
+ void* operator new(std::size_t = 0, // { dg-error "9:the first parameter of
.operator new. cannot have a default argument" }
+ const std::nothrow_t& = std::nothrow_t()) throw();
+ void* operator new[](std::size_t = 0, // { dg-error "9:the first parameter
of .operator new. cannot have a default argument" }
+ const std::nothrow_t& = std::nothrow_t()) throw();
};
Index: testsuite/g++.dg/init/new49.C
===================================================================
--- testsuite/g++.dg/init/new49.C (nonexistent)
+++ testsuite/g++.dg/init/new49.C (working copy)
@@ -0,0 +1 @@
+int operator new (__SIZE_TYPE__, int); // { dg-error "5:.operator new. must
return type .void*." }
Index: testsuite/g++.dg/template/new4.C
===================================================================
--- testsuite/g++.dg/template/new4.C (revision 261457)
+++ testsuite/g++.dg/template/new4.C (working copy)
@@ -4,5 +4,6 @@
struct A
{
template<typename T>
- static void* operator new(T) {} // { dg-error "first parameter|invalid
template" }
+ static void* operator new(T) {} // { dg-error "invalid template" }
+// { dg-error "18:.operator new. takes type .size_t." "first" { target *-*-* }
.-1 }
};
Index: testsuite/g++.old-deja/g++.jason/operator.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/operator.C (revision 261457)
+++ testsuite/g++.old-deja/g++.jason/operator.C (working copy)
@@ -25,8 +25,8 @@ struct B {
int operator-(int a, int b); // { dg-error "5:.int operator-\\(int, int\\).
must have an argument of class or enumerated type" }
-void * operator new (A a); // { dg-error "first parameter" }
-void operator delete (A a); // { dg-error "first parameter" }
+void * operator new (A a); // { dg-error ".operator new. takes type
.size_t." }
+void operator delete (A a); // { dg-error ".operator delete. takes type
.void\\*. as first parameter" }
char * operator char * (int); // { dg-error "return type" "ret" }
// { dg-error "8:.operator char\\*\\*\\(int\\). must be a nonstatic member
function" "mem" { target *-*-* } .-1 }