On Fri, Aug 1, 2025 at 4:55 AM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> Set a tentative TLS model in grokdeclarator and update DECL_TLS_MODEL
> with the default TLS access model after a TLS variable has been fully
> processed if the default TLS access model is stronger.
>
> gcc/c/
>
>         PR c/107419
>         * c-decl.cc (grokdeclarator): Add a pointer to bool argument to
>         indicate if DECL_TLS_MODEL should be updated later.  Set a
>         tentative TLS model if DECL_TLS_MODEL will be updated later.
>         (start_decl): Pass a pointer to bool argument to grokdeclarator.
>         Call set_decl_tls_model to update DECL_TLS_MODEL with the default
>         TLS access model after calling grokdeclarator if the default TLS
>         access model is stronger.
>
> gcc/testsuite/
>
>         PR c/107419
>         * c-c++-common/tls-attr-common.c: New test.
>         * c-c++-common/tls-attr-le-pic.c: Likewise.
>         * c-c++-common/tls-attr-le-pie.c: Likewise.
>
> Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
> ---
>  gcc/c/c-decl.cc                              | 33 +++++++++++++++++---
>  gcc/testsuite/c-c++-common/tls-attr-common.c | 17 ++++++++++
>  gcc/testsuite/c-c++-common/tls-attr-le-pic.c | 15 +++++++++
>  gcc/testsuite/c-c++-common/tls-attr-le-pie.c | 15 +++++++++
>  4 files changed, 76 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/c-c++-common/tls-attr-common.c
>  create mode 100644 gcc/testsuite/c-c++-common/tls-attr-le-pic.c
>  create mode 100644 gcc/testsuite/c-c++-common/tls-attr-le-pie.c
>
> diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
> index 4bef43864a1..c07ba82689c 100644
> --- a/gcc/c/c-decl.cc
> +++ b/gcc/c/c-decl.cc
> @@ -685,7 +685,8 @@ static tree c_make_fname_decl (location_t, tree, int);
>  static tree grokdeclarator (const struct c_declarator *,
>                             struct c_declspecs *,
>                             enum decl_context, bool, tree *, tree *, tree *,
> -                           bool *, enum deprecated_states);
> +                           bool *, enum deprecated_states,
> +                           bool * = nullptr);
>  static tree grokparms (struct c_arg_info *, bool);
>  static void layout_array_type (tree);
>  static const char *header_for_builtin_fn (tree);
> @@ -5603,9 +5604,10 @@ start_decl (struct c_declarator *declarator, struct 
> c_declspecs *declspecs,
>    else if (lookup_attribute ("deprecated", attributes))
>      deprecated_state = DEPRECATED_SUPPRESS;
>
> +  bool tls_model_p = false;
>    decl = grokdeclarator (declarator, declspecs,
>                          NORMAL, initialized, NULL, &attributes, &expr, NULL,
> -                        deprecated_state);
> +                        deprecated_state, &tls_model_p);
>    if (!decl || decl == error_mark_node)
>      return NULL_TREE;
>
> @@ -5722,6 +5724,15 @@ start_decl (struct c_declarator *declarator, struct 
> c_declspecs *declspecs,
>         DECL_EXTERNAL (decl) = !DECL_EXTERNAL (decl);
>      }
>
> +  if (tls_model_p)
> +    {
> +      // tls_model attribute can set a stronger TLS access model.
> +      tls_model model = DECL_TLS_MODEL (decl);
> +      tls_model default_model = decl_default_tls_model (decl);
> +      if (default_model > model)
> +       set_decl_tls_model (decl, default_model);
> +    }
> +
>    if (TREE_CODE (decl) == FUNCTION_DECL
>        && DECL_DECLARED_INLINE_P (decl)
>        && DECL_UNINLINABLE (decl)
> @@ -6819,7 +6830,8 @@ grokdeclarator (const struct c_declarator *declarator,
>                 struct c_declspecs *declspecs,
>                 enum decl_context decl_context, bool initialized, tree *width,
>                 tree *decl_attrs, tree *expr, bool *expr_const_operands,
> -               enum deprecated_states deprecated_state)
> +               enum deprecated_states deprecated_state,
> +               bool *tls_model_p)
>  {
>    tree type = declspecs->type;
>    bool threadp = declspecs->thread_p;
> @@ -8312,7 +8324,20 @@ grokdeclarator (const struct c_declarator *declarator,
>           }
>
>         if (threadp)
> -         set_decl_tls_model (decl, decl_default_tls_model (decl));
> +         {
> +           tls_model model;
> +           if (tls_model_p)
> +             {
> +               // NB: Set a tentative TLS model to avoid tls_model
> +               // attribute warnings due to lack of thread storage
> +               // duration.  It will be updated later.
> +               model = TLS_MODEL_REAL;
> +               *tls_model_p = true;
> +             }
> +           else
> +             model = decl_default_tls_model (decl);
> +           set_decl_tls_model (decl, model);
> +         }
>        }
>
>      if ((storage_class == csc_extern
> diff --git a/gcc/testsuite/c-c++-common/tls-attr-common.c 
> b/gcc/testsuite/c-c++-common/tls-attr-common.c
> new file mode 100644
> index 00000000000..07c3fd2d440
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/tls-attr-common.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-require-effective-target tls } */
> +/* { dg-options "-O2 -fno-pic -fdump-ipa-whole-program" } */
> +/* { dg-additional-options "-mno-direct-extern-access" } */
> +
> +__attribute__((common))
> +__thread int i;
> +
> +int *
> +foo (void)
> +{
> +  return &i;
> +}
> +
> +/* tls_model should be tls-initial-exec due to common attribute.  */
> +/* { dg-final { scan-ipa-dump "Varpool flags: tls-initial-exec" 
> "whole-program" } } */
> diff --git a/gcc/testsuite/c-c++-common/tls-attr-le-pic.c 
> b/gcc/testsuite/c-c++-common/tls-attr-le-pic.c
> new file mode 100644
> index 00000000000..c02df6919f1
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/tls-attr-le-pic.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-require-effective-target tls } */
> +/* { dg-options "-O2 -fpic -fdump-ipa-whole-program" } */
> +
> +__attribute__ ((tls_model ("local-exec"))) __thread int i;
> +
> +int *
> +foo (void)
> +{
> +  return &i;
> +}
> +
> +/* tls_model should be local-exec due to tls_model attribute.  */
> +/* { dg-final { scan-ipa-dump "Varpool flags: tls-local-exec" 
> "whole-program" } } */
> diff --git a/gcc/testsuite/c-c++-common/tls-attr-le-pie.c 
> b/gcc/testsuite/c-c++-common/tls-attr-le-pie.c
> new file mode 100644
> index 00000000000..b8ef7840d79
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/tls-attr-le-pie.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile { target { tls && pie } } } */
> +/* { dg-options "-O2 -fPIE -fdump-ipa-whole-program" } */
> +
> +extern const int afoo[3];
> +
> +__thread const int *pfoo __attribute__ ((tls_model ("initial-exec"))) = afoo;
> +
> +const int **
> +ppfoo (void)
> +{
> +  return &pfoo;
> +}
> +
> +/* tls_model should be local-exec due to -fPIE.  */
> +/* { dg-final { scan-ipa-dump "Varpool flags: initialized tls-local-exec" 
> "whole-program" } } */
> --
> 2.50.1
>

PING.

-- 
H.J.

Reply via email to