Bug 203066 - _Thread_local detection is broken with GCC < 4.9
Summary: _Thread_local detection is broken with GCC < 4.9
Status: Closed Not A Bug
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-standards (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-09-13 10:55 UTC by Raphael Kubo da Costa
Modified: 2015-09-16 14:56 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Raphael Kubo da Costa freebsd_committer 2015-09-13 10:55:02 UTC
sys/cdefs.h contains:

    #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L || defined(lint)
    ...
    #if !__has_extension(c_thread_local)
    ...
    #if /* (defined(__cplusplus) && __cplusplus >= 201103L) || */ \
        __has_extension(cxx_thread_local)
    #define _Thread_local           thread_local
    #else
    #define _Thread_local           __thread
    #endif
    #endif

However, _Thread_local support has only been added to GCC in the 4.9 series, so "#include <runetype.h>" fails with both `gcc47 -std=gnu11' and `gcc48 -std=gnu11':

    /usr/include/runetype.h:92:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'const'
    /usr/include/runetype.h: In function '__getCurrentRuneLocale':
    /usr/include/runetype.h:96:6: error: '_ThreadRuneLocale' undeclared (first use in this function)
    /usr/include/runetype.h:96:6: note: each undeclared identifier is reported only once for each function it appears in

A consequence of this is that some ports may fail to build; for example, devel/cmake with lang/gcc (bug#200969, comment #11).
Comment 1 Ed Schouten freebsd_committer 2015-09-13 11:16:26 UTC
Hi Raphael,

Even though I agree that this isn't nice, I'm inclined to say that this is a "won't fix".

What happens here is that you're instructing the compiler to build a source file in C11 mode, using an (outdated) compiler that does not implement C11. It is wrong for the compiler to set __STDC_VERSION__ to 201112L, even though it does not implement that version of the standard in the first place. Keep in mind that this is not some kind of esoteric feature of the standard we're using -- it's one of the core features introduced in C11.

In other words, simply don't use GCC < 4.9 in combination with -std=gnu11. It's broken.

That said, I don't feel about this too strongly. If someone else is willing to work on this, please reopen. :-)

Thanks,
Ed
Comment 2 Konstantin Belousov freebsd_committer 2015-09-13 11:48:25 UTC
(In reply to Ed Schouten from comment #1)
Part of the problem is that default gcc from ports is 4.8.

It does not cost much to add gcc version check and avoid the problem.
Comment 3 Ed Schouten freebsd_committer 2015-09-13 11:50:33 UTC
(In reply to Konstantin Belousov from comment #2)

Ports also has a USE_CSTD knob that can be used to use different dialects of C. Ports could easily use GCC 4.9 in case GCC is required and USE_CSTD is set to C11.
Comment 4 commit-hook freebsd_committer 2015-09-16 14:56:56 UTC
A commit references this bug:

Author: rakuco
Date: Wed Sep 16 14:56:08 UTC 2015
New revision: 397068
URL: https://svnweb.freebsd.org/changeset/ports/397068

Log:
  Add upstream patch to fix the build with GCC 4.6, 4.7 and 4.8.

  runetype.h uses _Thread_local, and if we pass -std=c11 or -std=gnu11 to GCC
  the header expects it to be supported as part of the language and does not
  make it a typedef or something else.

  Since GCC only started supporting _Thread_local with the 4.9 series,
  building CMake with, say, lang/gcc (which is 4.8) fails:

      /usr/include/runetype.h:92:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'const'
      /usr/include/runetype.h: In function '__getCurrentRuneLocale':
      /usr/include/runetype.h:96:6: error: '_ThreadRuneLocale' undeclared (first use in this function)
      /usr/include/runetype.h:96:6: note: each undeclared identifier is reported only once for each function it appears in

  The upstream patch adds a test for _Thread_local and uses C99 instead of C11
  if it fails.

  PR:		203066

Changes:
  head/devel/cmake/files/patch-git_ffa6f057