From: Richard Smith Date: Fri, 3 Oct 2014 00:31:35 +0000 (+0000) Subject: Fix interaction of max_align_t and modules. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b3385dcc44e546b3647c785bd758e04d6dc72d3d;p=clang Fix interaction of max_align_t and modules. When building with modules enabled, we were defining max_align_t as a typedef for a different anonymous struct type each time it was included, resulting in an error if is not covered by a module map and is included more than once in the same modules-enabled compilation of C11 or C++11 code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218931 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Headers/CMakeLists.txt b/lib/Headers/CMakeLists.txt index d23e2122e3..f545780785 100644 --- a/lib/Headers/CMakeLists.txt +++ b/lib/Headers/CMakeLists.txt @@ -35,6 +35,7 @@ set(files stdarg.h stdbool.h stddef.h + __stddef_max_align_t.h stdint.h stdnoreturn.h tbmintrin.h diff --git a/lib/Headers/__stddef_max_align_t.h b/lib/Headers/__stddef_max_align_t.h new file mode 100644 index 0000000000..a06f412c53 --- /dev/null +++ b/lib/Headers/__stddef_max_align_t.h @@ -0,0 +1,40 @@ +/*===---- __stddef_max_align_t.h - Definition of max_align_t for modules ---=== + * + * Copyright (c) 2014 Chandler Carruth + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __CLANG_MAX_ALIGN_T_DEFINED +#define __CLANG_MAX_ALIGN_T_DEFINED + +#ifndef _MSC_VER +typedef struct { + long long __clang_max_align_nonce1 + __attribute__((__aligned__(__alignof__(long long)))); + long double __clang_max_align_nonce2 + __attribute__((__aligned__(__alignof__(long double)))); +} max_align_t; +#else +typedef double max_align_t; +#endif + +#endif diff --git a/lib/Headers/module.modulemap b/lib/Headers/module.modulemap index 93e4d65b8f..3c42477405 100644 --- a/lib/Headers/module.modulemap +++ b/lib/Headers/module.modulemap @@ -170,3 +170,7 @@ module _Builtin_intrinsics [system] { } } } + +module _Builtin_stddef_max_align_t [system] [extern_c] { + header "__stddef_max_align_t.h" +} diff --git a/lib/Headers/stddef.h b/lib/Headers/stddef.h index 2dfe0a29b2..7354996711 100644 --- a/lib/Headers/stddef.h +++ b/lib/Headers/stddef.h @@ -30,11 +30,15 @@ #if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \ !defined(__need_wchar_t) && !defined(__need_NULL) && \ !defined(__need_wint_t) +/* Always define miscellaneous pieces when modules are available. */ +#if !__has_feature(modules) #define __STDDEF_H +#endif #define __need_ptrdiff_t #define __need_size_t #define __need_wchar_t #define __need_NULL +#define __need_STDDEF_H_misc /* __need_wint_t is intentionally not defined here. */ #endif @@ -60,7 +64,7 @@ typedef __SIZE_TYPE__ size_t; #undef __need_size_t #endif /*defined(__need_size_t) */ -#if defined(__STDDEF_H) +#if defined(__need_STDDEF_H_misc) /* 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 && \ @@ -71,7 +75,7 @@ typedef __SIZE_TYPE__ size_t; #endif typedef __SIZE_TYPE__ rsize_t; #endif -#endif /* defined(__STDDEF_H) */ +#endif /* defined(__need_STDDEF_H_misc) */ #if defined(__need_wchar_t) #ifndef __cplusplus @@ -109,26 +113,13 @@ using ::std::nullptr_t; #undef __need_NULL #endif /* defined(__need_NULL) */ -#if defined(__STDDEF_H) - +#if defined(__need_STDDEF_H_misc) #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 - __attribute__((__aligned__(__alignof__(long long)))); - long double __clang_max_align_nonce2 - __attribute__((__aligned__(__alignof__(long double)))); -} max_align_t; -#else -typedef double max_align_t; +#include "__stddef_max_align_t.h" #endif -#define __CLANG_MAX_ALIGN_T_DEFINED -#endif -#endif - #define offsetof(t, d) __builtin_offsetof(t, d) -#endif /* __STDDEF_H */ +#undef __need_STDDEF_H_misc +#endif /* defined(__need_STDDEF_H_misc) */ /* 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 */ diff --git a/test/Headers/c11.c b/test/Headers/c11.c index b7b15011f3..6594823c27 100644 --- a/test/Headers/c11.c +++ b/test/Headers/c11.c @@ -1,6 +1,6 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -fmodules -fmodules-cache-path=%t %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -fmodules -fmodules-cache-path=%t %s -D__STDC_WANT_LIB_EXT1__=1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -triple i686-pc-win32 -fms-compatibility-version=17.00 %s diff --git a/test/Modules/Inputs/StdDef/include_again.h b/test/Modules/Inputs/StdDef/include_again.h new file mode 100644 index 0000000000..f29f6366cc --- /dev/null +++ b/test/Modules/Inputs/StdDef/include_again.h @@ -0,0 +1,2 @@ +#include + diff --git a/test/Modules/Inputs/StdDef/module.map b/test/Modules/Inputs/StdDef/module.map index 69c69eac35..5c4e0dae7b 100644 --- a/test/Modules/Inputs/StdDef/module.map +++ b/test/Modules/Inputs/StdDef/module.map @@ -8,4 +8,14 @@ module StdDef { header "other.h" export * } + + module PtrDiffT { + header "ptrdiff_t.h" + export * + } + + module IncludeAgain { + header "include_again.h" + export * + } } diff --git a/test/Modules/Inputs/StdDef/ptrdiff_t.h b/test/Modules/Inputs/StdDef/ptrdiff_t.h new file mode 100644 index 0000000000..acb0ab81ff --- /dev/null +++ b/test/Modules/Inputs/StdDef/ptrdiff_t.h @@ -0,0 +1,2 @@ +#define __need_ptrdiff_t +#include diff --git a/test/Modules/stddef.c b/test/Modules/stddef.c new file mode 100644 index 0000000000..aefc90f9a1 --- /dev/null +++ b/test/Modules/stddef.c @@ -0,0 +1,13 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify -fno-modules-error-recovery + +#include "ptrdiff_t.h" + +ptrdiff_t pdt; + +size_t st; // expected-error {{must be imported}} +// expected-note@stddef.h:* {{previous}} + +#include "include_again.h" + +size_t st2; diff --git a/test/Modules/system_headers.m b/test/Modules/system_headers.m index 39b13ca5fc..8adc7e8576 100644 --- a/test/Modules/system_headers.m +++ b/test/Modules/system_headers.m @@ -1,8 +1,13 @@ // Test that system-headerness works for building modules. // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -isystem %S/Inputs -pedantic -Werror %s -verify +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -isystem %S/Inputs -pedantic -Werror %s -verify -std=c11 // expected-no-diagnostics @import warning; int i = bigger_than_int; + +#include + +#define __need_size_t +#include