diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Headers/stddef.h | 38 | ||||
-rw-r--r-- | clang/test/Headers/stddefneeds.cpp | 69 | ||||
-rw-r--r-- | clang/test/Sema/format-strings.c | 3 |
3 files changed, 105 insertions, 5 deletions
diff --git a/clang/lib/Headers/stddef.h b/clang/lib/Headers/stddef.h index 97126ed1527..2dfe0a29b2a 100644 --- a/clang/lib/Headers/stddef.h +++ b/clang/lib/Headers/stddef.h @@ -23,9 +23,22 @@ *===-----------------------------------------------------------------------=== */ -#ifndef __STDDEF_H +#if !defined(__STDDEF_H) || defined(__need_ptrdiff_t) || \ + defined(__need_size_t) || defined(__need_wchar_t) || \ + defined(__need_NULL) || defined(__need_wint_t) + +#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \ + !defined(__need_wchar_t) && !defined(__need_NULL) && \ + !defined(__need_wint_t) #define __STDDEF_H +#define __need_ptrdiff_t +#define __need_size_t +#define __need_wchar_t +#define __need_NULL +/* __need_wint_t is intentionally not defined here. */ +#endif +#if defined(__need_ptrdiff_t) #if !defined(_PTRDIFF_T) || __has_feature(modules) /* Always define ptrdiff_t when modules are available. */ #if !__has_feature(modules) @@ -33,7 +46,10 @@ #endif typedef __PTRDIFF_TYPE__ ptrdiff_t; #endif +#undef __need_ptrdiff_t +#endif /* defined(__need_ptrdiff_t) */ +#if defined(__need_size_t) #if !defined(_SIZE_T) || __has_feature(modules) /* Always define size_t when modules are available. */ #if !__has_feature(modules) @@ -41,7 +57,10 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t; #endif typedef __SIZE_TYPE__ size_t; #endif +#undef __need_size_t +#endif /*defined(__need_size_t) */ +#if defined(__STDDEF_H) /* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is * enabled. */ #if (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 && \ @@ -52,7 +71,9 @@ typedef __SIZE_TYPE__ size_t; #endif typedef __SIZE_TYPE__ rsize_t; #endif +#endif /* defined(__STDDEF_H) */ +#if defined(__need_wchar_t) #ifndef __cplusplus /* Always define wchar_t when modules are available. */ #if !defined(_WCHAR_T) || __has_feature(modules) @@ -65,7 +86,10 @@ typedef __SIZE_TYPE__ rsize_t; typedef __WCHAR_TYPE__ wchar_t; #endif #endif +#undef __need_wchar_t +#endif /* defined(__need_wchar_t) */ +#if defined(__need_NULL) #undef NULL #ifdef __cplusplus # if !defined(__MINGW32__) && !defined(_MSC_VER) @@ -76,15 +100,19 @@ typedef __WCHAR_TYPE__ wchar_t; #else # define NULL ((void*)0) #endif - #ifdef __cplusplus #if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED) namespace std { typedef decltype(nullptr) nullptr_t; } using ::std::nullptr_t; #endif #endif +#undef __need_NULL +#endif /* defined(__need_NULL) */ + +#if defined(__STDDEF_H) #if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L +#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) || __has_feature(modules) #ifndef _MSC_VER typedef struct { long long __clang_max_align_nonce1 @@ -97,10 +125,10 @@ typedef double max_align_t; #endif #define __CLANG_MAX_ALIGN_T_DEFINED #endif +#endif #define offsetof(t, d) __builtin_offsetof(t, d) - -#endif /* __STDDEF_H */ +#endif /* __STDDEF_H */ /* Some C libraries expect to see a wint_t here. Others (notably MinGW) will use __WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */ @@ -114,3 +142,5 @@ typedef __WINT_TYPE__ wint_t; #endif #undef __need_wint_t #endif /* __need_wint_t */ + +#endif diff --git a/clang/test/Headers/stddefneeds.cpp b/clang/test/Headers/stddefneeds.cpp new file mode 100644 index 00000000000..304a224acc6 --- /dev/null +++ b/clang/test/Headers/stddefneeds.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wsentinel -std=c++11 %s + +ptrdiff_t p0; // expected-error{{unknown}} +size_t s0; // expected-error{{unknown}} +void* v0 = NULL; // expected-error{{undeclared}} +wint_t w0; // expected-error{{unknown}} +max_align_t m0; // expected-error{{unknown}} + +#define __need_ptrdiff_t +#include <stddef.h> + +ptrdiff_t p1; +size_t s1; // expected-error{{unknown}} +void* v1 = NULL; // expected-error{{undeclared}} +wint_t w1; // expected-error{{unknown}} +max_align_t m1; // expected-error{{unknown}} + +#define __need_size_t +#include <stddef.h> + +ptrdiff_t p2; +size_t s2; +void* v2 = NULL; // expected-error{{undeclared}} +wint_t w2; // expected-error{{unknown}} +max_align_t m2; // expected-error{{unknown}} + +#define __need_NULL +#include <stddef.h> + +ptrdiff_t p3; +size_t s3; +void* v3 = NULL; +wint_t w3; // expected-error{{unknown}} +max_align_t m3; // expected-error{{unknown}} + +// Shouldn't bring in wint_t by default: +#include <stddef.h> + +ptrdiff_t p4; +size_t s4; +void* v4 = NULL; +wint_t w4; // expected-error{{unknown}} +max_align_t m4; + +#define __need_wint_t +#include <stddef.h> + +ptrdiff_t p5; +size_t s5; +void* v5 = NULL; +wint_t w5; +max_align_t m5; + + +// linux/stddef.h does something like this for cpp files: +#undef NULL +#define NULL 0 + +// glibc (and other) headers then define __need_NULL and rely on stddef.h +// to redefine NULL to the correct value again. +#define __need_NULL +#include <stddef.h> + +// gtk headers then use __attribute__((sentinel)), which doesn't work if NULL +// is 0. +void f(const char* c, ...) __attribute__((sentinel)); +void g() { + f("", NULL); // Shouldn't warn. +} diff --git a/clang/test/Sema/format-strings.c b/clang/test/Sema/format-strings.c index ad7b37c3e11..e31644a9875 100644 --- a/clang/test/Sema/format-strings.c +++ b/clang/test/Sema/format-strings.c @@ -1,8 +1,9 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs -fno-signed-char %s -#define __need_wint_t #include <stdarg.h> +#include <stddef.h> +#define __need_wint_t #include <stddef.h> // For wint_t and wchar_t typedef struct _FILE FILE; |