diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -299,8 +299,9 @@ if (Requested->isSubModuleOf(Use)) return true; - // Anyone is allowed to use our builtin stddef.h and its accompanying module. - if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") + // Anyone is allowed to use our builtin stdarg.h and stddef.h and their + // accompanying modules. + if (!Requested->Parent && (Requested->Name == "_Builtin_stdarg" || Requested->Name == "_Builtin_stddef")) return true; if (NoUndeclaredIncludes) diff --git a/clang/lib/Headers/__stddef_max_align_t.h b/clang/lib/Headers/__stddef_max_align_t.h --- a/clang/lib/Headers/__stddef_max_align_t.h +++ b/clang/lib/Headers/__stddef_max_align_t.h @@ -1,4 +1,4 @@ -/*===---- __stddef_max_align_t.h - Definition of max_align_t for modules ---=== +/*===---- __stddef_max_align_t.h - Definition of max_align_t ---------------=== * * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. * See https://llvm.org/LICENSE.txt for license information. diff --git a/clang/lib/Headers/__stddef_null.h b/clang/lib/Headers/__stddef_null.h --- a/clang/lib/Headers/__stddef_null.h +++ b/clang/lib/Headers/__stddef_null.h @@ -7,7 +7,15 @@ *===-----------------------------------------------------------------------=== */ +#if !defined(NULL) || !__has_feature(modules) + +/* 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. + * Modules don't support redefining macros like that, but support that pattern + * in the non-modules case. + */ #undef NULL + #ifdef __cplusplus #if !defined(__MINGW32__) && !defined(_MSC_VER) #define NULL __null @@ -17,3 +25,5 @@ #else #define NULL ((void*)0) #endif + +#endif diff --git a/clang/lib/Headers/__stddef_nullptr_t.h b/clang/lib/Headers/__stddef_nullptr_t.h --- a/clang/lib/Headers/__stddef_nullptr_t.h +++ b/clang/lib/Headers/__stddef_nullptr_t.h @@ -7,11 +7,9 @@ *===-----------------------------------------------------------------------=== */ -#if !defined(_NULLPTR_T) || __has_feature(modules) -/* Always define nullptr_t when modules are available. */ -#if !__has_feature(modules) +#ifndef _NULLPTR_T #define _NULLPTR_T -#endif + #ifdef __cplusplus #if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED) namespace std { @@ -19,7 +17,8 @@ } using ::std::nullptr_t; #endif -#else +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L typedef typeof(nullptr) nullptr_t; #endif + #endif diff --git a/clang/lib/Headers/__stddef_offsetof.h b/clang/lib/Headers/__stddef_offsetof.h --- a/clang/lib/Headers/__stddef_offsetof.h +++ b/clang/lib/Headers/__stddef_offsetof.h @@ -7,7 +7,6 @@ *===-----------------------------------------------------------------------=== */ -#if !defined(offsetof) || __has_feature(modules) -/* Always define offsetof when modules are available. */ +#ifndef offsetof #define offsetof(t, d) __builtin_offsetof(t, d) #endif diff --git a/clang/lib/Headers/__stddef_ptrdiff_t.h b/clang/lib/Headers/__stddef_ptrdiff_t.h --- a/clang/lib/Headers/__stddef_ptrdiff_t.h +++ b/clang/lib/Headers/__stddef_ptrdiff_t.h @@ -7,10 +7,9 @@ *===-----------------------------------------------------------------------=== */ -#if !defined(_PTRDIFF_T) || __has_feature(modules) -/* Always define ptrdiff_t when modules are available. */ -#if !__has_feature(modules) +#ifndef _PTRDIFF_T #define _PTRDIFF_T -#endif + typedef __PTRDIFF_TYPE__ ptrdiff_t; + #endif diff --git a/clang/lib/Headers/__stddef_rsize_t.h b/clang/lib/Headers/__stddef_rsize_t.h --- a/clang/lib/Headers/__stddef_rsize_t.h +++ b/clang/lib/Headers/__stddef_rsize_t.h @@ -7,10 +7,9 @@ *===-----------------------------------------------------------------------=== */ -#if !defined(_RSIZE_T) || __has_feature(modules) -/* Always define rsize_t when modules are available. */ -#if !__has_feature(modules) +#ifndef _RSIZE_T #define _RSIZE_T -#endif + typedef __SIZE_TYPE__ rsize_t; + #endif diff --git a/clang/lib/Headers/__stddef_size_t.h b/clang/lib/Headers/__stddef_size_t.h --- a/clang/lib/Headers/__stddef_size_t.h +++ b/clang/lib/Headers/__stddef_size_t.h @@ -7,10 +7,9 @@ *===-----------------------------------------------------------------------=== */ -#if !defined(_SIZE_T) || __has_feature(modules) -/* Always define size_t when modules are available. */ -#if !__has_feature(modules) +#ifndef _SIZE_T #define _SIZE_T -#endif + typedef __SIZE_TYPE__ size_t; + #endif diff --git a/clang/lib/Headers/__stddef_unreachable.h b/clang/lib/Headers/__stddef_unreachable.h --- a/clang/lib/Headers/__stddef_unreachable.h +++ b/clang/lib/Headers/__stddef_unreachable.h @@ -7,7 +7,6 @@ *===-----------------------------------------------------------------------=== */ -#if !defined(unreachable) || __has_feature(modules) -/* Always define unreachable when modules are available. */ +#ifndef unreachable #define unreachable() __builtin_unreachable() #endif diff --git a/clang/lib/Headers/__stddef_wchar_t.h b/clang/lib/Headers/__stddef_wchar_t.h --- a/clang/lib/Headers/__stddef_wchar_t.h +++ b/clang/lib/Headers/__stddef_wchar_t.h @@ -8,14 +8,16 @@ */ #if !defined(__cplusplus) || (defined(_MSC_VER) && !_NATIVE_WCHAR_T_DEFINED) -/* Always define wchar_t when modules are available. */ -#if !defined(_WCHAR_T) || __has_feature(modules) -#if !__has_feature(modules) + +#ifndef _WCHAR_T #define _WCHAR_T -#if defined(_MSC_EXTENSIONS) + +#ifdef _MSC_EXTENSIONS #define _WCHAR_T_DEFINED #endif -#endif + typedef __WCHAR_TYPE__ wchar_t; + #endif + #endif diff --git a/clang/lib/Headers/__stddef_wint_t.h b/clang/lib/Headers/__stddef_wint_t.h --- a/clang/lib/Headers/__stddef_wint_t.h +++ b/clang/lib/Headers/__stddef_wint_t.h @@ -7,10 +7,9 @@ *===-----------------------------------------------------------------------=== */ -/* Always define wint_t when modules are available. */ -#if !defined(_WINT_T) || __has_feature(modules) -#if !__has_feature(modules) +#ifndef _WINT_T #define _WINT_T -#endif + typedef __WINT_TYPE__ wint_t; + #endif diff --git a/clang/lib/Headers/module.modulemap b/clang/lib/Headers/module.modulemap --- a/clang/lib/Headers/module.modulemap +++ b/clang/lib/Headers/module.modulemap @@ -153,9 +153,164 @@ } } -module _Builtin_stddef_max_align_t [system] [extern_c] { - header "__stddef_max_align_t.h" +// 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. + +// e.g. if -fbuiltin-headers-in-system-modules is passed, then +// float.h will not be in the _Builtin_float module (that module +// will be empty). If there is a system module that declares +// `header "float.h"`, then the builtin float.h will join +// that module. The system float.h (if present) will be treated +// as a textual header in the sytem module. +module _Builtin_float [system] { + header "float.h" + export * +} + +module _Builtin_inttypes [system] { + header "inttypes.h" + export * +} + +module _Builtin_iso646 [system] { + header "iso646.h" + export * +} + +module _Builtin_limits [system] { + header "limits.h" + export * +} + +module _Builtin_stdalign [system] { + header "stdalign.h" + 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" + + explicit module __gnuc_va_list { + header "__stdarg___gnuc_va_list.h" + export * + } + + explicit module __va_copy { + header "__stdarg___va_copy.h" + export * + } + + explicit module va_arg { + header "__stdarg_va_arg.h" + export * + } + + explicit module va_copy { + header "__stdarg_va_copy.h" + export * + } + + explicit module va_list { + header "__stdarg_va_list.h" + export * + } +} + +module _Builtin_stdatomic [system] { + header "stdatomic.h" + export * +} + +module _Builtin_stdbool [system] { + header "stdbool.h" + export * +} + +module _Builtin_stddef [system] { + textual header "stddef.h" + + explicit module max_align_t { + header "__stddef_max_align_t.h" + export * + } + + explicit module null { + header "__stddef_null.h" + export * + } + + explicit module nullptr_t { + header "__stddef_nullptr_t.h" + export * + } + + explicit module offsetof { + header "__stddef_offsetof.h" + export * + } + + explicit module ptrdiff_t { + header "__stddef_ptrdiff_t.h" + export * + } + + explicit module rsize_t { + header "__stddef_rsize_t.h" + export * + } + + explicit module size_t { + header "__stddef_size_t.h" + export * + } + + explicit module unreachable { + header "__stddef_unreachable.h" + export * + } + + explicit module wchar_t { + header "__stddef_wchar_t.h" + export * + } +} + +/* wint_t is provided by and not . It's here + * for compatibility, but must be explicitly requested. Therefore + * __stddef_wint_t.h is not part of _Builtin_stddef. */ +module _Builtin_stddef_wint_t [system] { + header "__stddef_wint_t.h" + export * +} + +module _Builtin_stdint [system] { + header "stdint.h" + export * +} + +module _Builtin_stdnoreturn [system] { + header "stdnoreturn.h" + export * +} + +module _Builtin_tgmath [system] { + header "tgmath.h" + export * +} + +module _Builtin_unwind [system] { + header "unwind.h" + export * } +// End -fbuiltin-headers-in-system-modules affected modules module opencl_c { requires opencl diff --git a/clang/lib/Headers/stdarg.h b/clang/lib/Headers/stdarg.h --- a/clang/lib/Headers/stdarg.h +++ b/clang/lib/Headers/stdarg.h @@ -7,9 +7,31 @@ *===-----------------------------------------------------------------------=== */ -#if !defined(__STDARG_H) || defined(__need___va_list) || \ - defined(__need_va_list) || defined(__need_va_arg) || \ - defined(__need___va_copy) || defined(__need_va_copy) +/* + * This header is designed to be included multiple times. If any of the __need_ + * macros are defined, then only that subset of interfaces are provided. This + * can be useful for POSIX headers that need to not expose all of stdarg.h, but + * need to use some of its interfaces. Otherwise this header provides all of + * the expected interfaces. + * + * When clang modules are enabled, this header is a textual header. It ignores + * its header guard so that multiple submodules can export its interfaces. + * Take module SM with submodules A and B, whose headers both include stdarg.h + * When SM.A builds, __STDARG_H will be defined. When SM.B builds, the + * definition from SM.A will leak when building without local submodule + * visibility. stdarg.h wouldn't include any of its implementation headers, and + * SM.B wouldn't import any of the stdarg modules, and SM.B's `export *` + * wouldn't export any stdarg interfaces as expected. However, since stdarg.h + * ignores its header guard when building with modules, it all works as + * expected. + * + * When clang modules are not enabled, the header guards can function in the + * normal simple fashion. + */ +#if !defined(__STDARG_H) || __has_feature(modules) || \ + defined(__need___va_list) || defined(__need_va_list) || \ + defined(__need_va_arg) || defined(__need___va_copy) || \ + defined(__need_va_copy) #if !defined(__need___va_list) && !defined(__need_va_list) && \ !defined(__need_va_arg) && !defined(__need___va_copy) && \ diff --git a/clang/lib/Headers/stddef.h b/clang/lib/Headers/stddef.h --- a/clang/lib/Headers/stddef.h +++ b/clang/lib/Headers/stddef.h @@ -7,23 +7,41 @@ *===-----------------------------------------------------------------------=== */ -#if !defined(__STDDEF_H) || defined(__need_ptrdiff_t) || \ - defined(__need_size_t) || defined(__need_rsize_t) || \ - defined(__need_wchar_t) || defined(__need_NULL) || \ - defined(__need_nullptr_t) || defined(__need_unreachable) || \ - defined(__need_max_align_t) || defined(__need_offsetof) || \ - defined(__need_wint_t) || \ - (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1) +/* + * This header is designed to be included multiple times. If any of the __need_ + * macros are defined, then only that subset of interfaces are provided. This + * can be useful for POSIX headers that need to not expose all of stddef.h, but + * need to use some of its interfaces. Otherwise this header provides all of + * the expected interfaces. + * + * When clang modules are enabled, this header is a textual header. It ignores + * its header guard so that multiple submodules can export its interfaces. + * Take module SM with submodules A and B, whose headers both include stddef.h + * When SM.A builds, __STDDEF_H will be defined. When SM.B builds, the + * definition from SM.A will leak when building without local submodule + * visibility. stddef.h wouldn't include any of its implementation headers, and + * SM.B wouldn't import any of the stddef modules, and SM.B's `export *` + * wouldn't export any stddef interfaces as expected. However, since stddef.h + * ignores its header guard when building with modules, it all works as + * expected. + * + * When clang modules are not enabled, the header guards can function in the + * normal simple fashion. + */ +#if !defined(__STDDEF_H) || __has_feature(modules) || \ + (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1) || \ + defined(__need_ptrdiff_t) || defined(__need_size_t) || \ + defined(__need_rsize_t) || defined(__need_wchar_t) || \ + defined(__need_NULL) || defined(__need_nullptr_t) || \ + defined(__need_unreachable) || defined(__need_max_align_t) || \ + defined(__need_offsetof) || defined(__need_wint_t) #if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \ !defined(__need_rsize_t) && !defined(__need_wchar_t) && \ !defined(__need_NULL) && !defined(__need_nullptr_t) && \ !defined(__need_unreachable) && !defined(__need_max_align_t) && \ !defined(__need_offsetof) && !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 /* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is diff --git a/clang/test/Headers/stdarg.c b/clang/test/Headers/stdarg.c --- a/clang/test/Headers/stdarg.c +++ b/clang/test/Headers/stdarg.c @@ -1,29 +1,47 @@ +// RUN: rm -fR %t // RUN: split-file %s %t // RUN: %clang_cc1 -fsyntax-only -verify=c89 -Werror=implicit-function-declaration -std=c89 %t/stdarg0.c // RUN: %clang_cc1 -fsyntax-only -verify=c99 -Werror=implicit-function-declaration -std=c99 %t/stdarg0.c +// RUN: %clang_cc1 -fsyntax-only -verify=c89-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdarg0.c +// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c99 %t/stdarg0.c // RUN: %clang_cc1 -fsyntax-only -verify=c89 -Werror=implicit-function-declaration -std=c89 %t/stdarg1.c // RUN: %clang_cc1 -fsyntax-only -verify=c99 -Werror=implicit-function-declaration -std=c99 %t/stdarg1.c +// RUN: %clang_cc1 -fsyntax-only -verify=c89-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdarg1.c +// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c99 %t/stdarg1.c // Split the file so that the "implicitly declaring library function" errors get repeated. //--- stdarg0.c static void f(int p, ...) { - __gnuc_va_list g; // c89-error{{undeclared identifier '__gnuc_va_list'}} c99-error{{undeclared identifier}} - va_list v; // c89-error{{undeclared identifier 'va_list'}} c99-error{{undeclared identifier}} + __gnuc_va_list g; // c89-error{{undeclared identifier '__gnuc_va_list'}} c99-error{{undeclared identifier}} \ + c89-modules-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}} + va_list v; // c89-error{{undeclared identifier 'va_list'}} c99-error{{undeclared identifier}} \ + c89-modules-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}} va_start(v, p); // c89-error{{implicitly declaring library function 'va_start'}} c89-note{{include the header or explicitly provide a declaration for 'va_start'}} c89-error{{undeclared identifier 'v'}} \ - c99-error{{call to undeclared library function 'va_start'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} + c99-error{{call to undeclared library function 'va_start'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} \ + c89-modules-error{{implicitly declaring library function}} c89-modules-note{{provide a declaration}} c89-modules-error{{undeclared identifier}} \ + c99-modules-error{{undeclared library function}} c99-modules-note{{provide a declaration}} c99-modules-error{{undeclared identifier}} int i = va_arg(v, int); // c89-error{{implicit declaration of function 'va_arg'}} c89-error{{expected expression}} c89-error{{use of undeclared identifier 'v'}} \ - c99-error{{call to undeclared function 'va_arg'}} c99-error{{expected expression}} c99-error{{undeclared identifier}} + c99-error{{call to undeclared function 'va_arg'}} c99-error{{expected expression}} c99-error{{undeclared identifier}} \ + c89-modules-error{{implicit declaration of function}} c89-modules-error{{expected expression}} c89-modules-error{{undeclared identifier}} \ + c99-modules-error{{undeclared function}} c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} va_end(v); // c89-error{{implicitly declaring library function 'va_end'}} c89-note{{include the header or explicitly provide a declaration for 'va_end'}} c89-error{{undeclared identifier 'v'}} \ - c99-error{{call to undeclared library function 'va_end'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} + c99-error{{call to undeclared library function 'va_end'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} \ + c89-modules-error{{implicitly declaring library function}} c89-modules-note{{provide a declaration}} c89-modules-error{{undeclared identifier}} \ + c99-modules-error{{undeclared library function}} c99-modules-note{{provide a declaration}} c99-modules-error{{undeclared identifier}} __va_copy(g, v); // c89-error{{implicit declaration of function '__va_copy'}} c89-error{{use of undeclared identifier 'g'}} c89-error{{use of undeclared identifier 'v'}} \ - c99-error{{call to undeclared function '__va_copy'}} c99-error{{undeclared identifier}} c99-error{{undeclared identifier}} + c99-error{{call to undeclared function '__va_copy'}} c99-error{{undeclared identifier}} c99-error{{undeclared identifier}} \ + c89-modules-error{{implicit declaration of function}} c89-modules-error{{undeclared identifier}} c89-modules-error{{undeclared identifier}} \ + c99-modules-error{{undeclared function}} c99-modules-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}} va_copy(g, v); // c89-error{{implicitly declaring library function 'va_copy'}} c89-note{{include the header or explicitly provide a declaration for 'va_copy'}} c89-error{{use of undeclared identifier 'g'}} c89-error{{use of undeclared identifier 'v'}} \ - c99-error{{call to undeclared library function 'va_copy'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} c99-error{{undeclared identifier}} + c99-error{{call to undeclared library function 'va_copy'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} c99-error{{undeclared identifier}} \ + c89-modules-error{{implicitly declaring library function}} c89-modules-note{{provide a declaration}} c89-modules-error{{undeclared identifier}} c89-modules-error{{undeclared identifier}} \ + c99-modules-error{{undeclared library function}} c99-modules-note{{provide a declaration}} c99-modules-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}} } //--- stdarg1.c // c99-no-diagnostics +// c99-modules-no-diagnostics #include static void f(int p, ...) { @@ -33,5 +51,6 @@ int i = va_arg(v, int); va_end(v); __va_copy(g, v); - va_copy(g, v); // c89-error{{implicitly declaring library function}} c89-note{{provide a declaration}} + va_copy(g, v); // c89-error{{implicitly declaring library function}} c89-note{{provide a declaration}} \ + c89-modules-error{{implicitly declaring library function}} c89-modules-note{{provide a declaration}} } diff --git a/clang/test/Headers/stdargneeds.c b/clang/test/Headers/stdargneeds.c --- a/clang/test/Headers/stdargneeds.c +++ b/clang/test/Headers/stdargneeds.c @@ -1,23 +1,35 @@ +// RUN: rm -fR %t // RUN: split-file %s %t // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds0.c +// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds0.c // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds1.c +// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds1.c // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds2.c +// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds2.c // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds3.c +// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds3.c // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds4.c +// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds4.c // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds5.c +// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds5.c // Split the file so that the "implicitly declaring library function" errors get repeated. // Use C89 to verify that __need_ can be used to get types that wouldn't normally be available. //--- stdargneeds0.c static void f(int p, ...) { - __gnuc_va_list g; // expected-error{{undeclared identifier '__gnuc_va_list'}} - va_list v; // expected-error{{undeclared identifier 'va_list'}} - va_start(v, p); // expected-error{{implicitly declaring library function 'va_start'}} expected-note{{include the header or explicitly provide a declaration for 'va_start'}} expected-error{{undeclared identifier 'v'}} - int i = va_arg(v, int); // expected-error{{implicit declaration of function 'va_arg'}} expected-error{{expected expression}} expected-error{{use of undeclared identifier 'v'}} - va_end(v); // expected-error{{implicitly declaring library function 'va_end'}} expected-note{{include the header or explicitly provide a declaration for 'va_end'}} expected-error{{undeclared identifier 'v'}} - __va_copy(g, v); // expected-error{{implicit declaration of function '__va_copy'}} expected-error{{use of undeclared identifier 'g'}} expected-error{{use of undeclared identifier 'v'}} - va_copy(g, v); // expected-error{{implicitly declaring library function 'va_copy'}} expected-note{{include the header or explicitly provide a declaration for 'va_copy'}} expected-error{{use of undeclared identifier 'g'}} expected-error{{use of undeclared identifier 'v'}} + __gnuc_va_list g; // expected-error{{undeclared identifier '__gnuc_va_list'}} expected-modules-error{{undeclared identifier}} + va_list v; // expected-error{{undeclared identifier 'va_list'}} expected-modules-error{{undeclared identifier}} + va_start(v, p); // expected-error{{implicitly declaring library function 'va_start'}} expected-note{{include the header or explicitly provide a declaration for 'va_start'}} expected-error{{undeclared identifier 'v'}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} expected-modules-error{{undeclared identifier}} + int i = va_arg(v, int); // expected-error{{implicit declaration of function 'va_arg'}} expected-error{{expected expression}} expected-error{{use of undeclared identifier 'v'}} \ + expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}} expected-modules-error{{undeclared identifier}} + va_end(v); // expected-error{{implicitly declaring library function 'va_end'}} expected-note{{include the header or explicitly provide a declaration for 'va_end'}} expected-error{{undeclared identifier 'v'}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} expected-modules-error{{undeclared identifier}} + __va_copy(g, v); // expected-error{{implicit declaration of function '__va_copy'}} expected-error{{use of undeclared identifier 'g'}} expected-error{{use of undeclared identifier 'v'}} \ + expected-modules-error{{implicit declaration of function}} expected-modules-error{{undeclared identifier}} expected-modules-error{{undeclared identifier}} + va_copy(g, v); // expected-error{{implicitly declaring library function 'va_copy'}} expected-note{{include the header or explicitly provide a declaration for 'va_copy'}} expected-error{{use of undeclared identifier 'g'}} expected-error{{use of undeclared identifier 'v'}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} expected-modules-error{{undeclared identifier}} expected-modules-error{{undeclared identifier}} } //--- stdargneeds1.c @@ -25,25 +37,37 @@ #include static void f(int p, ...) { __gnuc_va_list g; - va_list v; // expected-error{{undeclared identifier}} - va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} - int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} expected-error{{undeclared identifier}} - va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} - __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}} - va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} + va_list v; // expected-error{{undeclared identifier}} \ + expected-modules-error{{'va_list' must be declared before it is used}} expected-modules-note@__stdarg_va_list.h:*{{declaration here is not visible}} + va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} + int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} expected-error{{undeclared identifier}} \ + expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}} + va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} + __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}} \ + expected-modules-error{{implicit declaration of function}} + va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} } //--- stdargneeds2.c #define __need_va_list #include static void f(int p, ...) { - __gnuc_va_list g; // expected-error{{undeclared identifier}} + __gnuc_va_list g; // expected-error{{undeclared identifier}} \ + expected-modules-error{{'__gnuc_va_list' must be declared before it is used}} expected-modules-note@__stdarg___gnuc_va_list.h:*{{declaration here is not visible}} va_list v; - va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} - int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} - va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} - __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}} - va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} + va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} + int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} \ + expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}} + va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} + __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}} \ + expected-modules-error{{implicit declaration of function}} + va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} } //--- stdargneeds3.c @@ -51,13 +75,16 @@ #define __need_va_arg #include static void f(int p, ...) { - __gnuc_va_list g; // expected-error{{undeclared identifier}} + __gnuc_va_list g; // expected-error{{undeclared identifier}} \ + expected-modules-error{{'__gnuc_va_list' must be declared before it is used}} expected-modules-note@__stdarg___gnuc_va_list.h:*{{declaration here is not visible}} va_list v; va_start(v, p); int i = va_arg(v, int); va_end(v); - __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}} - va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} + __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}} \ + expected-modules-error{{implicit declaration of function}} + va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} } //--- stdargneeds4.c @@ -68,11 +95,15 @@ static void f(int p, ...) { __gnuc_va_list g; va_list v; - va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} - int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} - va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} + va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} + int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} \ + expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}} + va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} __va_copy(g, v); - va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} + va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} } //--- stdargneeds5.c @@ -83,9 +114,12 @@ static void f(int p, ...) { __gnuc_va_list g; va_list v; - va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} - int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} - va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} - __va_copy(g, v); // expected-error{{implicit declaration of function}} + va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} + int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} \ + expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}} + va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \ + expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} + __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-modules-error{{implicit declaration of function}} va_copy(g, v); } diff --git a/clang/test/Headers/stddef.c b/clang/test/Headers/stddef.c --- a/clang/test/Headers/stddef.c +++ b/clang/test/Headers/stddef.c @@ -1,35 +1,57 @@ +// RUN: rm -fR %t // RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %s // RUN: %clang_cc1 -fsyntax-only -verify=c11 -std=c11 %s // RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s +// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c99 %s +// RUN: %clang_cc1 -fsyntax-only -verify=c11-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c11 %s +// RUN: %clang_cc1 -fsyntax-only -verify=c23-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c23 %s struct astruct { char member; }; -ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c11-error{{unknown type}} c23-error{{unknown type}} -size_t s0; // c99-error{{unknown type name 'size_t'}} c11-error{{unknown type}} c23-error{{unknown type}} -rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c11-error{{unknown type}} c23-error{{unknown type}} -wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c11-error{{unknown type}} c23-error{{unknown type}} -void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c11-error{{undeclared identifier}} c23-error{{undeclared identifier}} -nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c11-error{{unknown type}} c23-error{{unknown type}} -static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c11-error{{undeclared function}} c23-error{{undeclared identifier}} -max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c11-error{{unknown type}} c23-error{{unknown type}} +ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}} +size_t s0; // c99-error{{unknown type name 'size_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}} +rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}} +wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}} +void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c11-error{{undeclared identifier}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared identifier}} c11-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}} +nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}} +static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c11-error{{undeclared function}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared function}} c11-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}} +max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}} size_t o0 = offsetof(struct astruct, member); // c99-error{{unknown type name 'size_t'}} c99-error{{call to undeclared function 'offsetof'}} c99-error{{expected expression}} c99-error{{use of undeclared identifier 'member'}} \ c11-error{{unknown type}} c11-error{{undeclared function}} c11-error{{expected expression}} c11-error{{undeclared identifier}} \ - c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} -wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c11-error{{unknown type}} c23-error{{unknown type}} + c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \ + c99-modules-error{{unknown type}} c99-modules-error{{undeclared function}} c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c11-modules-error{{unknown type}} c11-modules-error{{undeclared function}} c11-modules-error{{expected expression}} c11-modules-error{{undeclared identifier}} \ + c23-modules-error{{unknown type}} c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type name 'wint_t'}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}} #include ptrdiff_t p1; size_t s1; -rsize_t r1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}} - // c99-note@__stddef_size_t.h:*{{'size_t' declared here}} c11-note@__stddef_size_t.h:*{{'size_t' declared here}} c23-note@__stddef_size_t.h:*{{'size_t' declared here}} +rsize_t r1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-note@__stddef_size_t.h:*{{'size_t' declared here}} c11-note@__stddef_size_t.h:*{{'size_t' declared here}} c23-note@__stddef_size_t.h:*{{'size_t' declared here}} \ + c99-modules-error{{'rsize_t' must be declared before it is used}} c11-modules-error{{must be declared}} c23-modules-error{{must be declared}} \ + c99-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}} c11-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}} wchar_t wc1; void *v1 = NULL; -nullptr_t n1; // c99-error{{unknown type}} c11-error{{unknown type}} -static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}} -max_align_t m1; // c99-error{{unknown type}} +nullptr_t n1; // c99-error{{unknown type}} c11-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} +static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}} \ + c99-modules-error{{undeclared function}} c11-modules-error{{undeclared function}} +max_align_t m1; // c99-error{{unknown type}} c99-modules-error{{'max_align_t' must be declared before it is used}} \ + c99-modules-note@__stddef_max_align_t.h:*{{declaration here is not visible}} size_t o1 = offsetof(struct astruct, member); -wint_t wi1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}} +wint_t wi1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}} // rsize_t needs to be opted into via __STDC_WANT_LIB_EXT1__ >= 1. #define __STDC_WANT_LIB_EXT1__ 1 @@ -39,8 +61,14 @@ rsize_t r2; wchar_t wc2; void *v2 = NULL; -nullptr_t n2; // c99-error{{unknown type}} c11-error{{unknown type}} -static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}} +nullptr_t n2; // c99-error{{unknown type}} c11-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} +static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}} \ + c99-modules-error{{undeclared function}} c11-modules-error{{undeclared function}} max_align_t m2; // c99-error{{unknown type}} size_t o2 = offsetof(struct astruct, member); -wint_t wi2; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}} +wint_t wi2; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}} + +// m2 and wi2 don't generate errors in modules, the "must be declared before used" +// errors are only emitted the first time the known-but-not-visible type is seen. diff --git a/clang/test/Headers/stddefneeds.c b/clang/test/Headers/stddefneeds.c --- a/clang/test/Headers/stddefneeds.c +++ b/clang/test/Headers/stddefneeds.c @@ -1,36 +1,72 @@ +// RUN: rm -fR %t // RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %s // RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s +// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c99 %s +// RUN: %clang_cc1 -fsyntax-only -verify=c23-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c23 %s // Use C99 to verify that __need_ can be used to get types that wouldn't normally be available. struct astruct { char member; }; -ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c23-error{{unknown type}} -size_t s0; // c99-error{{unknown type name 'size_t'}} c23-error{{unknown type}} -rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c23-error{{unknown type}} -wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c23-error{{unknown type}} -void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c23-error{{undeclared identifier}} -nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c23-error{{unknown type}} -static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c23-error{{undeclared identifier 'unreachable'}} -max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c23-error{{unknown type}} +ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} +size_t s0; // c99-error{{unknown type name 'size_t'}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} +rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} +wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} +void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}} +nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} +static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c23-error{{undeclared identifier 'unreachable'}} \ + c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}} +max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} size_t o0 = offsetof(struct astruct, member); // c99-error{{unknown type name 'size_t'}} c99-error{{call to undeclared function 'offsetof'}} c99-error{{expected expression}} c99-error{{use of undeclared identifier 'member'}} \ - c23-error{{unknown type name 'size_t'}} c23-error{{undeclared identifier 'offsetof'}} c23-error{{expected expression}} c23-error{{use of undeclared identifier 'member'}} -wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c23-error{{unknown type}} + c23-error{{unknown type name 'size_t'}} c23-error{{undeclared identifier 'offsetof'}} c23-error{{expected expression}} c23-error{{use of undeclared identifier 'member'}} \ + c99-modules-error{{unknown type}} c99-modules-error{{undeclared function}} c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c23-modules-error{{unknown type}} c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} #define __need_ptrdiff_t #include ptrdiff_t p1; -size_t s1; // c99-error{{unknown type}} c23-error{{unknown type}} -rsize_t r1; // c99-error{{unknown type}} c23-error{{unknown type}} -wchar_t wc1; // c99-error{{unknown type}} c23-error{{unknown type}} -void *v1 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} -nullptr_t n1; // c99-error{{unknown type}} c23-error{{unknown type}} -static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} -max_align_t m1; // c99-error{{unknown type}} c23-error{{unknown type}} +size_t s1; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{'size_t' must be declared before it is used}} c23-modules-error{{must be declared}} \ + c99-modules-note@__stddef_size_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_size_t.h:*{{declaration here is not visible}} +rsize_t r1; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{'rsize_t' must be declared before it is used}} c23-modules-error{{must be declared}} \ + c99-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}} +wchar_t wc1; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{'wchar_t' must be declared before it is used}} c23-modules-error{{must be declared}} \ + c99-modules-note@__stddef_wchar_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_wchar_t.h:*{{declaration here is not visible}} +void *v1 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}} +nullptr_t n1; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{'nullptr_t' must be declared before it is used}} \ + c23-modules-note@__stddef_nullptr_t.h:*{{declaration here is not visible}} +static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}} +max_align_t m1; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{'max_align_t' must be declared before it is used}} c23-modules-error{{must be declared}} \ + c99-modules-note@__stddef_max_align_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_max_align_t.h:*{{declaration here is not visible}} size_t o1 = offsetof(struct astruct, member); // c99-error{{unknown type}} c99-error{{expected expression}} c99-error{{undeclared identifier}} \ - c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} -wint_t wi1; // c99-error{{unknown type}} c23-error{{unknown type}} + c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \ + c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi1; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} + +// The "must be declared before used" errors are only emitted the first time a +// known-but-not-visible type is seen. At this point the _Builtin_stddef module +// has been built and all of the types tried, so most of the errors won't be +// repeated below in modules. The types still aren't available, just the errors +// aren't repeated. e.g. rsize_t still isn't available, if r1 above got deleted, +// its error would move to r2 below. #define __need_size_t #include @@ -40,13 +76,19 @@ rsize_t r2; // c99-error{{unknown type}} c23-error{{unknown type}} // c99-note@__stddef_size_t.h:*{{'size_t' declared here}} c23-note@__stddef_size_t.h:*{{'size_t' declared here}} wchar_t wc2; // c99-error{{unknown type}} c23-error{{unknown type}} -void *v2 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} -nullptr_t n2; // c99-error{{unknown type}} c23-error{{unknown type}} -static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} +void *v2 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}} +nullptr_t n2; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} +static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}} max_align_t m2; // c99-error{{unknown type}} c23-error{{unknown type}} size_t o2 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \ - c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} -wint_t wi2; // c99-error{{unknown type}} c23-error{{unknown type}} + c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \ + c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi2; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} #define __need_rsize_t #include @@ -55,13 +97,19 @@ size_t s3; rsize_t r3; wchar_t wc3; // c99-error{{unknown type}} c23-error{{unknown type}} -void *v3 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} -nullptr_t n3; // c99-error{{unknown type}} c23-error{{unknown type}} -static void f3(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} +void *v3 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}} +nullptr_t n3; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} +static void f3(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}} max_align_t m3; // c99-error{{unknown type}} c23-error{{unknown type}} size_t o3 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \ - c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} -wint_t wi3; // c99-error{{unknown type}} c23-error{{unknown type}} + c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \ + c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi3; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} #define __need_wchar_t #include @@ -70,13 +118,19 @@ size_t s4; rsize_t r4; wchar_t wc4; -void *v4 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} -nullptr_t n4; // c99-error{{unknown type}} c23-error{{unknown type}} -static void f4(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} +void *v4 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}} +nullptr_t n4; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} +static void f4(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}} max_align_t m4; // c99-error{{unknown type}} c23-error{{unknown type}} size_t o4 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \ - c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} -wint_t wi4; // c99-error{{unknown type}} c23-error{{unknown type}} + c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \ + c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi4; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} #define __need_NULL #include @@ -86,29 +140,38 @@ rsize_t r5; wchar_t wc5; void *v5 = NULL; -nullptr_t n5; // c99-error{{unknown type}} c23-error{{unknown type}} -static void f5(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} +nullptr_t n5; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} +static void f5(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}} max_align_t m5; // c99-error{{unknown type}} c23-error{{unknown type}} size_t o5 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \ - c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} -wint_t wi5; // c99-error{{unknown type}} c23-error{{unknown type}} + c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \ + c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi5; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} -// __need_nullptr_t generates an error in // c99-error@__stddef_nullptr_t.h:*{{expected function body}} +#include ptrdiff_t p6; size_t s6; rsize_t r6; wchar_t wc6; void *v6 = NULL; -nullptr_t n6; // c99-error{{unknown type}} -static void f6(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} +nullptr_t n6; // c99-error{{unknown type}} c99-modules-error{{unknown type}} +static void f6(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \ + c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}} max_align_t m6; // c99-error{{unknown type}} c23-error{{unknown type}} size_t o6 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \ - c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} -wint_t wi6; // c99-error{{unknown type}} c23-error{{unknown type}} + c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \ + c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi6; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} #define __need_unreachable #include @@ -118,12 +181,15 @@ rsize_t r7; wchar_t wc7; void *v7 = NULL; -nullptr_t n7 ; // c99-error{{unknown type}} +nullptr_t n7 ; // c99-error{{unknown type}} c99-modules-error{{unknown type}} static void f7(void) { unreachable(); } max_align_t m7; // c99-error{{unknown type}} c23-error{{unknown type}} size_t o7 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \ - c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} -wint_t wi7; // c99-error{{unknown type}} c23-error{{unknown type}} + c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \ + c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi7; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} #define __need_max_align_t #include @@ -133,12 +199,15 @@ rsize_t r8; wchar_t wc8; void *v8 = NULL; -nullptr_t n8; // c99-error{{unknown type}} +nullptr_t n8; // c99-error{{unknown type}} c99-modules-error{{unknown type}} static void f8(void) { unreachable(); } max_align_t m8; size_t o8 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \ - c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} -wint_t wi8; // c99-error{{unknown type}} c23-error{{unknown type}} + c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \ + c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \ + c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}} +wint_t wi8; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} #define __need_offsetof #include @@ -146,13 +215,14 @@ ptrdiff_t p9; size_t s9; rsize_t r9; -nullptr_t n9; // c99-error{{unknown type}} +nullptr_t n9; // c99-error{{unknown type}} c99-modules-error{{unknown type}} static void f9(void) { unreachable(); } wchar_t wc9; void *v9 = NULL; max_align_t m9; size_t o9 = offsetof(struct astruct, member); -wint_t wi9; // c99-error{{unknown type}} c23-error{{unknown type}} +wint_t wi9; // c99-error{{unknown type}} c23-error{{unknown type}} \ + c99-modules-error{{unknown type}} c23-modules-error{{unknown type}} #define __need_wint_t #include @@ -162,7 +232,7 @@ rsize_t r10; wchar_t wc10; void *v10 = NULL; -nullptr_t n10; // c99-error{{unknown type}} +nullptr_t n10; // c99-error{{unknown type}} c99-modules-error{{unknown type}} static void f10(void) { unreachable(); } max_align_t m10; size_t o10 = offsetof(struct astruct, member); diff --git a/clang/test/Modules/Inputs/System/usr/include/complex.h b/clang/test/Modules/Inputs/System/usr/include/complex.h new file mode 100644 diff --git a/clang/test/Modules/Inputs/System/usr/include/inttypes.h b/clang/test/Modules/Inputs/System/usr/include/inttypes.h new file mode 100644 diff --git a/clang/test/Modules/Inputs/System/usr/include/math.h b/clang/test/Modules/Inputs/System/usr/include/math.h new file mode 100644 diff --git a/clang/test/Modules/Inputs/System/usr/include/module.map b/clang/test/Modules/Inputs/System/usr/include/module.map --- a/clang/test/Modules/Inputs/System/usr/include/module.map +++ b/clang/test/Modules/Inputs/System/usr/include/module.map @@ -1,9 +1,24 @@ module cstd [system] { + // Only in system headers directory + module complex { + header "complex.h" + } + // Only in compiler support directory module float_constants { header "float.h" } + // In both directories (compiler support version wins, forwards) + module inttypes { + header "inttypes.h" + } + + // Only in system headers directory + module math { + header "math.h" + } + // Only in system headers directory module stdio { header "stdio.h" diff --git a/clang/test/Modules/Inputs/System/usr/include/stdint.h b/clang/test/Modules/Inputs/System/usr/include/stdint.h --- a/clang/test/Modules/Inputs/System/usr/include/stdint.h +++ b/clang/test/Modules/Inputs/System/usr/include/stdint.h @@ -1 +1,35 @@ +#ifndef STDINT_H +#define STDINT_H + typedef int my_awesome_nonstandard_integer_type; + +// types needed by stdatomic.h + +typedef char int_least8_t; +typedef short int_least16_t; +typedef int int_least32_t; +typedef long long int int_least64_t; +typedef unsigned char uint_least8_t; +typedef unsigned short uint_least16_t; +typedef unsigned int uint_least32_t; +typedef unsigned long long uint_least64_t; + +typedef char int_fast8_t; +typedef short int_fast16_t; +typedef int int_fast32_t; +typedef long long int int_fast64_t; +typedef unsigned char uint_fast8_t; +typedef unsigned short uint_fast16_t; +typedef unsigned int uint_fast32_t; +typedef unsigned long long uint_fast64_t; + +typedef int intptr_t; +typedef unsigned int uintptr_t; +typedef int intmax_t; +typedef unsigned int uintmax_t; + +// additional types for unwind.h + +typedef unsigned long long uint64_t; + +#endif /* STDINT_H */ diff --git a/clang/test/Modules/compiler_builtins.m b/clang/test/Modules/compiler_builtins.m --- a/clang/test/Modules/compiler_builtins.m +++ b/clang/test/Modules/compiler_builtins.m @@ -1,7 +1,7 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s -I%S/Inputs/System/usr/include -verify -// RUN: %clang_cc1 -fsyntax-only -std=c99 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s -I%S/Inputs/System/usr/include -verify -// RUN: %clang_cc1 -fsyntax-only -fmodules -fmodule-map-file=%resource_dir/module.modulemap -fmodules-cache-path=%t %s -I%S/Inputs/System/usr/include -verify +// RUN: %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s -internal-isystem %S/Inputs/System/usr/include -verify +// RUN: %clang_cc1 -fsyntax-only -std=c99 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s -internal-isystem %S/Inputs/System/usr/include -verify +// RUN: %clang_cc1 -fsyntax-only -fmodules -fmodule-map-file=%resource_dir/module.modulemap -fmodules-cache-path=%t %s -I%S/Inputs/System/usr/include -DNO_SYSTEM_MODULES -verify // expected-no-diagnostics #ifdef __SSE__ @@ -11,3 +11,19 @@ #ifdef __AVX2__ @import _Builtin_intrinsics.intel.avx2; #endif + +#ifndef NO_SYSTEM_MODULES +@import _Builtin_float; +@import _Builtin_inttypes; +@import _Builtin_iso646; +@import _Builtin_limits; +@import _Builtin_stdalign; +@import _Builtin_stdarg; +@import _Builtin_stdatomic; +@import _Builtin_stdbool; +@import _Builtin_stddef; +@import _Builtin_stdint; +@import _Builtin_stdnoreturn; +@import _Builtin_tgmath; +@import _Builtin_unwind; +#endif diff --git a/clang/test/Modules/stddef.c b/clang/test/Modules/stddef.c --- a/clang/test/Modules/stddef.c +++ b/clang/test/Modules/stddef.c @@ -1,13 +1,29 @@ // 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: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -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 {{missing '#include "include_again.h"'; 'size_t' must be declared before it is used}} -// expected-note@__stddef_size_t.h:* {{here}} +// 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}} #include "include_again.h" +// Includes which includes <__stddef_size_t.h> which imports the +// _Builtin_stddef.size_t module. size_t st2; + +#include "size_t.h" +// Redeclares size_t, but the type merger should figure it out. + +size_t st3; diff --git a/clang/test/Modules/stddef.m b/clang/test/Modules/stddef.m --- a/clang/test/Modules/stddef.m +++ b/clang/test/Modules/stddef.m @@ -4,4 +4,6 @@ // 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 +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/StdDef %s -verify // expected-no-diagnostics