mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-26 23:21:11 +00:00
[clang][modules] giving the __stddef_ headers their own modules can cause redeclaration errors with -fbuiltin-headers-in-system-modules (#84127)
On Apple platforms, some of the stddef.h types are also declared in system headers. In particular NULL has a conflicting declaration in <sys/_types/_null.h>. When that's in a different module from <__stddef_null.h>, redeclaration errors can occur. Make the \_\_stddef_ headers be non-modular in -fbuiltin-headers-in-system-modules and restore them back to not respecting their header guards. Still define the header guards though. __stddef_max_align_t.h was in _Builtin_stddef_max_align_t prior to the addition of _Builtin_stddef, and it needs to stay in a module because struct's can't be type merged. __stddef_wint_t.h didn't used to have a module, but leave it in it current module since it doesn't really belong to stddef.h. (cherry picked from commit f50d3582b4844b86ad86372028e44b52c560ec7d)
This commit is contained in:
parent
12a3bf3515
commit
a649e0a6e8
@ -301,10 +301,9 @@ bool Module::directlyUses(const Module *Requested) {
|
||||
if (Requested->isSubModuleOf(Use))
|
||||
return true;
|
||||
|
||||
// Anyone is allowed to use our builtin stdarg.h and stddef.h and their
|
||||
// accompanying modules.
|
||||
if (Requested->getTopLevelModuleName() == "_Builtin_stdarg" ||
|
||||
Requested->getTopLevelModuleName() == "_Builtin_stddef")
|
||||
// Anyone is allowed to use our builtin stddef.h and its accompanying modules.
|
||||
if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
|
||||
Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
|
||||
return true;
|
||||
|
||||
if (NoUndeclaredIncludes)
|
||||
|
@ -7,7 +7,7 @@
|
||||
*===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#if !defined(NULL) || !__has_feature(modules)
|
||||
#if !defined(NULL) || !__building_module(_Builtin_stddef)
|
||||
|
||||
/* linux/stddef.h will define NULL to 0. glibc (and other) headers then define
|
||||
* __need_NULL and rely on stddef.h to redefine NULL to the correct value again.
|
||||
|
@ -7,7 +7,12 @@
|
||||
*===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef _NULLPTR_T
|
||||
/*
|
||||
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
|
||||
* and needs to behave as if it was textual.
|
||||
*/
|
||||
#if !defined(_NULLPTR_T) || \
|
||||
(__has_feature(modules) && !__building_module(_Builtin_stddef))
|
||||
#define _NULLPTR_T
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -7,6 +7,11 @@
|
||||
*===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef offsetof
|
||||
/*
|
||||
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
|
||||
* and needs to behave as if it was textual.
|
||||
*/
|
||||
#if !defined(offsetof) || \
|
||||
(__has_feature(modules) && !__building_module(_Builtin_stddef))
|
||||
#define offsetof(t, d) __builtin_offsetof(t, d)
|
||||
#endif
|
||||
|
@ -7,7 +7,12 @@
|
||||
*===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef _PTRDIFF_T
|
||||
/*
|
||||
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
|
||||
* and needs to behave as if it was textual.
|
||||
*/
|
||||
#if !defined(_PTRDIFF_T) || \
|
||||
(__has_feature(modules) && !__building_module(_Builtin_stddef))
|
||||
#define _PTRDIFF_T
|
||||
|
||||
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||
|
@ -7,7 +7,12 @@
|
||||
*===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef _RSIZE_T
|
||||
/*
|
||||
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
|
||||
* and needs to behave as if it was textual.
|
||||
*/
|
||||
#if !defined(_RSIZE_T) || \
|
||||
(__has_feature(modules) && !__building_module(_Builtin_stddef))
|
||||
#define _RSIZE_T
|
||||
|
||||
typedef __SIZE_TYPE__ rsize_t;
|
||||
|
@ -7,7 +7,12 @@
|
||||
*===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef _SIZE_T
|
||||
/*
|
||||
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
|
||||
* and needs to behave as if it was textual.
|
||||
*/
|
||||
#if !defined(_SIZE_T) || \
|
||||
(__has_feature(modules) && !__building_module(_Builtin_stddef))
|
||||
#define _SIZE_T
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
|
@ -7,6 +7,11 @@
|
||||
*===-----------------------------------------------------------------------===
|
||||
*/
|
||||
|
||||
#ifndef unreachable
|
||||
/*
|
||||
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
|
||||
* and needs to behave as if it was textual.
|
||||
*/
|
||||
#if !defined(unreachable) || \
|
||||
(__has_feature(modules) && !__building_module(_Builtin_stddef))
|
||||
#define unreachable() __builtin_unreachable()
|
||||
#endif
|
||||
|
@ -9,7 +9,12 @@
|
||||
|
||||
#if !defined(__cplusplus) || (defined(_MSC_VER) && !_NATIVE_WCHAR_T_DEFINED)
|
||||
|
||||
#ifndef _WCHAR_T
|
||||
/*
|
||||
* When -fbuiltin-headers-in-system-modules is set this is a non-modular header
|
||||
* and needs to behave as if it was textual.
|
||||
*/
|
||||
#if !defined(_WCHAR_T) || \
|
||||
(__has_feature(modules) && !__building_module(_Builtin_stddef))
|
||||
#define _WCHAR_T
|
||||
|
||||
#ifdef _MSC_EXTENSIONS
|
||||
|
@ -155,9 +155,9 @@ module _Builtin_intrinsics [system] [extern_c] {
|
||||
|
||||
// Start -fbuiltin-headers-in-system-modules affected modules
|
||||
|
||||
// The following modules all ignore their top level headers
|
||||
// when -fbuiltin-headers-in-system-modules is passed, and
|
||||
// most of those headers join system modules when present.
|
||||
// The following modules all ignore their headers when
|
||||
// -fbuiltin-headers-in-system-modules is passed, and many of
|
||||
// those headers join system modules when present.
|
||||
|
||||
// e.g. if -fbuiltin-headers-in-system-modules is passed, then
|
||||
// float.h will not be in the _Builtin_float module (that module
|
||||
@ -190,11 +190,6 @@ module _Builtin_stdalign [system] {
|
||||
export *
|
||||
}
|
||||
|
||||
// When -fbuiltin-headers-in-system-modules is passed, only
|
||||
// the top level headers are removed, the implementation headers
|
||||
// will always be in their submodules. That means when stdarg.h
|
||||
// is included, it will still import this module and make the
|
||||
// appropriate submodules visible.
|
||||
module _Builtin_stdarg [system] {
|
||||
textual header "stdarg.h"
|
||||
|
||||
@ -237,6 +232,8 @@ module _Builtin_stdbool [system] {
|
||||
module _Builtin_stddef [system] {
|
||||
textual header "stddef.h"
|
||||
|
||||
// __stddef_max_align_t.h is always in this module, even if
|
||||
// -fbuiltin-headers-in-system-modules is passed.
|
||||
explicit module max_align_t {
|
||||
header "__stddef_max_align_t.h"
|
||||
export *
|
||||
@ -283,9 +280,10 @@ module _Builtin_stddef [system] {
|
||||
}
|
||||
}
|
||||
|
||||
/* wint_t is provided by <wchar.h> and not <stddef.h>. It's here
|
||||
* for compatibility, but must be explicitly requested. Therefore
|
||||
* __stddef_wint_t.h is not part of _Builtin_stddef. */
|
||||
// wint_t is provided by <wchar.h> and not <stddef.h>. It's here
|
||||
// for compatibility, but must be explicitly requested. Therefore
|
||||
// __stddef_wint_t.h is not part of _Builtin_stddef. It is always in
|
||||
// this module even if -fbuiltin-headers-in-system-modules is passed.
|
||||
module _Builtin_stddef_wint_t [system] {
|
||||
header "__stddef_wint_t.h"
|
||||
export *
|
||||
|
@ -2498,9 +2498,12 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
|
||||
}
|
||||
|
||||
bool NeedsFramework = false;
|
||||
// Don't add the top level headers to the builtin modules if the builtin headers
|
||||
// belong to the system modules.
|
||||
if (!Map.LangOpts.BuiltinHeadersInSystemModules || ActiveModule->isSubModule() || !isBuiltInModuleName(ActiveModule->Name))
|
||||
// Don't add headers to the builtin modules if the builtin headers belong to
|
||||
// the system modules, with the exception of __stddef_max_align_t.h which
|
||||
// always had its own module.
|
||||
if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
|
||||
!isBuiltInModuleName(ActiveModule->getTopLevelModuleName()) ||
|
||||
ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))
|
||||
Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
|
||||
|
||||
if (NeedsFramework)
|
||||
|
@ -8,7 +8,7 @@
|
||||
// headers.
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/no-undeclared-includes-builtins/libcxx -I %S/Inputs/no-undeclared-includes-builtins/glibc %s
|
||||
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fbuiltin-headers-in-system-modules -fimplicit-module-maps -I %S/Inputs/no-undeclared-includes-builtins/libcxx -I %S/Inputs/no-undeclared-includes-builtins/glibc %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
#include <stddef.h>
|
||||
|
@ -1,29 +1,33 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fbuiltin-headers-in-system-modules -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify -fno-modules-error-recovery
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fbuiltin-headers-in-system-modules -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify=builtin-headers-in-system-modules -fno-modules-error-recovery
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify -fno-modules-error-recovery
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify=no-builtin-headers-in-system-modules -fno-modules-error-recovery
|
||||
|
||||
#include "ptrdiff_t.h"
|
||||
|
||||
ptrdiff_t pdt;
|
||||
|
||||
// size_t is declared in both size_t.h and __stddef_size_t.h, both of which are
|
||||
// modular headers. Regardless of whether stddef.h joins the StdDef test module
|
||||
// or is in its _Builtin_stddef module, __stddef_size_t.h will be in
|
||||
// _Builtin_stddef.size_t. It's not defined which module will win as the expected
|
||||
// provider of size_t. For the purposes of this test it doesn't matter which header
|
||||
// gets reported, just as long as it isn't other.h or include_again.h.
|
||||
size_t st; // expected-error-re {{missing '#include "{{size_t|__stddef_size_t}}.h"'; 'size_t' must be declared before it is used}}
|
||||
// expected-note@size_t.h:* 0+ {{here}}
|
||||
// expected-note@__stddef_size_t.h:* 0+ {{here}}
|
||||
// size_t is declared in both size_t.h and __stddef_size_t.h. If
|
||||
// -fbuiltin-headers-in-system-modules is set, then __stddef_size_t.h is a
|
||||
// non-modular header that will be transitively pulled in the StdDef test module
|
||||
// by include_again.h. Otherwise it will be in the _Builtin_stddef module. In
|
||||
// any case it's not defined which module will win as the expected provider of
|
||||
// size_t. For the purposes of this test it doesn't matter which of the two
|
||||
// providing headers get reported.
|
||||
size_t st; // builtin-headers-in-system-modules-error-re {{missing '#include "{{size_t|include_again}}.h"'; 'size_t' must be declared before it is used}} \
|
||||
no-builtin-headers-in-system-modules-error-re {{missing '#include "{{size_t|__stddef_size_t}}.h"'; 'size_t' must be declared before it is used}}
|
||||
// builtin-headers-in-system-modules-note@size_t.h:* 0+ {{here}} \
|
||||
no-builtin-headers-in-system-modules-note@size_t.h:* 0+ {{here}}
|
||||
// builtin-headers-in-system-modules-note@__stddef_size_t.h:* 0+ {{here}} \
|
||||
no-builtin-headers-in-system-modules-note@__stddef_size_t.h:* 0+ {{here}}
|
||||
|
||||
#include "include_again.h"
|
||||
// Includes <stddef.h> which includes <__stddef_size_t.h> which imports the
|
||||
// _Builtin_stddef.size_t module.
|
||||
// Includes <stddef.h> which includes <__stddef_size_t.h>.
|
||||
|
||||
size_t st2;
|
||||
|
||||
#include "size_t.h"
|
||||
// Redeclares size_t, but the type merger should figure it out.
|
||||
// Redeclares size_t when -fbuiltin-headers-in-system-modules is not passed, but
|
||||
// the type merger should figure it out.
|
||||
|
||||
size_t st3;
|
||||
|
Loading…
Reference in New Issue
Block a user