I understand. Your project relied on an incorrect implementation of Clang header search paths, and now that the implementation has been corrected, it breaks. It's unfortunate, and I'm not sure what to advise in this situation.
FWIW, here's what a clang -v says on macOS (this is the default clang):
%
[pmbaty@mac-pro-de-pierre-marie ~]% clang -v empty.c
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx11.0.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name empty.c -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fno-strict-return -fno-rounding-math -munwind-tables -target-sdk-version=11.3 -fvisibility-inlines-hidden-static-local-var -target-cpu penryn -debugger-tuning=lldb -target-linker-version 650.9 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.5 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -I/usr/local/include -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.5/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -Wno-elaborated-enum-base -fdebug-compilation-dir /Users/pmbaty -ferror-limit 19 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fmax-type-align=16 -fcommon -fcolor-diagnostics -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation -fno-odr-hash-protocols -mllvm -disable-aligned-alloc-awareness=1 -o /var/folders/3h/8x2fp6b91p595gdvk7qsdw5w0000gn/T/empty-f6f8cd.o -x c empty.c
clang -cc1 version 12.0.5 (clang-1205.0.22.11) default target x86_64-apple-darwin20.3.0
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.5/include
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
%
The user-supplied directory list is empty here too. Which makes me believe that, contrarily to what you think, not so many projects will break. But some will sure do.
I still want to make something 100% clear, when you say:
“it's weird if recent clang thinks that "../blabla.h" shouldn't be a parent of file currently compiled.”
Actually this has never been the case (see my definition of the meaning of the #include "..." syntax for the preprocessor). This is not a particularity of clang, this is how C preprocessors have always worked, because that's what the language reference says.
I encourage you to fix your code so that it's conformant to the C specification. You'll save time in the long run, it'll make it more portable, and well, should there be one last reason, don't underestimate the importance of having learned something new today. Such a reasoning has saved me many times.
Edit: I don't want to say stupid things, so I'll refresh my memories on this topic. I'll read the reference again and post back.
Here's what GCC says:
“2.3 Search Path
By default, the preprocessor looks for header files included by the quote form of the directive #include "file" first relative to the directory of the current file, and then in a preconfigured list of standard system directories. For example, if /usr/include/sys/stat.h contains #include "types.h", GCC looks for types.h first in /usr/include/sys, then in its usual search path.”
So, #include "../blabla.h" works with GCC and I was *wrong*. Either it's a design choice by the GCC authors, or this behaviour is really how all compilers are supposed to work. I'm looking now on how this is supposed to be implemented in clang...
Well, it looks like it *really* is a Clang design choice after all. Here's what the reference says: https://en.cppreference.com/w/c/preprocessor/include
“#include "filename" (2)
2) Searches for the file in implementation-defined manner. The intent of this syntax is to search for the files that are not controlled by the implementation. Typical implementations first search the directory where the current file resides and, only if the file is not found, search the standard include directories as with (1).”
Conclusion: it's implementation-dependent. And we should look in the Clang source code for confirmation. Pah...
Okay, end word. I made a test on macOS with Clang 12 (same compiler as with the builder, except the minor version). I created a source file in a subdirectory:
% test/include-test.c
#include "../blabla.h"
int ENTRYPOINT (int argc, char **argv)
{
printf ("well, it works.\n");
exit (0);
}
%
And I put an include like yours in the current directory:
% blabla.h
#include <stdio.h>
#include <stdlib.h>
#define ENTRYPOINT main
%
Results:
%
[pmbaty@mac-pro-de-pierre-marie ~/Desktop]% clang test/include-test.c
[pmbaty@mac-pro-de-pierre-marie ~/Desktop]% ./a.out
well, it works.
[pmbaty@mac-pro-de-pierre-marie ~/Desktop]%
%
So, you *were* right and I was wrong. My apologies. The search paths implementation in my Clang compiler on Windows is dissymetrical with the Clang compiler on macOS. I'll see what I can do.