From: Richard Smith Date: Fri, 12 Apr 2013 22:11:07 +0000 (+0000) Subject: tl;dr: Teach Clang to work around g++ changing its workaround to glibc's X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=32b5013a7a443ff12cbaa5f3e2f86978179d5e04;p=clang 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 , 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 , which was incorrect, because is supposed to provide these macros too. g++ 4.8 works around it by defining __STDC_*_MACROS in its builtin header. This change makes Clang act like g++ 4.8 in this regard: our 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 . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179419 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Headers/stdint.h b/lib/Headers/stdint.h index 6f1a8761e1..051047f7d2 100644 --- a/lib/Headers/stdint.h +++ b/lib/Headers/stdint.h @@ -30,7 +30,48 @@ */ #if __STDC_HOSTED__ && \ defined(__has_include_next) && __has_include_next() + +// 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 is included. +// +// Footnote 222: C++ implementations should define these macros only when +// __STDC_CONSTANT_MACROS is defined before is included. +// +// C++11 [cstdint.syn]p2: +// +// The macros defined by 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 + +# 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. diff --git a/test/Headers/cxx11.cpp b/test/Headers/cxx11.cpp index 41bdc76fda..54fe350ea5 100644 --- a/test/Headers/cxx11.cpp +++ b/test/Headers/cxx11.cpp @@ -13,3 +13,10 @@ static_assert(__alignas_is_defined, ""); static_assert(__alignof_is_defined, ""); + + +#include + +#ifndef SIZE_MAX +#error SIZE_MAX should be defined in C++ +#endif