From: Harald Anlauf <anlauf@gmx.de>
To: Rimvydas Jasinskas <rimvydasjas@gmail.com>
Cc: Thomas Schwinge <thomas@codesourcery.com>,
Rimvydas Jasinskas via Fortran <fortran@gcc.gnu.org>,
fortran <fortran@gcc.gnu.org>
Subject: Re: Support for WEAK attribute, part 2
Date: Thu, 16 Feb 2023 22:50:21 +0100 [thread overview]
Message-ID: <trinity-bb49b3d4-7455-4c7b-89d9-a9a857e68651-1676584221172@3c-app-gmx-bs44> (raw)
In-Reply-To: <CAFmAMQ04TtgTu1oZnzFSWw9pkgK0tRmt8ptpx1Xz4K0gjDCaag@mail.gmail.com>
Hi Rimvydas,
> Gesendet: Mittwoch, 15. Februar 2023 um 21:58 Uhr
> Von: "Rimvydas Jasinskas" <rimvydasjas@gmail.com>
>
> On Tue, Feb 14, 2023 at 9:55 PM Harald Anlauf <anlauf@gmx.de> wrote:
> > >>> There is one thing I cannot test, which is the handling of weak symbols
> > >>> on other platforms. A quick glance at the C testcases suggests that
> > >>> someone with access to either an NVPTX or MingGW target might tell
> > >>> whether that particular target should be excluded.
> While working on part 2 patch for weak variables I noticed that MingGW
> has quite different handling of weak symbols as weak externals between
> 32/64. I think adding "! { dg-skip-if "" { x86-64-*-mingw*} }" is
> needed to weak-1.f90 testcase, but I decided to wait for testsuite
> failure reports.
there are some MinGW users that will hopefully report back here soon.
> > > And, orthogonally: is '!GCC$ ATTRIBUTES weak' meant to be used only for
> > > subroutines (like in 'gfortran.dg/weak-1.f90') and also functions (I
> > > suppose; test case?), or also for weak "data" in some way (which, for
> > > example, in the C world then evaluates to a zero-address unless actually
> > > defined)?
> Weak zero-addressed "data" is more complicated between targets, I do
> not see a need for it.
> Functions are handled the same as subroutines, I had testcase for it,
> but decided to deal with fallout from weak-1.f90 first:
> $ cat gcc/testsuite/gfortran.dg/weak-2.f90
> ! { dg-do compile }
> ! { dg-require-weak "" }
> ! { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?impl" } }
> integer function impl()
> implicit none
> !GCC$ ATTRIBUTES weak :: impl
> end function
Yes, this works. I tried that before pushing.
> > Syntax and use of the WEAK directive.
> > !DIR$ WEAK procedure_name[, procedure_name] ...
> > !DIR$ WEAK procedure_name= stub_name[, procedure_name1= stub_name1] ...
> > stub_name
> > A stub procedure that exists in the code. The stub_name will be
> > called if a strong reference does not exist for procedure_name. The
> > stub_name procedure must have the same name and dummy argument list as
> > procedure_name.
> I think the same for procedure_name=stub_name can be achieved with
> bind(c,'sym') already without caring about symbol name mangling:
> $ cat gcc/testsuite/gfortran.dg/weak-6.f90
> ! { dg-do compile }
> ! { dg-require-weak "" }
> ! { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?bar__" } }
> integer function impl() bind(c,name='bar__')
> implicit none
> !GCC$ ATTRIBUTES weak :: impl
> end function
This does work indeed. It would be good to add these examples to
the documentation for reference in a subsequent patch.
> > I'm not sure whether we need to support weak symbols other than
> > procedures in gfortran. Maybe Rimvydas can comment on this.
> In 2nd part patch I was thinking to add support for weak global
> variables (like in modules):
> --- a/gcc/fortran/trans-decl.cc
> +++ b/gcc/fortran/trans-decl.cc
> @@ -814,6 +814,10 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
> && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
> set_decl_tls_model (decl, decl_default_tls_model (decl));
>
> + /* Mark weak variables. */
> + if (sym->attr.ext_attr & (1 << EXT_ATTR_WEAK))
> + declare_weak (decl);
> +
> gfc_finish_decl_attrs (decl, &sym->attr);
> }
>
> $ cat gcc/testsuite/gfortran.dg/weak-3.f90
> ! { dg-do compile }
> ! { dg-require-weak "" }
> ! { dg-skip-if "" { x86_64-*-mingw* } }
> ! { dg-skip-if "" { nvptx-*-* } }
> ! { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?__foo_MOD_abc" } }
> module foo
> implicit none
> !GCC$ ATTRIBUTES weak :: abc
> real :: abc(7)
> end module
>
> The catch is again scan-assembler issues with various symbol name
> manglings. Maybe just to add testcase without scan-assembler to check
> if testcase is not rejected?
Either that, or restricting those testcases by adding:
! { dg-skip-if "" { nvptx-*-* } }
! { dg-skip-if "" { x86_64-*-mingw* } }
> Currently already rejected are:
> $ cat gcc/testsuite/gfortran.dg/weak-4.f90
> ! { dg-do compile }
> ! { dg-require-weak "" }
> program foo ! { dg-error "weak declaration of 'foo' must be public" "" }
> implicit none
> !GCC$ ATTRIBUTES weak :: foo
> end program
Yes.
> $ cat gcc/testsuite/gfortran.dg/weak-9.f90
> ! { dg-do compile }
> ! { dg-require-weak "" }
> subroutine foo
> implicit none
> real :: abc ! { dg-error "weak declaration of 'abc' must be public" "" }
> !GCC$ ATTRIBUTES weak :: abc
> print *, abc
> contains
> subroutine bar ! { dg-error "weak declaration of 'bar' must be public" "" }
> !GCC$ ATTRIBUTES weak :: bar
> end subroutine
> end subroutine
>
> However error is not given if 'abc' is made a dummy argument or is not
> used, any ideas why?
At least for a dummy argument one can generate an error in
gfc_get_symbol_decl():
@@ -1549,6 +1552,14 @@ gfc_get_symbol_decl (gfc_symbol * sym)
|| (sym->module && sym->attr.if_source != IFSRC_DECL
&& sym->backend_decl));
+ if (sym->attr.dummy && (sym->attr.ext_attr & (1 << EXT_ATTR_WEAK)))
+ {
+ if (!sym->error)
+ gfc_error ("Symbol %qs at %L has the WEAK attribute but is a dummy "
+ "argument", sym->name, &sym->declared_at);
+ sym->error = 1;
+ }
+
if (sym->attr.dummy && sym->ns->proc_name->attr.is_bind_c
&& is_CFI_desc (sym, NULL))
{
(The setting of sym->error is done to suppress multiple errors
for the same line. Not sure if this is the best solution, but
it works.)
> $ cat gcc/testsuite/gfortran.dg/weak-8.f90
> ! { dg-do compile }
> ! { dg-require-weak "" }
> module foo
> implicit none
> real :: a,b
> common /c/ a,b
> !GCC$ ATTRIBUTES weak :: c
> ! { dg-error "has no IMPLICIT type" "common" {target *-*-*} .-1 }
> end module
Well, here 'c' is an undeclared variable.
(The syntax would be different anyway, see e.g. SAVE).
> I suspect declaring common blocks weak should be explicitly rejected
> somewhere in resolve.cc, since .comm + .weak (should?) be illegal:
> $ cat cweak.s
> .comm c_,8,16
> .weak c_
> $ as cweak.s
> cweak.s: Assembler messages:
> cweak.s: Error: symbol `c_' can not be both weak and common
> However in weak-8.f90 error depends if "implicit none" is given.
Commenting out the "implicit none", I see in the assembler:
.comm c_,8,16
.weak __foo_MOD_c
which confirms that variable "c" and common /c/ are different beasts.
> Also what to do with declarations like:
> $ cat gcc/testsuite/gfortran.dg/weak-7.f90
> ! { dg-do compile }
> ! { dg-require-weak "" }
> module foo
> implicit none
> !GCC$ ATTRIBUTES weak :: foo
> integer :: ijk
> end module
>
> Currently it is silently accepted and has no effect. I would see it
> useful if such a declaration would make all publicly visible variables
> and procedures to be marked as weak (as a shorthand, instead of
> declaring each variable/procedure as weak). But I have not looked up
> how to do this yet.
Yes, it makes sense to either diagnose it or apply it
to publicly visible variables and procedures. This
appears to be more work.
> Similar issue is with other attributes too:
> module aaa
> !GCC$ ATTRIBUTES fastcall :: aaa
> !GCC$ ATTRIBUTES deprecated :: aaa
> !GCC$ ATTRIBUTES noinline :: aaa
> integer :: ijk
> end module
>
> If such declarations to be explicitly rejected/diagnosed (say under
> -Wattributes) some kind of table like in
> gcc/c-family/c-attribs.cc:c_common_attribute_table[] would be needed,
> where false/true indicate if attribute could be applied for a given
> use case.
> On a side note, could someone check if cdecl/stdcall/fastcall actually
> affect code generation on windows targets?
Could you please open a PR for handling and tracking this?
This mail has already gotten quite long.
> In the end, the most problematic issue is useability of GCC directives
> in user codes. As more and more attributes or other directives get
> supported it tends to create chaos in how users (try to) make use of
> these attributes. The NO_ARGS_CHECK is/was a good example. The mpi
> libraries generate bindings on the fly after checking if this
> attribute is supported. Other projects use cpp preprocessor "#if
> __GNUC__ > 8", sometimes even in wrong ways like "#if __GFORTRAN__ >
> 10" or explicit rules like "cc -E -P -traditional -xc foo.F90 >
> foo.f90 && $(FC) -c foo.f90" while not suspecting that system cc(1)
> and say gfortran-10 could be of different versions on given host
> environment (or even not gfortran), specially on systems where cc(1)
> is 4.8.5. The __GFORTRAN__ macro defined to '1' seems like a lost
> opportunity to use it as a compiler version major or maybe even
> currently active Fortran standard level.
> Issue is that unlike C frontends, gfortran hard rejects compilation
> units containing unknown attributes or slightly expanded new syntax:
> $ cat cold.f90
> subroutine foo
> !GCC$ ATTRIBUTES cold :: foo
> end subroutine
> $ gfortran -c cold.f90
> Error: Unknown attribute in !GCC$ ATTRIBUTES statement at (1)
Same here: please open a PR on this.
> I have a patch that adds -fallow-ignored-directive to demote such
> errors to warnings, but it looks too ugly and does not solve the
> useability issues by itself.
> What about adding support for conditional directives based on the
> compiler version? Simple "!GCC$ if(13+) ATTRIBUTES weak :: foo" would
> in theory allow to keep the same sourcecode with different compiler
> versions and not require cpp preprocessor tricks once this feature
> "age" enough.
This does look a bit strange to me, and I do not see the real
point. It is possible to use the accompanying preprocessor to
generate gcc/gfortran version dependent stuff (works for me):
#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 1300
#define GCC_ATTRIBUTES_WEAK GCC$ ATTRIBUTES weak
#endif
!GCC_ATTRIBUTES_WEAK :: foo
(The system gcc/cpp version is lower).
Cheers,
Harald
> Any thoughts?
>
> Regards,
> Rimvydas
>
next prev parent reply other threads:[~2023-02-16 21:50 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-10 5:42 Support for NOINLINE attribute Rimvydas Jasinskas
2023-02-10 8:24 ` Steve Kargl
2023-02-10 8:38 ` Rimvydas Jasinskas
2023-02-10 18:53 ` Steve Kargl
2023-02-10 21:07 ` Harald Anlauf
2023-02-10 21:16 ` Steve Kargl
2023-02-10 22:16 ` Rimvydas Jasinskas
2023-02-11 21:26 ` Harald Anlauf
2023-02-12 6:59 ` Rimvydas Jasinskas
2023-02-12 21:28 ` Harald Anlauf
2023-02-13 17:50 ` Harald Anlauf
2023-02-14 9:35 ` nvptx: Adjust 'scan-assembler' in 'gfortran.dg/weak-1.f90' (was: Support for NOINLINE attribute) Thomas Schwinge
2023-02-14 19:55 ` Harald Anlauf
2023-02-15 20:58 ` Support for WEAK attribute, part 2 Rimvydas Jasinskas
2023-02-16 21:50 ` Harald Anlauf [this message]
2023-02-23 13:55 ` Rimvydas Jasinskas
2023-02-23 20:53 ` Harald Anlauf
2023-02-24 5:16 ` Rimvydas Jasinskas
2023-02-24 22:03 ` Harald Anlauf
2023-03-28 21:06 ` Enable 'gfortran.dg/weak-2.f90' for nvptx target (was: Support for WEAK attribute, part 2) Thomas Schwinge
2023-02-18 20:35 ` Support for NOINLINE attribute Bernhard Reutner-Fischer
2023-02-24 7:19 ` Bernhard Reutner-Fischer
2023-02-24 12:02 ` Rimvydas Jasinskas
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=trinity-bb49b3d4-7455-4c7b-89d9-a9a857e68651-1676584221172@3c-app-gmx-bs44 \
--to=anlauf@gmx.de \
--cc=fortran@gcc.gnu.org \
--cc=rimvydasjas@gmail.com \
--cc=thomas@codesourcery.com \
/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).