diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -398,6 +398,8 @@ PCH or modules. When Clang hits this limit, it now produces notes mentioning which header and source files are consuming large amounts of this space. ``#pragma clang __debug sloc_usage`` can also be used to request this report. +- Clang will implicitly add ``#include "stdc-predef.h"`` on musl-based systems + as GCC does. Non-comprehensive list of changes in this release ------------------------------------------------- diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -636,6 +636,12 @@ if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl()) addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude); + + // Add an implicit include for musl-based non-free-standing systems. + if (!DriverArgs.hasArg(options::OPT_ffreestanding) && getTriple().isMusl()) { + CC1Args.push_back("-include"); + CC1Args.push_back("stdc-predef.h"); + } } void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, diff --git a/clang/test/Driver/Inputs/stdc-predef/usr/include/stdc-predef.h b/clang/test/Driver/Inputs/stdc-predef/usr/include/stdc-predef.h new file mode 100644 --- /dev/null +++ b/clang/test/Driver/Inputs/stdc-predef/usr/include/stdc-predef.h @@ -0,0 +1,4 @@ +#ifndef _STDC_PREDEF_H +#define _STDC_PREDEF_H 1 +#define DUMMY_STDC_PREDEF 1 +#endif diff --git a/clang/test/Driver/stdc-predef.c b/clang/test/Driver/stdc-predef.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/stdc-predef.c @@ -0,0 +1,62 @@ +// Test that clang preincludes stdc-predef.h, if we are using libc that does not +// pre-include it, e.g. Musl + +// Musl-based systems need this addition include. +// +// RUN: %clang %s -### -c 2>&1 \ +// RUN: -target x86_64-unknown-linux-musl \ +// RUN: --sysroot=%S/Inputs/stdc-predef \ +// RUN: | FileCheck -check-prefix CHECK-CPP-FLAG %s + +// GNU-based systems do not need this addition include. +// +// RUN: %clang %s -### -c -ffreestanding 2>&1 \ +// RUN: -target x86_64-unknown-linux-gnu \ +// RUN: --sysroot=%S/Inputs/stdc-predef \ +// RUN: | FileCheck --implicit-check-not "stdc-predef.h" %s + +// Freestanding compilations do not need this addition include. +// +// RUN: %clang %s -### -c 2>&1 \ +// RUN: -target x86_64-unknown-linux-musl -ffreestanding \ +// RUN: --sysroot=%S/Inputs/stdc-predef \ +// RUN: | FileCheck --implicit-check-not "stdc-predef.h" %s + +// Because this behavior is implemented by adding preprocessor flags in the +// driver, disabling preprocessing means the include flag should not appear. +// +// RUN: %clang -x cpp-output %s -### -c 2>&1 \ +// RUN: -target x86_64-unknown-linux-musl \ +// RUN: --sysroot=%S/Inputs/stdc-predef \ +// RUN: | FileCheck --implicit-check-not "stdc-predef.h" %s + +// This behavior should appear in all files clang accepted that use the C +// preprocessor, including C, C++ and Objective-C files, as long as the system +// uses musl. +// +// RUN: %clang -x objective-c %s -### -c 2>&1 \ +// RUN: -target x86_64-unknown-linux-musl \ +// RUN: --sysroot=%S/Inputs/stdc-predef \ +// RUN: | FileCheck -check-prefix CHECK-CPP-FLAG %s + +// If a musl-based system does not have this header, give an error at line 1. +// +// RUN: %clang %s -c -Xclang -verify=expected 2>&1 \ +// RUN: -target x86_64-unknown-linux-musl \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree +// expected-error@1 {{'stdc-predef.h' file not found}} + +// Check if the file is really included by macro. +// +// RUN: %clang %s -c -Xclang -verify=ok -DCHECK_DUMMY=1 \ +// RUN: -target x86_64-unknown-linux-musl \ +// RUN: --sysroot=%S/Inputs/stdc-predef +// ok-no-diagnostics + +// CHECK-CPP-FLAG: "-include" "stdc-predef.h" +int i; +#if CHECK_DUMMY +#if !DUMMY_STDC_PREDEF + #error "Expected macro symbol DUMMY_STDC_PREDEF is not defined." +#endif +#endif diff --git a/clang/test/Driver/stdc-predef.i b/clang/test/Driver/stdc-predef.i new file mode 100644 --- /dev/null +++ b/clang/test/Driver/stdc-predef.i @@ -0,0 +1,9 @@ +// The automatic preinclude of stdc-predef.h should not occur if +// the source filename indicates a preprocessed file. +// +// RUN: %clang %s -### -c 2>&1 \ +// RUN: --sysroot=%S/Inputs/stdc-predef \ +// RUN: -target x86_64-unknown-linux-musl \ +// RUN: | FileCheck --implicit-check-not "stdc-predef.h" %s + +int i;