LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 23156 - gcc5 defines __GLIBCXX_TYPE_INT_N_0 and __GLIBCXX_BITSIZE_INT_N_0 in C++ mode
Summary: gcc5 defines __GLIBCXX_TYPE_INT_N_0 and __GLIBCXX_BITSIZE_INT_N_0 in C++ mode
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: C++ (show other bugs)
Version: unspecified
Hardware: PC Linux
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-04-07 21:09 PDT by John Steele Scott
Modified: 2016-07-21 02:55 PDT (History)
4 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Steele Scott 2015-04-07 21:09:55 PDT
g++-5 (Ubuntu 5-20150329-1ubuntu11~14.04) 5.0.0 20150329 (experimental) [trunk revision 221764]
Ubuntu clang version 3.6.1-svn232753-1~exp1 (branches/release_36) (based on LLVM 3.6.1)

jscott@citra:/tmp$ cat int128.cpp 
#include <type_traits>

int main ()
{
  static_assert(std::is_integral<__int128>::value, "__int128 should be integral");
  return 0;
}
jscott@citra:/tmp$ g++-5 -std=gnu++11 -c int128.cpp 
jscott@citra:/tmp$ clang++ -std=gnu++11 -c int128.cpp 
int128.cpp:5:3: error: static_assert failed "__int128 should be integral"
  static_assert(std::is_integral<__int128>::value, "__int128 should be integral");
  ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.


With GCC 4.9, this program builds fine.

This breakage appears to be due to the following GCC change:
http://permalink.gmane.org/gmane.comp.gcc.cvs/165545

In GCC 4.9 there was a symbol _GLIBCXX_USE_INT128 defined somewhere (maybe in some config header? I'm not sure) which let this work. With GCC 5, __GLIBCXX_TYPE_INT_N_0 and __GLIBCXX_BITSIZE_INT_N_0 are built into the preprocessor, and must be defined to let type_traits acknowledge __int128 as an integer.


I discovered this issue due to some code which uses GCC's SIMD Mersenne Twister extension. A minimal example is:

#include <ext/random>

typedef __gnu_cxx::simd_fast_mersenne_twister_engine<
  unsigned __int128,
  /* The following parameters all relate to Mersenne Twister internal
   * state. These are thoughtlessly copied from the definition of sfmt19937.
   */
  19937, 122,
  18, 1, 11, 1,
  0xdfffffefU, 0xddfecb7fU,
  0xbffaffffU, 0xbffffff6U,
  0x00000001U, 0x00000000U,
  0x00000000U, 0x13c9e684U>
sfmt19937_128;

int main ()
{
  sfmt19937_128 engine;
  auto value = engine();
}

Which fails to build with Clang 3.6 + libstdc++ 5.0 like:

jscott@citra:/tmp$ clang++ -std=gnu++11 random.cpp
In file included from random.cpp:1:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.0/../../../../include/c++/5.0.0/ext/random:67:7: error: static_assert failed "template argument substituting _UIntType not an unsigned integral type"
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
      ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
random.cpp:18:17: note: in instantiation of template class '__gnu_cxx::simd_fast_mersenne_twister_engine<unsigned __int128, 19937, 122, 18, 1, 11, 1, 3758096367, 3724462975, 3220897791, 3221225462, 1, 0, 0,
      331998852>' requested here
  sfmt19937_128 engine;
                ^
1 error generated.


With the following definitions added to the top of the file it builds. Haven't tried a real example to see if it works though.

"""
#define __GLIBCXX_BITSIZE_INT_N_0 128
#define __GLIBCXX_TYPE_INT_N_0 __int128
"""
Comment 1 John Steele Scott 2015-09-10 19:59:09 PDT
Still an issue with 3.7.0-svn246299-1~exp1.
Comment 2 John Steele Scott 2016-04-06 02:13:30 PDT
This is still a problem with clang 3.8.0.
Comment 3 Yaron Keren 2016-07-20 09:44:23 PDT
this is still a bug with trunk. g++ in C++ mode defines __GLIBCXX_TYPE_INT_N_0 to __int128:

$ g++ -v
gcc version 5.2.1 20151031 (Ubuntu 5.2.1-23ubuntu1~14.04.2)
$ g++ -x c++ -dM -E - < /dev/null | grep __GLIBCXX_TYPE_INT_N_0
#define __GLIBCXX_TYPE_INT_N_0 __int128
$ g++ -dM -E - < /dev/null | grep __GLIBCXX_TYPE_INT_N_0
$

$ clang++ -v
clang version 3.9.0 (trunk 274529)
$ clang++ -x c++ -dM -E - < /dev/null | grep __GLIBCXX_TYPE_INT_N_0
$
Comment 4 Yaron Keren 2016-07-20 09:47:55 PDT
also,

$ g++ -x c++ -dM -E - < /dev/null | grep __GLIBCXX_BITSIZE_INT_N_0
#define __GLIBCXX_BITSIZE_INT_N_0 128
Comment 5 Yaron Keren 2016-07-21 02:55:14 PDT
g++ defines these in C++ gnu langaugae extensions mode only.

r276252