r179419 - tl; dr: Teach Clang to work around g++ changing its workaround to glibc's

Richard Smith richard-llvm at metafoo.co.uk
Fri Apr 12 15:11:07 PDT 2013


Author: rsmith
Date: Fri Apr 12 17:11:07 2013
New Revision: 179419

URL: http://llvm.org/viewvc/llvm-project?rev=179419&view=rev
Log:
tl;dr: Teach Clang to work around g++ changing its workaround to glibc's
implementation of C99's attempt to control the C++ standard. *sigh*


The C99 standard says that certain macros in <stdint.h>, such as SIZE_MAX,
should not be defined when the header is included in C++ mode, unless
__STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS are defined. The C++11 standard
says "Thanks, but no thanks" and C11 removed this rule, but various C library
implementations (such as glibc) follow C99 anyway.

g++ prior to 4.8 worked around the C99 / glibc behavior by defining
__STDC_*_MACROS in <cstdint>, which was incorrect, because <stdint.h> is
supposed to provide these macros too. g++ 4.8 works around it by defining
__STDC_*_MACROS in its builtin <stdint.h> header.

This change makes Clang act like g++ 4.8 in this regard: our <stdint.h> now
countermands any attempt by the C library to implement the undesired C99 rules,
by defining the __STDC_*_MACROS first. Unlike g++, we do this even in C++98
mode, since that was the intent of the C++ committee, matches the behavior
required in C11, and matches our built-in implementation of <stdint.h>.

Modified:
    cfe/trunk/lib/Headers/stdint.h
    cfe/trunk/test/Headers/cxx11.cpp

Modified: cfe/trunk/lib/Headers/stdint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/stdint.h?rev=179419&r1=179418&r2=179419&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/stdint.h (original)
+++ cfe/trunk/lib/Headers/stdint.h Fri Apr 12 17:11:07 2013
@@ -30,7 +30,48 @@
  */
 #if __STDC_HOSTED__ && \
     defined(__has_include_next) && __has_include_next(<stdint.h>)
+
+// C99 7.18.3 Limits of other integer types
+//
+//  Footnote 219, 220: C++ implementations should define these macros only when
+//  __STDC_LIMIT_MACROS is defined before <stdint.h> is included.
+//
+//  Footnote 222: C++ implementations should define these macros only when
+//  __STDC_CONSTANT_MACROS is defined before <stdint.h> is included.
+//
+// C++11 [cstdint.syn]p2:
+//
+//  The macros defined by <cstdint> are provided unconditionally. In particular,
+//  the symbols __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS (mentioned in
+//  footnotes 219, 220, and 222 in the C standard) play no role in C++.
+//
+// C11 removed the problematic footnotes.
+//
+// Work around this inconsistency by always defining those macros in C++ mode,
+// so that a C library implementation which follows the C99 standard can be
+// used in C++.
+# ifdef __cplusplus
+#  if !defined(__STDC_LIMIT_MACROS)
+#   define __STDC_LIMIT_MACROS
+#   define __STDC_LIMIT_MACROS_DEFINED_BY_CLANG
+#  endif
+#  if !defined(__STDC_CONSTANT_MACROS)
+#   define __STDC_CONSTANT_MACROS
+#   define __STDC_CONSTANT_MACROS_DEFINED_BY_CLANG
+#  endif
+# endif
+
 # include_next <stdint.h>
+
+# ifdef __STDC_LIMIT_MACROS_DEFINED_BY_CLANG
+#  undef __STDC_LIMIT_MACROS
+#  undef __STDC_LIMIT_MACROS_DEFINED_BY_CLANG
+# endif
+# ifdef __STDC_CONSTANT_MACROS_DEFINED_BY_CLANG
+#  undef __STDC_CONSTANT_MACROS
+#  undef __STDC_CONSTANT_MACROS_DEFINED_BY_CLANG
+# endif
+
 #else
 
 /* C99 7.18.1.1 Exact-width integer types.

Modified: cfe/trunk/test/Headers/cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Headers/cxx11.cpp?rev=179419&r1=179418&r2=179419&view=diff
==============================================================================
--- cfe/trunk/test/Headers/cxx11.cpp (original)
+++ cfe/trunk/test/Headers/cxx11.cpp Fri Apr 12 17:11:07 2013
@@ -13,3 +13,10 @@
 
 static_assert(__alignas_is_defined, "");
 static_assert(__alignof_is_defined, "");
+
+
+#include <stdint.h>
+
+#ifndef SIZE_MAX
+#error SIZE_MAX should be defined in C++
+#endif





More information about the cfe-commits mailing list