https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34165

--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Matt Turner <[email protected]>:

https://gcc.gnu.org/g:2104f1a937eb8c7a701fb7338bee9bfb5f72f902

commit r17-6145-g2104f1a937eb8c7a701fb7338bee9bfb5f72f902
Author: Matt Turner <[email protected]>
Date:   Wed Oct 28 11:55:37 2026 -0400

    c-family: Recompute TLS model of weak variables [PR c/125418]

    Since r16-3673 (C) and r16-3637 (C++) the front ends upgrade a TLS
    variable's access model to decl_default_tls_model as soon as its
    declaration has been processed.  If the variable becomes weak only
    afterwards, the model is chosen while the symbol still appears to bind
    locally.  A hidden extern TLS variable that is then made weak keeps a
    model that assumes it is defined in the same module, which is wrong for
    an undefined weak symbol: with local-exec the linker has no TLS segment
    offset to use.  This breaks static links of glibc on ia64, and on alpha
    when the linker lacks the fix for PR ld/34165.  glibc declares its
    _nl_current_LC_* variables as

      extern __thread struct __locale_data *const *_nl_current_LC_CTYPE
        attribute_hidden attribute_tls_model_ie;
      #pragma weak _nl_current_LC_CTYPE

    There are two ways the variable becomes weak too late.  #pragma weak is
    applied after the declaration has been processed.  And a redeclaration
    has its model chosen on its own, before duplicate_decls merges it with
    an earlier weak declaration and merge_weak makes it weak, and that model
    then replaces the earlier declaration's.  The second happens with
    __attribute__((weak)) on the earlier declaration as well as with
    #pragma weak.

    Add weak_decl_tls_model, which recomputes the default model of a weak
    TLS variable and lowers the model if the new default is weaker.  An
    explicit tls_model attribute remains a lower bound, as it is when the
    declaration is first processed, so the example above ends up
    initial-exec rather than local-exec, and an explicit local-exec is left
    alone.  Call it from apply_pragma_weak, and from duplicate_decls in both
    front ends once a merged variable is weak.  To read the attribute, split
    the string matching out of handle_tls_model_attribute, and make that
    function drop an attribute whose argument is not a string once it has
    diagnosed it, so a tls_model attribute left on a declaration always has
    a string argument.

    apply_pragma_weak recomputes nothing for "#pragma weak sym = target".
    That makes the symbol an alias defined in this translation unit, so it
    binds no less locally than before, but decl_default_tls_model cannot see
    that yet and would treat it as weak undefined.  By the time a
    redeclaration is merged it can, so the alias keeps its model.  The test
    for this scans the early visibility dump, because the whole-program
    visibility pass upgrades the model of an attribute-free variable again
    and would hide the difference.

    gcc/c-family/ChangeLog:

            PR c/125418
            * c-attribs.cc (parse_tls_model): New function, split out of...
            (handle_tls_model_attribute): ...here.  Use it.  Do not add the
            attribute if its argument is not a string.
            (weak_decl_tls_model): New function.
            * c-common.h (parse_tls_model, weak_decl_tls_model): Declare.
            * c-pragma.cc (apply_pragma_weak): Call weak_decl_tls_model after
            declaring a symbol weak.

    gcc/c/ChangeLog:

            PR c/125418
            * c-decl.cc (merge_decls): Call weak_decl_tls_model for a weak
            thread-local variable.

    gcc/cp/ChangeLog:

            PR c/125418
            * decl.cc (duplicate_decls): Call weak_decl_tls_model for a weak
            thread-local variable.

    gcc/testsuite/ChangeLog:

            PR c/125418
            * c-c++-common/tls-pragma-weak-1.c: New test.
            * c-c++-common/tls-pragma-weak-2.c: New test.
            * c-c++-common/tls-pragma-weak-3.c: New test.
            * c-c++-common/tls-pragma-weak-4.c: New test.
            * gcc.dg/tls/pragma-weak-alias.c: New test.

Reply via email to