https://github.com/jamieschmeiser updated https://github.com/llvm/llvm-project/pull/149176
>From e50062b48a09bd6e077b86bdeed65c7c1abb2ebe Mon Sep 17 00:00:00 2001 From: Jamie Schmeiser <schme...@ca.ibm.com> Date: Wed, 16 Jul 2025 15:40:09 -0400 Subject: [PATCH] Ensure proper NULL macro definition for system include files. The C standard allows for at least 2 valid definitions of a null pointer constant and mandates that several standard headers files define the macro NULL to be a null pointer constant. Ensure that definitions of NULL are consistent across the various C header files. respond to review: add in locale.h --- clang/lib/Headers/CMakeLists.txt | 38 ++++++++++++++++++++++++++++ clang/lib/Headers/dbm.h | 39 +++++++++++++++++++++++++++++ clang/lib/Headers/locale.h | 25 ++++++++++++++++++ clang/lib/Headers/stdio.h | 25 ++++++++++++++++++ clang/lib/Headers/stdlib.h | 25 ++++++++++++++++++ clang/lib/Headers/string.h | 25 ++++++++++++++++++ clang/lib/Headers/sys/dir.h | 38 ++++++++++++++++++++++++++++ clang/lib/Headers/sys/param.h | 38 ++++++++++++++++++++++++++++ clang/lib/Headers/sys/types.h | 38 ++++++++++++++++++++++++++++ clang/lib/Headers/time.h | 25 ++++++++++++++++++ clang/lib/Headers/unistd.h | 35 ++++++++++++++++++++++++++ clang/lib/Headers/wchar.h | 25 ++++++++++++++++++ clang/test/Headers/check-NULL-aix.c | 16 ++++++++++++ clang/test/Headers/check-NULL.c | 15 +++++++++++ 14 files changed, 407 insertions(+) create mode 100644 clang/lib/Headers/dbm.h create mode 100644 clang/lib/Headers/locale.h create mode 100644 clang/lib/Headers/stdio.h create mode 100644 clang/lib/Headers/stdlib.h create mode 100644 clang/lib/Headers/string.h create mode 100644 clang/lib/Headers/sys/dir.h create mode 100644 clang/lib/Headers/sys/param.h create mode 100644 clang/lib/Headers/sys/types.h create mode 100644 clang/lib/Headers/time.h create mode 100644 clang/lib/Headers/unistd.h create mode 100644 clang/lib/Headers/wchar.h create mode 100644 clang/test/Headers/check-NULL-aix.c create mode 100644 clang/test/Headers/check-NULL.c diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index dd52498bbef4c..6c238c2e8aee9 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -39,6 +39,26 @@ set(core_files varargs.h ) +set(aix_wrapper_files + dbm.h + locale.h + stdio.h + stdlib.h + string.h + time.h + unistd.h + wchar.h + ) +set(aix_sys_subdir_wrapper_files + sys/dir.h + sys/param.h + sys/types.h + ) +set(aix_files + ${aix_wrapper_files} + ${aix_sys_subdir_wrapper_files} + ) + set(arm_common_files # Headers shared by Arm and AArch64 arm_acle.h @@ -312,6 +332,7 @@ set(utility_files set(files ${core_files} + ${aix_files} ${arm_common_files} ${arm_only_files} ${aarch64_only_files} @@ -529,6 +550,7 @@ set_target_properties("clang-resource-headers" PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${output_dir}") add_dependencies("clang-resource-headers" "core-resource-headers" + "aix-resource-headers" "arm-common-resource-headers" "arm-resource-headers" "aarch64-resource-headers" @@ -557,6 +579,7 @@ add_header_target("core-resource-headers" ${core_files}) add_header_target("arm-common-resource-headers" "${arm_common_files};${arm_common_generated_files}") # Architecture/platform specific targets +add_header_target("aix-resource-headers" "${aix_files}") add_header_target("arm-resource-headers" "${arm_only_files};${arm_only_generated_files}") add_header_target("aarch64-resource-headers" "${aarch64_only_files};${aarch64_only_generated_files}") add_header_target("cuda-resource-headers" "${cuda_files};${cuda_wrapper_files};${cuda_wrapper_bits_files};${cuda_wrapper_utility_files}") @@ -644,6 +667,18 @@ install( EXCLUDE_FROM_ALL COMPONENT core-resource-headers) +install( + FILES ${aix_wrapper_files} + DESTINATION ${header_install_dir} + EXCLUDE_FROM_ALL + COMPONENT aix-resource-headers) + +install( + FILES ${aix_sys_subdir_wrapper_files} + DESTINATION ${header_install_dir}/sys + EXCLUDE_FROM_ALL + COMPONENT aix-resource-headers) + install( FILES ${arm_common_files} ${arm_common_generated_files} DESTINATION ${header_install_dir} @@ -837,6 +872,9 @@ if (NOT LLVM_ENABLE_IDE) add_llvm_install_targets(install-core-resource-headers DEPENDS core-resource-headers COMPONENT core-resource-headers) + add_llvm_install_targets(install-aix-resource-headers + DEPENDS aix-resource-headers + COMPONENT aix-resource-headers) add_llvm_install_targets(install-arm-common-resource-headers DEPENDS arm-common-resource-headers COMPONENT arm-common-resource-headers) diff --git a/clang/lib/Headers/dbm.h b/clang/lib/Headers/dbm.h new file mode 100644 index 0000000000000..8b7e2f51c5664 --- /dev/null +++ b/clang/lib/Headers/dbm.h @@ -0,0 +1,39 @@ +/*===---- dbm.h - BSD header for database management ----------------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// Limit the effects to those platforms that have this as a system header. +#if defined(_AIX) + +// Ensure that the definition of NULL (if present) is correct since it might +// not be redefined if it is already defined. This ensures any use of NULL is +// correct while processing the include_next. +#define __need_NULL +#include <stddef.h> + +#endif + +// Always include_next the file so that it will be included when requested. +// This will trigger an error on platforms where it is not found unless +// system include paths find it, which is the correct behaviour. + +#include_next <dbm.h> + +// Limit the effects to those platforms that have this as a system header. +#if defined(_AIX) && defined(NULL) + +// Ensure that the definition of NULL (if present) is consistent with what +// is expected, regardless of where it came from. +#define __need_NULL +#include <stddef.h> + +#endif diff --git a/clang/lib/Headers/locale.h b/clang/lib/Headers/locale.h new file mode 100644 index 0000000000000..6cb85738521cb --- /dev/null +++ b/clang/lib/Headers/locale.h @@ -0,0 +1,25 @@ +/*===---- locale.h - Standard header for localization ---------------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// The standard specifies that locale.h defines NULL so ensure that the +// definition is correct since it might not be redefined if it is already +// defined. This ensures any use of NULL is correct while processing the +// include_next. +#define __need_NULL +#include <stddef.h> + +#include_next <locale.h> + +// Ensure that the definition of NULL is as expected (likely redundant). +#define __need_NULL +#include <stddef.h> diff --git a/clang/lib/Headers/stdio.h b/clang/lib/Headers/stdio.h new file mode 100644 index 0000000000000..db981f54ec193 --- /dev/null +++ b/clang/lib/Headers/stdio.h @@ -0,0 +1,25 @@ +/*===---- stdio.h - Standard header for input and output-------------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// The standard specifies that stdio.h defines NULL so ensure that the +// definition is correct since it might not be redefined if it is already +// defined. This ensures any use of NULL is correct while processing the +// include_next. +#define __need_NULL +#include <stddef.h> + +#include_next <stdio.h> + +// Ensure that the definition of NULL is as expected (likely redundant). +#define __need_NULL +#include <stddef.h> diff --git a/clang/lib/Headers/stdlib.h b/clang/lib/Headers/stdlib.h new file mode 100644 index 0000000000000..2bcf79e9622a5 --- /dev/null +++ b/clang/lib/Headers/stdlib.h @@ -0,0 +1,25 @@ +/*===---- stdlib.h - Standard header for general utilities ----------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// The standard specifies that stdlib.h defines NULL so ensure that the +// definition is correct since it might not be redefined if it is already +// defined. This ensures any use of NULL is correct while processing the +// include_next. +#define __need_NULL +#include <stddef.h> + +#include_next <stdlib.h> + +// Ensure that the definition of NULL is as expected (likely redundant). +#define __need_NULL +#include <stddef.h> diff --git a/clang/lib/Headers/string.h b/clang/lib/Headers/string.h new file mode 100644 index 0000000000000..a23d91e25743f --- /dev/null +++ b/clang/lib/Headers/string.h @@ -0,0 +1,25 @@ +/*===---- string.h - Standard header for string handling ------------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// The standard specifies that string.h defines NULL so ensure that the +// definition is correct since it might not be redefined if it is already +// defined. This ensures any use of NULL is correct while processing the +// include_next. +#define __need_NULL +#include <stddef.h> + +#include_next <string.h> + +// Ensure that the definition of NULL is as expected (likely redundant). +#define __need_NULL +#include <stddef.h> diff --git a/clang/lib/Headers/sys/dir.h b/clang/lib/Headers/sys/dir.h new file mode 100644 index 0000000000000..8f7e2a40d1bd8 --- /dev/null +++ b/clang/lib/Headers/sys/dir.h @@ -0,0 +1,38 @@ +/*===---- sys/dir.h - BSD header for directory handling -------------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// Limit the effects to those platforms that have this as a system header. +#if defined(_AIX) + +// Ensure that the definition of NULL (if present) is correct since it might +// not be redefined if it is already defined. This ensures any use of NULL is +// correct while processing the include_next. +#define __need_NULL +#include <stddef.h> + +#endif + +// Always include_next the file so that it will be included when requested. +// This will trigger an error on platforms where it is not found unless +// system include paths find it, which is the correct behaviour. +#include_next <sys/dir.h> + +// Limit the effects to those platforms that have this as a system header. +#if defined(_AIX) && defined(NULL) + +// Ensure that the definition of NULL (if present) is consistent with what +// is expected, regardless of where it came from. +#define __need_NULL +#include <stddef.h> + +#endif diff --git a/clang/lib/Headers/sys/param.h b/clang/lib/Headers/sys/param.h new file mode 100644 index 0000000000000..e1338854ad0b0 --- /dev/null +++ b/clang/lib/Headers/sys/param.h @@ -0,0 +1,38 @@ +/*===---- sys/param.h - BSD header ----------------------------------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// Limit the effects to those platforms that have this as a system header. +#if defined(_AIX) + +// Ensure that the definition of NULL (if present) is correct since it might +// not be redefined if it is already defined. This ensures any use of NULL is +// correct while processing the include_next. +#define __need_NULL +#include <stddef.h> + +#endif + +// Always include_next the file so that it will be included when requested. +// This will trigger an error on platforms where it is not found unless +// system include paths find it, which is the correct behaviour. +#include_next <sys/param.h> + +// Limit the effects to those platforms that have this as a system header. +#if defined(_AIX) && defined(NULL) + +// Ensure that the definition of NULL (if present) is consistent with what +// is expected, regardless of where it came from. +#define __need_NULL +#include <stddef.h> + +#endif diff --git a/clang/lib/Headers/sys/types.h b/clang/lib/Headers/sys/types.h new file mode 100644 index 0000000000000..c4f6d75491d3a --- /dev/null +++ b/clang/lib/Headers/sys/types.h @@ -0,0 +1,38 @@ +/*===---- sys/types.h - BSD header for types ------------------------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// Limit the effects to those platforms that have this as a system header. +#if defined(_AIX) + +// Ensure that the definition of NULL (if present) is correct since it might +// not be redefined if it is already defined. This ensures any use of NULL is +// correct while processing the include_next. +#define __need_NULL +#include <stddef.h> + +#endif + +// Always include_next the file so that it will be included when requested. +// This will trigger an error on platforms where it is not found unless +// system include paths find it, which is the correct behaviour. +#include_next <sys/types.h> + +// Limit the effects to those platforms that have this as a system header. +#if defined(_AIX) && defined(NULL) + +// Ensure that the definition of NULL (if present) is consistent with what +// is expected, regardless of where it came from. +#define __need_NULL +#include <stddef.h> + +#endif diff --git a/clang/lib/Headers/time.h b/clang/lib/Headers/time.h new file mode 100644 index 0000000000000..3702d40caf8c5 --- /dev/null +++ b/clang/lib/Headers/time.h @@ -0,0 +1,25 @@ +/*===---- time.h - Standard header for date and time handling -------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// The standard specifies that time.h defines NULL so ensure that the +// definition is correct since it might not be redefined if it is already +// defined. This ensures any use of NULL is correct while processing the +// include_next. +#define __need_NULL +#include <stddef.h> + +#include_next <time.h> + +// Ensure that the definition of NULL is as expected (likely redundant). +#define __need_NULL +#include <stddef.h> diff --git a/clang/lib/Headers/unistd.h b/clang/lib/Headers/unistd.h new file mode 100644 index 0000000000000..05b8c936ba574 --- /dev/null +++ b/clang/lib/Headers/unistd.h @@ -0,0 +1,35 @@ +/*===---- unistd.h - Posix Standard header --------------------------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// Limit the effects to those platforms that are POSIX compliant. +#if defined(_AIX) + +// POSIX specifies that unistd.h defines NULL so ensure that the +// definition is correct since it might not be redefined if it is already +// defined. This ensures any use of NULL is correct while processing the +// include_next. +#define __need_NULL +#include <stddef.h> + +#endif + +#include_next <unistd.h> + +// Limit the effects to those platforms that are POSIX compliant. +#if defined(_AIX) && defined(NULL) + +// Ensure that the definition of NULL is as expected (likely redundant). +#define __need_NULL +#include <stddef.h> + +#endif diff --git a/clang/lib/Headers/wchar.h b/clang/lib/Headers/wchar.h new file mode 100644 index 0000000000000..ae7a1e779f5b0 --- /dev/null +++ b/clang/lib/Headers/wchar.h @@ -0,0 +1,25 @@ +/*===---- wchar.h - Standard header for string handling ------------------===*\ + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * +\*===----------------------------------------------------------------------===*/ + +// Although technically correct according to the standard, NULL defined as 0 +// may be problematic since it may result in a different size object than a +// pointer (eg 64 bit mode on AIX). Therefore, re-define the macro to +// ((void*)0) for consistency where needed. + +// The standard specifies that wchar.h defines NULL so ensure that the +// definition is correct since it might not be redefined if it is already +// defined. This ensures any use of NULL is correct while processing the +// include_next. +#define __need_NULL +#include <stddef.h> + +#include_next <wchar.h> + +// Ensure that the definition of NULL is as expected (likely redundant). +#define __need_NULL +#include <stddef.h> diff --git a/clang/test/Headers/check-NULL-aix.c b/clang/test/Headers/check-NULL-aix.c new file mode 100644 index 0000000000000..01bef5efd4ecd --- /dev/null +++ b/clang/test/Headers/check-NULL-aix.c @@ -0,0 +1,16 @@ +// There are at least 2 valid C null-pointer constants as defined +// by the C language standard. +// Test that the macro NULL is defined consistently by those system headers +// on AIX that have a macro definition for NULL. + +// REQUIRES: system-aix + +// RUN: %clang %s -Dheader="<dbm.h>" -E | tail -1 | FileCheck %s +// RUN: %clang %s -Dheader="<sys/dir.h>" -E | tail -1 | FileCheck %s +// RUN: %clang %s -Dheader="<sys/param.h>" -E | tail -1 | FileCheck %s +// RUN: %clang %s -Dheader="<sys/types.h>" -E | tail -1 | FileCheck %s +// RUN: %clang %s -Dheader="<unistd.h>" -E | tail -1 | FileCheck %s + +#include header +void *p = NULL; +// CHECK: ({{ *}}({{ *}}void{{ *}}*{{ *}}){{ *}}0{{ *}}) diff --git a/clang/test/Headers/check-NULL.c b/clang/test/Headers/check-NULL.c new file mode 100644 index 0000000000000..10d40b941b648 --- /dev/null +++ b/clang/test/Headers/check-NULL.c @@ -0,0 +1,15 @@ +// There are at least 2 valid C null-pointer constants as defined +// by the C language standard. +// Test that the macro NULL is defined consistently for all platforms by +// those headers that the C standard mandates a macro definition for NULL. + +// RUN: %clang %s -Dheader="<locale.h>" -E | tail -1 | FileCheck %s +// RUN: %clang %s -Dheader="<stdio.h>" -E | tail -1 | FileCheck %s +// RUN: %clang %s -Dheader="<stdlib.h>" -E | tail -1 | FileCheck %s +// RUN: %clang %s -Dheader="<string.h>" -E | tail -1 | FileCheck %s +// RUN: %clang %s -Dheader="<time.h>" -E | tail -1 | FileCheck %s +// RUN: %clang %s -Dheader="<wchar.h>" -E | tail -1 | FileCheck %s + +#include header +void *p = NULL; +// CHECK: ({{ *}}({{ *}}void{{ *}}*{{ *}}){{ *}}0{{ *}}) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits