diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index d682ffc832c83..f4556de86b7e1 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1402,21 +1402,26 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { std::string RealMode = getExecutableForDriverMode(Mode); llvm::Triple Triple; - // If name prefix is present, no --target= override was passed via CLOptions - // and the name prefix is not a valid triple, force it for backwards - // compatibility. - if (!ClangNameParts.TargetPrefix.empty() && - computeTargetTriple(*this, "/invalid/", *CLOptions).str() == - "/invalid/") { + llvm::Triple RealTriple = + computeTargetTriple(*this, TargetTriple, *CLOptions); + + // If name prefix is present, we might prefer that over the actual triple + if (!ClangNameParts.TargetPrefix.empty()) { llvm::Triple PrefixTriple{ClangNameParts.TargetPrefix}; - if (PrefixTriple.getArch() == llvm::Triple::UnknownArch || - PrefixTriple.isOSUnknown()) + llvm::Triple NormalizedTriple{llvm::Triple::normalize(ClangNameParts.TargetPrefix)}; + // If no --target= override was passed via CLOptions + // and the name prefix is not a valid triple + if ((computeTargetTriple(*this, "/invalid/", *CLOptions).str() == + "/invalid/") && + (PrefixTriple.getArch() == llvm::Triple::UnknownArch || + PrefixTriple.isOSUnknown())) + Triple = PrefixTriple; + // If name prefix is just an unnormalised form + else if (NormalizedTriple == RealTriple) Triple = PrefixTriple; } // Otherwise, use the real triple as used by the driver. - llvm::Triple RealTriple = - computeTargetTriple(*this, TargetTriple, *CLOptions); if (Triple.str().empty()) { Triple = RealTriple; assert(!Triple.str().empty()); @@ -1442,6 +1447,12 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { if (findTripleConfigFile(ExpCtx, CfgFilePath, Triple, "-" + RealMode + ".cfg")) return readConfigFile(CfgFilePath, ExpCtx); + bool TryRealTriple = Triple != RealTriple; + if (TryRealTriple) { + if (findTripleConfigFile(ExpCtx, CfgFilePath, RealTriple, + "-" + RealMode + ".cfg")) + return readConfigFile(CfgFilePath, ExpCtx); + } bool TryModeSuffix = !ClangNameParts.ModeSuffix.empty() && ClangNameParts.ModeSuffix != RealMode; @@ -1449,6 +1460,11 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { if (findTripleConfigFile(ExpCtx, CfgFilePath, Triple, "-" + ClangNameParts.ModeSuffix + ".cfg")) return readConfigFile(CfgFilePath, ExpCtx); + if (TryRealTriple) { + if (findTripleConfigFile(ExpCtx, CfgFilePath, RealTriple, + "-" + ClangNameParts.ModeSuffix + ".cfg")) + return readConfigFile(CfgFilePath, ExpCtx); + } } // Try loading .cfg, and return if loading failed. If a matching file @@ -1467,6 +1483,10 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { // Try loading .cfg and return if we find a match. if (findTripleConfigFile(ExpCtx, CfgFilePath, Triple, ".cfg")) return readConfigFile(CfgFilePath, ExpCtx); + if (TryRealTriple) { + if (findTripleConfigFile(ExpCtx, CfgFilePath, RealTriple, ".cfg")) + return readConfigFile(CfgFilePath, ExpCtx); + } // If we were unable to find a config file deduced from executable name, // that is not an error. diff --git a/clang/test/Driver/config-file5.c b/clang/test/Driver/config-file5.c new file mode 100644 index 0000000000000..af2895c1d2520 --- /dev/null +++ b/clang/test/Driver/config-file5.c @@ -0,0 +1,64 @@ +// REQUIRES: shell +// REQUIRES: x86-registered-target + +// RUN: unset CLANG_NO_DEFAULT_CONFIG +// RUN: rm -rf %t && mkdir %t + +// --- Clang started via an alternative prefix is preferred over "real" triple. +// +// RUN: mkdir %t/testdmode +// RUN: ln -s %clang %t/testdmode/x86_64-w64-windows-gnu-clang-g++ +// RUN: ln -s %clang %t/testdmode/x86_64-w64-windows-gnu-clang +// RUN: ln -s %clang %t/testdmode/x86_64-w64-mingw32-clang-g++ +// RUN: ln -s %clang %t/testdmode/x86_64-w64-mingw32-clang +// RUN: touch %t/testdmode/x86_64-w64-windows-gnu-clang++.cfg +// RUN: touch %t/testdmode/x86_64-w64-windows-gnu-clang-g++.cfg +// RUN: touch %t/testdmode/x86_64-w64-windows-gnu-clang.cfg +// RUN: touch %t/testdmode/x86_64-w64-windows-gnu.cfg +// RUN: touch %t/testdmode/x86_64-w64-mingw32-clang++.cfg +// RUN: touch %t/testdmode/x86_64-w64-mingw32-clang-g++.cfg +// RUN: touch %t/testdmode/x86_64-w64-mingw32-clang.cfg +// RUN: touch %t/testdmode/x86_64-w64-mingw32.cfg +// RUN: touch %t/testdmode/clang++.cfg +// RUN: touch %t/testdmode/clang-g++.cfg +// RUN: touch %t/testdmode/clang.cfg +// RUN: %t/testdmode/x86_64-w64-mingw32-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1-ALT --implicit-check-not 'Configuration file:' +// +// FULL1-ALT: Configuration file: {{.*}}/testdmode/x86_64-w64-mingw32-clang++.cfg + +// --- Test fallback to real triple. +// +// RUN: rm %t/testdmode/x86_64-w64-mingw32-clang++.cfg +// RUN: %t/testdmode/x86_64-w64-mingw32-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL2-ALT --implicit-check-not 'Configuration file:' +// +// FULL2-ALT: Configuration file: {{.*}}/testdmode/x86_64-w64-windows-gnu-clang++.cfg + +// --- Test fallback to x86_64-w64-mingw32-clang-g++.cfg. +// +// RUN: rm %t/testdmode/x86_64-w64-windows-gnu-clang++.cfg +// RUN: %t/testdmode/x86_64-w64-mingw32-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL3-ALT --implicit-check-not 'Configuration file:' +// +// FULL3-ALT: Configuration file: {{.*}}/testdmode/x86_64-w64-mingw32-clang-g++.cfg + +// --- Test fallback to real triple. +// +// RUN: rm %t/testdmode/x86_64-w64-mingw32-clang-g++.cfg +// RUN: %t/testdmode/x86_64-w64-mingw32-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL4-ALT --implicit-check-not 'Configuration file:' +// +// FULL4-ALT: Configuration file: {{.*}}/testdmode/x86_64-w64-windows-gnu-clang-g++.cfg + +//--- Test fallback to x86_64-w64-mingw32.cfg + clang++.cfg. +// +// RUN: rm %t/testdmode/x86_64-w64-windows-gnu-clang-g++.cfg +// RUN: %t/testdmode/x86_64-w64-mingw32-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix ALT-FALLBACK1 --implicit-check-not 'Configuration file:' +// +// ALT-FALLBACK1: Configuration file: {{.*}}/testdmode/clang++.cfg +// ALT-FALLBACK1: Configuration file: {{.*}}/testdmode/x86_64-w64-mingw32.cfg + +// --- Test fallback to real triple. +// +// RUN: rm %t/testdmode/x86_64-w64-mingw32.cfg +// RUN: %t/testdmode/x86_64-w64-mingw32-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix ALT-FALLBACK2 --implicit-check-not 'Configuration file:' +// +// ALT-FALLBACK2: Configuration file: {{.*}}/testdmode/clang++.cfg +// ALT-FALLBACK2: Configuration file: {{.*}}/testdmode/x86_64-w64-windows-gnu.cfg