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:
Brad King committed 2016-03-07 13:52:38 -05:00
1 parent 8256d021c8
commit 72e0dc58d3
13 files changed
+49

No files matched your search

+21
View File
@@ -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);
}
}
//----------------------------------------------------------------------------
+1
View File
@@ -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;
+1
View File
@@ -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)
@@ -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)
Whitespace-only changes.
@@ -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)
Whitespace-only changes.
@@ -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)