This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++ PATCH for c++/85363, wrong-code with throwing list-initializer


OK.

On Wed, May 16, 2018 at 2:44 PM, Marek Polacek <polacek@redhat.com> wrote:
> On Wed, May 16, 2018 at 01:53:50PM -0400, Jason Merrill wrote:
>> You should be able to avoid duplication here by using cp_get_callee
>> rather than *_FN.
>
> Even better, thanks!
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2018-05-16  Marek Polacek  <polacek@redhat.com>
>
>         PR c++/85363
>         * call.c (set_flags_from_callee): Handle AGGR_INIT_EXPRs too.
>         * tree.c (bot_manip): Call set_flags_from_callee for
>         AGGR_INIT_EXPRs too.
>
>         * g++.dg/cpp0x/initlist-throw1.C: New test.
>         * g++.dg/cpp0x/initlist-throw2.C: New test.
>
> diff --git gcc/cp/call.c gcc/cp/call.c
> index 09a3618b007..4d04785f2b9 100644
> --- gcc/cp/call.c
> +++ gcc/cp/call.c
> @@ -319,15 +319,17 @@ build_call_n (tree function, int n, ...)
>  void
>  set_flags_from_callee (tree call)
>  {
> -  bool nothrow;
> -  tree decl = get_callee_fndecl (call);
> +  /* Handle both CALL_EXPRs and AGGR_INIT_EXPRs.  */
> +  tree decl = cp_get_callee_fndecl_nofold (call);
>
>    /* We check both the decl and the type; a function may be known not to
>       throw without being declared throw().  */
> -  nothrow = decl && TREE_NOTHROW (decl);
> -  if (CALL_EXPR_FN (call))
> -    nothrow |= TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (call))));
> -  else if (internal_fn_flags (CALL_EXPR_IFN (call)) & ECF_NOTHROW)
> +  bool nothrow = decl && TREE_NOTHROW (decl);
> +  tree callee = cp_get_callee (call);
> +  if (callee)
> +    nothrow |= TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (callee)));
> +  else if (TREE_CODE (call) == CALL_EXPR
> +          && internal_fn_flags (CALL_EXPR_IFN (call)) & ECF_NOTHROW)
>      nothrow = true;
>
>    if (!nothrow && at_function_scope_p () && cfun && cp_function_chain)
> diff --git gcc/cp/tree.c gcc/cp/tree.c
> index ecb88df23b9..db81da91676 100644
> --- gcc/cp/tree.c
> +++ gcc/cp/tree.c
> @@ -2987,7 +2987,7 @@ bot_manip (tree* tp, int* walk_subtrees, void* data_)
>
>    /* Make a copy of this node.  */
>    t = copy_tree_r (tp, walk_subtrees, NULL);
> -  if (TREE_CODE (*tp) == CALL_EXPR)
> +  if (TREE_CODE (*tp) == CALL_EXPR || TREE_CODE (*tp) == AGGR_INIT_EXPR)
>      set_flags_from_callee (*tp);
>    if (data.clear_location && EXPR_HAS_LOCATION (*tp))
>      SET_EXPR_LOCATION (*tp, input_location);
> diff --git gcc/testsuite/g++.dg/cpp0x/initlist-throw1.C gcc/testsuite/g++.dg/cpp0x/initlist-throw1.C
> index e69de29bb2d..264c6c7a7a0 100644
> --- gcc/testsuite/g++.dg/cpp0x/initlist-throw1.C
> +++ gcc/testsuite/g++.dg/cpp0x/initlist-throw1.C
> @@ -0,0 +1,29 @@
> +// PR c++/85363
> +// { dg-do run { target c++11 } }
> +
> +int
> +init (int f)
> +{
> +  throw f;
> +}
> +
> +struct X {
> +  X (int f) : n {init (f)} {}
> +  int n;
> +};
> +
> +struct P {
> +  X x{20};
> +};
> +
> +int
> +main ()
> +{
> +  try {
> +    P p {};
> +  }
> +  catch (int n) {
> +    return 0;
> +  }
> +  return 1;
> +}
> diff --git gcc/testsuite/g++.dg/cpp0x/initlist-throw2.C gcc/testsuite/g++.dg/cpp0x/initlist-throw2.C
> index e69de29bb2d..2bb05834d9e 100644
> --- gcc/testsuite/g++.dg/cpp0x/initlist-throw2.C
> +++ gcc/testsuite/g++.dg/cpp0x/initlist-throw2.C
> @@ -0,0 +1,33 @@
> +// PR c++/85363
> +// { dg-do run { target c++11 } }
> +
> +int
> +init (int f)
> +{
> +  throw f;
> +}
> +
> +struct X {
> +  X () : n {init (42)} {}
> +  int n;
> +};
> +
> +struct P {
> +  struct R {
> +    struct Q {
> +      X x = {};
> +    } q;
> +  } r;
> +};
> +
> +int
> +main ()
> +{
> +  try {
> +    P p {};
> +  }
> +  catch (int n) {
> +    return 0;
> +  }
> +  return 1;
> +}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]