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 <stddef.h> 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.

llvm-svn: 218931
This commit is contained in:
Richard Smith 2014-10-03 00:31:35 +00:00
parent 5312afe7e1
commit ef99e4d88a
10 changed files with 89 additions and 21 deletions

View File

@ -35,6 +35,7 @@ set(files
stdarg.h
stdbool.h
stddef.h
__stddef_max_align_t.h
stdint.h
stdnoreturn.h
tbmintrin.h

View File

@ -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

View File

@ -170,3 +170,7 @@ module _Builtin_intrinsics [system] {
}
}
}
module _Builtin_stddef_max_align_t [system] [extern_c] {
header "__stddef_max_align_t.h"
}

View File

@ -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 */

View File

@ -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

View File

@ -0,0 +1,2 @@
#include <stddef.h>

View File

@ -8,4 +8,14 @@ module StdDef {
header "other.h"
export *
}
module PtrDiffT {
header "ptrdiff_t.h"
export *
}
module IncludeAgain {
header "include_again.h"
export *
}
}

View File

@ -0,0 +1,2 @@
#define __need_ptrdiff_t
#include <stddef.h>

View File

@ -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;

View File

@ -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 <stddef.h>
#define __need_size_t
#include <stddef.h>