Diagnose recursive project/enable_language without crashing (#15999)
Calling `project()` or `enable_language()` from a toolchain file will infinitely recurse since those commands load the toolchain file. Diagnose and reject this case with an error message instead of crashing when the stack eventually overflows.
This commit is contained in:
parent
8256d021c8
commit
72e0dc58d3
|
@ -398,6 +398,21 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<std::string> cur_languages(languages.begin(), languages.end());
|
||||||
|
for (std::set<std::string>::iterator li = cur_languages.begin();
|
||||||
|
li != cur_languages.end(); ++li)
|
||||||
|
{
|
||||||
|
if (!this->LanguagesInProgress.insert(*li).second)
|
||||||
|
{
|
||||||
|
std::ostringstream e;
|
||||||
|
e << "Language '" << *li << "' is currently being enabled. "
|
||||||
|
"Recursive call not allowed.";
|
||||||
|
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||||
|
cmSystemTools::SetFatalErrorOccured();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(this->TryCompileOuterMakefile)
|
if(this->TryCompileOuterMakefile)
|
||||||
{
|
{
|
||||||
// In a try-compile we can only enable languages provided by caller.
|
// In a try-compile we can only enable languages provided by caller.
|
||||||
|
@ -823,6 +838,12 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
|
||||||
{
|
{
|
||||||
cmSystemTools::SetFatalErrorOccured();
|
cmSystemTools::SetFatalErrorOccured();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (std::set<std::string>::iterator li = cur_languages.begin();
|
||||||
|
li != cur_languages.end(); ++li)
|
||||||
|
{
|
||||||
|
this->LanguagesInProgress.erase(*li);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -457,6 +457,7 @@ private:
|
||||||
// in EnableLanguagesFromGenerator
|
// in EnableLanguagesFromGenerator
|
||||||
std::map<std::string, bool> IgnoreExtensions;
|
std::map<std::string, bool> IgnoreExtensions;
|
||||||
std::set<std::string> LanguagesReady; // Ready for try_compile
|
std::set<std::string> LanguagesReady; // Ready for try_compile
|
||||||
|
std::set<std::string> LanguagesInProgress;
|
||||||
std::map<std::string, std::string> OutputExtensions;
|
std::map<std::string, std::string> OutputExtensions;
|
||||||
std::map<std::string, std::string> LanguageToOutputExtension;
|
std::map<std::string, std::string> LanguageToOutputExtension;
|
||||||
std::map<std::string, std::string> ExtensionToLanguage;
|
std::map<std::string, std::string> ExtensionToLanguage;
|
||||||
|
|
|
@ -152,6 +152,7 @@ add_RunCMake_test(ObjectLibrary)
|
||||||
add_RunCMake_test(Swift)
|
add_RunCMake_test(Swift)
|
||||||
add_RunCMake_test(TargetObjects)
|
add_RunCMake_test(TargetObjects)
|
||||||
add_RunCMake_test(TargetSources)
|
add_RunCMake_test(TargetSources)
|
||||||
|
add_RunCMake_test(ToolchainFile)
|
||||||
add_RunCMake_test(find_dependency)
|
add_RunCMake_test(find_dependency)
|
||||||
add_RunCMake_test(CompileDefinitions)
|
add_RunCMake_test(CompileDefinitions)
|
||||||
add_RunCMake_test(CompileFeatures)
|
add_RunCMake_test(CompileFeatures)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
^CMake Error at CallEnableLanguage-toolchain.cmake:[0-9]+ \(enable_language\):
|
||||||
|
Language 'NONE' is currently being enabled. Recursive call not allowed.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
.*/Modules/CMakeDetermineSystem.cmake:[0-9]+ \(include\)
|
||||||
|
CMakeLists.txt:[0-9]+ \(project\)$
|
|
@ -0,0 +1 @@
|
||||||
|
enable_language(NONE)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
^CMake Error at CallProject-toolchain.cmake:[0-9]+ \(project\):
|
||||||
|
Language 'NONE' is currently being enabled. Recursive call not allowed.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
.*/Modules/CMakeDetermineSystem.cmake:[0-9]+ \(include\)
|
||||||
|
CMakeLists.txt:[0-9]+ \(project\)$
|
|
@ -0,0 +1 @@
|
||||||
|
project(Bad NONE)
|
|
@ -0,0 +1,9 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
function(run_cmake_toolchain t)
|
||||||
|
set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/${t}-toolchain.cmake)
|
||||||
|
run_cmake(${t})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
run_cmake_toolchain(CallEnableLanguage)
|
||||||
|
run_cmake_toolchain(CallProject)
|
Loading…
Reference in New Issue