mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
c++: printing AGGR_INIT_EXPR args
PR30854 was about wrongly dumping the dummy object argument to a constructor; r126582 in 4.3 fixed that by skipping the first argument. But not all functions called by AGGR_INIT_EXPR are constructors, as observed in PR116634; we shouldn't skip for non-member functions. And let's combine the printing code for CALL_EXPR and AGGR_INIT_EXPR. This doesn't make us accept the ill-formed 116634 testcase again with a pedwarn, just fixes the diagnostic issue. PR c++/30854 PR c++/116634 gcc/cp/ChangeLog: * error.cc (dump_aggr_init_expr_args): Remove. (dump_call_expr_args): Handle AGGR_INIT_EXPR. (dump_expr): Combine AGGR_INIT_EXPR and CALL_EXPR cases. gcc/testsuite/ChangeLog: * g++.dg/coroutines/coro-bad-alloc-02-no-op-new-nt.C: Adjust diagnostic. * g++.dg/diagnostic/aggr-init1.C: New test.
This commit is contained in:
parent
f003834bad
commit
e6d21cbf5c
@ -84,7 +84,6 @@ static void dump_type_prefix (cxx_pretty_printer *, tree, int);
|
||||
static void dump_type_suffix (cxx_pretty_printer *, tree, int);
|
||||
static void dump_function_name (cxx_pretty_printer *, tree, int);
|
||||
static void dump_call_expr_args (cxx_pretty_printer *, tree, int, bool);
|
||||
static void dump_aggr_init_expr_args (cxx_pretty_printer *, tree, int, bool);
|
||||
static void dump_expr_list (cxx_pretty_printer *, tree, int);
|
||||
static void dump_global_iord (cxx_pretty_printer *, tree);
|
||||
static void dump_parameters (cxx_pretty_printer *, tree, int);
|
||||
@ -2253,46 +2252,15 @@ dump_template_parms (cxx_pretty_printer *pp, tree info,
|
||||
static void
|
||||
dump_call_expr_args (cxx_pretty_printer *pp, tree t, int flags, bool skipfirst)
|
||||
{
|
||||
tree arg;
|
||||
call_expr_arg_iterator iter;
|
||||
const int len = call_expr_nargs (t);
|
||||
|
||||
pp_cxx_left_paren (pp);
|
||||
FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
|
||||
for (int i = skipfirst; i < len; ++i)
|
||||
{
|
||||
if (skipfirst)
|
||||
skipfirst = false;
|
||||
else
|
||||
{
|
||||
dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
|
||||
if (more_call_expr_args_p (&iter))
|
||||
pp_separate_with_comma (pp);
|
||||
}
|
||||
}
|
||||
pp_cxx_right_paren (pp);
|
||||
}
|
||||
|
||||
/* Print out the arguments of AGGR_INIT_EXPR T as a parenthesized list
|
||||
using flags FLAGS. Skip over the first argument if SKIPFIRST is
|
||||
true. */
|
||||
|
||||
static void
|
||||
dump_aggr_init_expr_args (cxx_pretty_printer *pp, tree t, int flags,
|
||||
bool skipfirst)
|
||||
{
|
||||
tree arg;
|
||||
aggr_init_expr_arg_iterator iter;
|
||||
|
||||
pp_cxx_left_paren (pp);
|
||||
FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
|
||||
{
|
||||
if (skipfirst)
|
||||
skipfirst = false;
|
||||
else
|
||||
{
|
||||
dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
|
||||
if (more_aggr_init_expr_args_p (&iter))
|
||||
pp_separate_with_comma (pp);
|
||||
}
|
||||
tree arg = get_nth_callarg (t, i);
|
||||
dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
|
||||
if (i + 1 < len)
|
||||
pp_separate_with_comma (pp);
|
||||
}
|
||||
pp_cxx_right_paren (pp);
|
||||
}
|
||||
@ -2451,28 +2419,9 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
|
||||
break;
|
||||
|
||||
case AGGR_INIT_EXPR:
|
||||
{
|
||||
tree fn = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (AGGR_INIT_EXPR_FN (t)) == ADDR_EXPR)
|
||||
fn = TREE_OPERAND (AGGR_INIT_EXPR_FN (t), 0);
|
||||
|
||||
if (fn && TREE_CODE (fn) == FUNCTION_DECL)
|
||||
{
|
||||
if (DECL_CONSTRUCTOR_P (fn))
|
||||
dump_type (pp, DECL_CONTEXT (fn), flags);
|
||||
else
|
||||
dump_decl (pp, fn, 0);
|
||||
}
|
||||
else
|
||||
dump_expr (pp, AGGR_INIT_EXPR_FN (t), 0);
|
||||
}
|
||||
dump_aggr_init_expr_args (pp, t, flags, true);
|
||||
break;
|
||||
|
||||
case CALL_EXPR:
|
||||
{
|
||||
tree fn = CALL_EXPR_FN (t);
|
||||
tree fn = cp_get_callee (t);
|
||||
bool skipfirst = false;
|
||||
|
||||
/* Deal with internal functions. */
|
||||
@ -2494,8 +2443,10 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
|
||||
&& NEXT_CODE (fn) == METHOD_TYPE
|
||||
&& call_expr_nargs (t))
|
||||
{
|
||||
tree ob = CALL_EXPR_ARG (t, 0);
|
||||
if (TREE_CODE (ob) == ADDR_EXPR)
|
||||
tree ob = get_nth_callarg (t, 0);
|
||||
if (is_dummy_object (ob))
|
||||
/* Don't print dummy object. */;
|
||||
else if (TREE_CODE (ob) == ADDR_EXPR)
|
||||
{
|
||||
dump_expr (pp, TREE_OPERAND (ob, 0),
|
||||
flags | TFF_EXPR_IN_PARENS);
|
||||
@ -2514,7 +2465,13 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
|
||||
pp_string (cxx_pp, M_("<ubsan routine call>"));
|
||||
break;
|
||||
}
|
||||
dump_expr (pp, fn, flags | TFF_EXPR_IN_PARENS);
|
||||
|
||||
if (TREE_CODE (fn) == FUNCTION_DECL
|
||||
&& DECL_CONSTRUCTOR_P (fn)
|
||||
&& is_dummy_object (get_nth_callarg (t, 0)))
|
||||
dump_type (pp, DECL_CONTEXT (fn), flags);
|
||||
else
|
||||
dump_expr (pp, fn, flags | TFF_EXPR_IN_PARENS);
|
||||
dump_call_expr_args (pp, t, flags, skipfirst);
|
||||
}
|
||||
break;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "coro1-allocators.h"
|
||||
|
||||
struct coro1
|
||||
f () /* { dg-error {'coro1::promise_type::get_return_object_on_allocation_failure\(\)\(\)' is provided by 'std::__n4861::__coroutine_traits_impl<coro1, void>::promise_type' \{aka 'coro1::promise_type'\} but 'operator new' is not marked 'throw\(\)' or 'noexcept'} } */
|
||||
f () /* { dg-error {'coro1::promise_type::get_return_object_on_allocation_failure\(\)' is provided by 'std::__n4861::__coroutine_traits_impl<coro1, void>::promise_type' \{aka 'coro1::promise_type'\} but 'operator new' is not marked 'throw\(\)' or 'noexcept'} } */
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
36
gcc/testsuite/g++.dg/diagnostic/aggr-init1.C
Normal file
36
gcc/testsuite/g++.dg/diagnostic/aggr-init1.C
Normal file
@ -0,0 +1,36 @@
|
||||
// PR c++/116634
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
namespace std {
|
||||
using size_t = decltype(sizeof(42));
|
||||
}
|
||||
|
||||
class ConstString final {
|
||||
public:
|
||||
constexpr ConstString() noexcept: buf(), len(0) {}
|
||||
template<int N>
|
||||
constexpr ConstString(const char (&a)[N]): buf(a), len(N - 1) {}
|
||||
constexpr ConstString(const ConstString &c1): buf(c1.buf), len(static_cast<int>(c1.len)) {}
|
||||
|
||||
private:
|
||||
const char* buf;
|
||||
int len;
|
||||
};
|
||||
|
||||
template<int N>
|
||||
struct Any final {
|
||||
constexpr
|
||||
Any(ConstString (&&_vec)[N]) noexcept: vec(_vec){} // { dg-error "array" }
|
||||
|
||||
ConstString vec[N];
|
||||
};
|
||||
|
||||
template<int... N1>
|
||||
constexpr static
|
||||
auto Any_of(const char (&...c1)[N1]) -> Any<static_cast<int>(sizeof...(N1))> {
|
||||
return {{ConstString(c1)...}};
|
||||
}
|
||||
|
||||
int main() {
|
||||
constexpr static const auto aa1 = Any_of("abcd", "def"); // { dg-message {"abcd", "def"} }
|
||||
}
|
Loading…
Reference in New Issue
Block a user