> Am 23.06.2022 um 16:00 schrieb Jan Hubicka via Gcc-patches > <gcc-patches@gcc.gnu.org>: > > Hi, > 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. > Looks OK to me, let’s see if Jason has any comments though. Richard > Honza > > gcc/cp/ChangeLog: > > 2022-06-23 Jan Hubicka <hubi...@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 <hubi...@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), > + 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" } }
Re: Add fnspec attributes to cxa_* functions
Richard Biener via Gcc-patches Fri, 24 Jun 2022 01:33:36 -0700
- Add fnspec attributes to cxa_* functions Jan Hubicka via Gcc-patches
- Re: Add fnspec attributes to cxa_* fun... Richard Biener via Gcc-patches
- Re: Add fnspec attributes to cxa_* fun... Jason Merrill via Gcc-patches