From: Jason Merrill <jason@redhat.com>
To: Jan Hubicka <hubicka@kam.mff.cuni.cz>,
gcc-patches@gcc.gnu.org, rguenther@suse.de
Subject: Re: Add fnspec attributes to cxa_* functions
Date: Fri, 24 Jun 2022 10:21:32 -0400 [thread overview]
Message-ID: <1910733a-85c3-cd8e-dc08-794efc98977e@redhat.com> (raw)
In-Reply-To: <YrRxxpA7WpvC+aPP@kam.mff.cuni.cz>
On 6/23/22 09:59, Jan Hubicka via Gcc-patches wrote:
Note that your email subject line is missing "[PATCH]" and a component
tag like "c++:".
> this patch adds fnspecs for cxa_* functions in except.cc. Main goal is to make
> modref to see proper side-effects of functions which may throw. So in general
> we get
> - cxa_allocate_exception
> which gets the same annotations as malloc (since it is kind of same thing)
> - cxa_free_exception
> which gets the same annotations as free
> - cxa_throw which is marked as const except for first parameter which is believed
> that it makes it escape (which is necessary) and modify (which is not necessary
> but it would matter inly if we would like to do constant propagation across
> EH edges.
Makes sense.
> gcc/cp/ChangeLog:
>
> 2022-06-23 Jan Hubicka <hubicka@ucw.cz>
>
> * except.cc (declare_library_fn_1): Add fnspec parameter.
> (declare_library_fn): Add fnspec parameter.
> (do_allocate_exception): Declare fnspecs.
> (do_free_exception): Declare fnspecs.
> (build_throw): Declare fnspecs.
>
> gcc/testsuite/ChangeLog:
>
> 2022-06-23 Jan Hubicka <hubicka@ucw.cz>
>
> * g++.dg/opt/eh6.C: New test.
> * g++.dg/tree-ssa/kill.C: New test.
>
> diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc
> index da0a65c613d..bb9a5aee6da 100644
> --- a/gcc/cp/except.cc
> +++ b/gcc/cp/except.cc
> @@ -133,13 +133,14 @@ build_exc_ptr (void)
> }
>
> /* Declare an exception ABI entry point called NAME.
> - ECF are the library flags, RTYPE the return type and ARGS[NARGS]
> + ECF are the library flags, FNSPEC is the attr "fn spec" string (or NULL),
It might be helpful to refer to attr_fnspec or attr-fnspec.h, since
that's where I found the documentation for that string? OK either way.
> + RTYPE the return type and ARGS[NARGS]
> the parameter types. We return the DECL -- which might be one
> found via the symbol table pushing, if the user already declared
> it. If we pushed a new decl, the user will see it. */
>
> static tree
> -declare_library_fn_1 (const char *name, int ecf,
> +declare_library_fn_1 (const char *name, int ecf, const char *fnspec,
> tree rtype, int nargs, tree args[])
> {
> tree ident = get_identifier (name);
> @@ -150,6 +151,14 @@ declare_library_fn_1 (const char *name, int ecf,
> for (unsigned ix = nargs; ix--;)
> arg_list = tree_cons (NULL_TREE, args[ix], arg_list);
> tree fntype = build_function_type (rtype, arg_list);
> + if (fnspec)
> + {
> + tree attr_args = build_tree_list (NULL_TREE,
> + build_string (strlen (fnspec), fnspec));
> + tree attrs = tree_cons (get_identifier ("fn spec"),
> + attr_args, TYPE_ATTRIBUTES (fntype));
> + fntype = build_type_attribute_variant (fntype, attrs);
> + }
> tree res = push_library_fn (ident, fntype, except, ecf);
>
> return res;
> @@ -157,7 +166,8 @@ declare_library_fn_1 (const char *name, int ecf,
>
> /* Find or declare a function NAME, returning RTYPE, taking a single
> parameter PTYPE, with an empty exception specification. ECF are the
> - library fn flags. If TM_ECF is non-zero, also find or create a
> + library fn flags. FNSPEC is the attr "fn spec" string (or NULL).
> + If TM_ECF is non-zero, also find or create a
> transaction variant and record it as a replacement, when flag_tm is
> in effect.
>
> @@ -167,9 +177,10 @@ declare_library_fn_1 (const char *name, int ecf,
>
> static tree
> declare_library_fn (const char *name, tree rtype, tree ptype,
> - int ecf, int tm_ecf)
> + int ecf, int tm_ecf, const char *fnspec = NULL)
> {
> - tree res = declare_library_fn_1 (name, ecf, rtype, ptype ? 1 : 0, &ptype);
> + tree res = declare_library_fn_1 (name, ecf, fnspec,
> + rtype, ptype ? 1 : 0, &ptype);
> if (res == error_mark_node)
> return res;
>
> @@ -177,7 +188,7 @@ declare_library_fn (const char *name, tree rtype, tree ptype,
> {
> char *tm_name = concat ("_ITM_", name + 2, NULL_TREE);
>
> - tree tm_fn = declare_library_fn_1 (tm_name, ecf | tm_ecf, rtype,
> + tree tm_fn = declare_library_fn_1 (tm_name, ecf | tm_ecf, fnspec, rtype,
> ptype ? 1 : 0, &ptype);
> free (tm_name);
> if (tm_fn != error_mark_node)
> @@ -547,7 +558,8 @@ do_allocate_exception (tree type)
> allocate_exception_fn
> = declare_library_fn ("__cxa_allocate_exception",
> ptr_type_node, size_type_node,
> - ECF_NOTHROW | ECF_MALLOC | ECF_COLD, ECF_TM_PURE);
> + ECF_NOTHROW | ECF_MALLOC | ECF_COLD, ECF_TM_PURE,
> + "mc");
>
> return cp_build_function_call_nary (allocate_exception_fn,
> tf_warning_or_error,
> @@ -565,7 +577,8 @@ do_free_exception (tree ptr)
> free_exception_fn
> = declare_library_fn ("__cxa_free_exception",
> void_type_node, ptr_type_node,
> - ECF_NOTHROW | ECF_LEAF, ECF_TM_PURE);
> + ECF_NOTHROW | ECF_LEAF, ECF_TM_PURE,
> + ".co ");
>
> return cp_build_function_call_nary (free_exception_fn,
> tf_warning_or_error, ptr, NULL_TREE);
> @@ -653,11 +666,13 @@ build_throw (location_t loc, tree exp)
>
> throw_fn = declare_library_fn_1 ("__cxa_throw",
> ECF_NORETURN | ECF_COLD,
> + ".c. X X ",
> void_type_node, 3, args);
> if (flag_tm && throw_fn != error_mark_node)
> {
> tree itm_fn = declare_library_fn_1 ("_ITM_cxa_throw",
> ECF_NORETURN | ECF_COLD,
> + ".c. X X ",
> void_type_node, 3, args);
> if (itm_fn != error_mark_node)
> {
> @@ -804,6 +819,7 @@ build_throw (location_t loc, tree exp)
> {
> rethrow_fn = declare_library_fn_1 ("__cxa_rethrow",
> ECF_NORETURN | ECF_COLD,
> + ".c",
> void_type_node, 0, NULL);
> if (flag_tm && rethrow_fn != error_mark_node)
> apply_tm_attr (rethrow_fn, get_identifier ("transaction_pure"));
> diff --git a/gcc/testsuite/g++.dg/opt/eh6.C b/gcc/testsuite/g++.dg/opt/eh6.C
> new file mode 100644
> index 00000000000..fa891fb2559
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/opt/eh6.C
> @@ -0,0 +1,34 @@
> +// PR middle-end/106057
> +// { dg-do run }
> +// { dg-options "-O2" }
> +struct a {int a; int b;} a;
> +int b;
> +
> +__attribute__((noinline))
> +struct a maybethrow(int b)
> +{
> + if (!b)
> + throw(0);
> + return {0,0};
> +}
> +
> +void
> +test(int b)
> +{
> + a={1,1};
> + a=maybethrow(b);
> + a={0,0};
> +}
> +int
> +main()
> +{
> + try {
> + test(b);
> + }
> + catch(int) {
> + if (!a.a)
> + __builtin_abort ();
> + }
> + return 0;
> +}
> +
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/kill.C b/gcc/testsuite/g++.dg/tree-ssa/kill.C
> new file mode 100644
> index 00000000000..bee58cd91fe
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/tree-ssa/kill.C
> @@ -0,0 +1,20 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 -fdump-tree-modref1" } */
> +__attribute__ ((noinline))
> +void test(int a)
> +{
> + if (a)
> + throw (1);
> +}
> +int mem;
> +void link_error ();
> +int
> +main()
> +{
> + mem = 0;
> + test (0);
> + if (mem)
> + link_error ();
> + return 0;
> +}
> +// { dg-final { scan-tree-dump-not "modref done with result: tracked." "modref1" } }
>
prev parent reply other threads:[~2022-06-24 14:21 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-23 13:59 Jan Hubicka
2022-06-24 8:33 ` Richard Biener
2022-06-24 14:21 ` Jason Merrill [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1910733a-85c3-cd8e-dc08-794efc98977e@redhat.com \
--to=jason@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hubicka@kam.mff.cuni.cz \
--cc=rguenther@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).