mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 05:40:09 +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))
|
if (Requested->isSubModuleOf(Use))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Anyone is allowed to use our builtin stdarg.h and stddef.h and their
|
// Anyone is allowed to use our builtin stddef.h and its accompanying modules.
|
||||||
// accompanying modules.
|
if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
|
||||||
if (Requested->getTopLevelModuleName() == "_Builtin_stdarg" ||
|
Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
|
||||||
Requested->getTopLevelModuleName() == "_Builtin_stddef")
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (NoUndeclaredIncludes)
|
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
|
/* 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.
|
* __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
|
#define _NULLPTR_T
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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)
|
#define offsetof(t, d) __builtin_offsetof(t, d)
|
||||||
#endif
|
#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
|
#define _PTRDIFF_T
|
||||||
|
|
||||||
typedef __PTRDIFF_TYPE__ 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
|
#define _RSIZE_T
|
||||||
|
|
||||||
typedef __SIZE_TYPE__ 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
|
#define _SIZE_T
|
||||||
|
|
||||||
typedef __SIZE_TYPE__ 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()
|
#define unreachable() __builtin_unreachable()
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,7 +9,12 @@
|
|||||||
|
|
||||||
#if !defined(__cplusplus) || (defined(_MSC_VER) && !_NATIVE_WCHAR_T_DEFINED)
|
#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
|
#define _WCHAR_T
|
||||||
|
|
||||||
#ifdef _MSC_EXTENSIONS
|
#ifdef _MSC_EXTENSIONS
|
||||||
|
@ -155,9 +155,9 @@ module _Builtin_intrinsics [system] [extern_c] {
|
|||||||
|
|
||||||
// Start -fbuiltin-headers-in-system-modules affected modules
|
// Start -fbuiltin-headers-in-system-modules affected modules
|
||||||
|
|
||||||
// The following modules all ignore their top level headers
|
// The following modules all ignore their headers when
|
||||||
// when -fbuiltin-headers-in-system-modules is passed, and
|
// -fbuiltin-headers-in-system-modules is passed, and many of
|
||||||
// most of those headers join system modules when present.
|
// those headers join system modules when present.
|
||||||
|
|
||||||
// e.g. if -fbuiltin-headers-in-system-modules is passed, then
|
// e.g. if -fbuiltin-headers-in-system-modules is passed, then
|
||||||
// float.h will not be in the _Builtin_float module (that module
|
// float.h will not be in the _Builtin_float module (that module
|
||||||
@ -190,11 +190,6 @@ module _Builtin_stdalign [system] {
|
|||||||
export *
|
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] {
|
module _Builtin_stdarg [system] {
|
||||||
textual header "stdarg.h"
|
textual header "stdarg.h"
|
||||||
|
|
||||||
@ -237,6 +232,8 @@ module _Builtin_stdbool [system] {
|
|||||||
module _Builtin_stddef [system] {
|
module _Builtin_stddef [system] {
|
||||||
textual header "stddef.h"
|
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 {
|
explicit module max_align_t {
|
||||||
header "__stddef_max_align_t.h"
|
header "__stddef_max_align_t.h"
|
||||||
export *
|
export *
|
||||||
@ -283,9 +280,10 @@ module _Builtin_stddef [system] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wint_t is provided by <wchar.h> and not <stddef.h>. It's here
|
// wint_t is provided by <wchar.h> and not <stddef.h>. It's here
|
||||||
* for compatibility, but must be explicitly requested. Therefore
|
// for compatibility, but must be explicitly requested. Therefore
|
||||||
* __stddef_wint_t.h is not part of _Builtin_stddef. */
|
// __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] {
|
module _Builtin_stddef_wint_t [system] {
|
||||||
header "__stddef_wint_t.h"
|
header "__stddef_wint_t.h"
|
||||||
export *
|
export *
|
||||||
|
@ -2498,9 +2498,12 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool NeedsFramework = false;
|
bool NeedsFramework = false;
|
||||||
// Don't add the top level headers to the builtin modules if the builtin headers
|
// Don't add headers to the builtin modules if the builtin headers belong to
|
||||||
// belong to the system modules.
|
// the system modules, with the exception of __stddef_max_align_t.h which
|
||||||
if (!Map.LangOpts.BuiltinHeadersInSystemModules || ActiveModule->isSubModule() || !isBuiltInModuleName(ActiveModule->Name))
|
// 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);
|
Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
|
||||||
|
|
||||||
if (NeedsFramework)
|
if (NeedsFramework)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
// headers.
|
// headers.
|
||||||
|
|
||||||
// RUN: rm -rf %t
|
// 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
|
// expected-no-diagnostics
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@ -1,29 +1,33 @@
|
|||||||
// RUN: rm -rf %t
|
// 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: 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"
|
#include "ptrdiff_t.h"
|
||||||
|
|
||||||
ptrdiff_t pdt;
|
ptrdiff_t pdt;
|
||||||
|
|
||||||
// size_t is declared in both size_t.h and __stddef_size_t.h, both of which are
|
// size_t is declared in both size_t.h and __stddef_size_t.h. If
|
||||||
// modular headers. Regardless of whether stddef.h joins the StdDef test module
|
// -fbuiltin-headers-in-system-modules is set, then __stddef_size_t.h is a
|
||||||
// or is in its _Builtin_stddef module, __stddef_size_t.h will be in
|
// non-modular header that will be transitively pulled in the StdDef test module
|
||||||
// _Builtin_stddef.size_t. It's not defined which module will win as the expected
|
// by include_again.h. Otherwise it will be in the _Builtin_stddef module. In
|
||||||
// provider of size_t. For the purposes of this test it doesn't matter which header
|
// any case it's not defined which module will win as the expected provider of
|
||||||
// gets reported, just as long as it isn't other.h or include_again.h.
|
// size_t. For the purposes of this test it doesn't matter which of the two
|
||||||
size_t st; // expected-error-re {{missing '#include "{{size_t|__stddef_size_t}}.h"'; 'size_t' must be declared before it is used}}
|
// providing headers get reported.
|
||||||
// expected-note@size_t.h:* 0+ {{here}}
|
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}} \
|
||||||
// expected-note@__stddef_size_t.h:* 0+ {{here}}
|
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"
|
#include "include_again.h"
|
||||||
// Includes <stddef.h> which includes <__stddef_size_t.h> which imports the
|
// Includes <stddef.h> which includes <__stddef_size_t.h>.
|
||||||
// _Builtin_stddef.size_t module.
|
|
||||||
|
|
||||||
size_t st2;
|
size_t st2;
|
||||||
|
|
||||||
#include "size_t.h"
|
#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;
|
size_t st3;
|
||||||
|
Loading…
Reference in New Issue
Block a user