Commit 72e0dc58 authored by Brad King's avatar Brad King

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.
parent 8256d021
......@@ -398,6 +398,21 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
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)
{
// 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();
}
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
std::map<std::string, bool> IgnoreExtensions;
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> LanguageToOutputExtension;
std::map<std::string, std::string> ExtensionToLanguage;
......
......@@ -152,6 +152,7 @@ add_RunCMake_test(ObjectLibrary)
add_RunCMake_test(Swift)
add_RunCMake_test(TargetObjects)
add_RunCMake_test(TargetSources)
add_RunCMake_test(ToolchainFile)
add_RunCMake_test(find_dependency)
add_RunCMake_test(CompileDefinitions)
add_RunCMake_test(CompileFeatures)
......
cmake_minimum_required(VERSION 3.5)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
^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\)$
^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\)$
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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment