summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2020-10-22 20:50:42 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2020-10-22 21:04:31 (GMT)
commit8aee7fdb32a7099e3e4efdf1bf0a00732ee1c46b (patch)
tree3854ce6ac00cc25aa55905af070f2b91d0569504
parent3a82ff6a11d643c4a5959f65ea538a3b60784a16 (diff)
downloadCMake-8aee7fdb32a7099e3e4efdf1bf0a00732ee1c46b.zip
CMake-8aee7fdb32a7099e3e4efdf1bf0a00732ee1c46b.tar.gz
CMake-8aee7fdb32a7099e3e4efdf1bf0a00732ee1c46b.tar.bz2
cmState: Prohibit override of flow control commands
-rw-r--r--Source/cmCommands.cxx17
-rw-r--r--Source/cmFunctionCommand.cxx7
-rw-r--r--Source/cmLoadCommandCommand.cxx11
-rw-r--r--Source/cmMacroCommand.cxx7
-rw-r--r--Source/cmState.cxx31
-rw-r--r--Source/cmState.h8
-rw-r--r--Tests/RunCMake/Syntax/Override.cmake6
-rw-r--r--Tests/RunCMake/Syntax/OverrideBreak-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideContinue-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideElse-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideElseIf-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideEndForeach-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideEndFunction-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideEndIf-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideEndMacro-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideEndWhile-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideForeach-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideFunction-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideIf-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideMacro-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideReturn-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/OverrideWhile-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/RunCMakeTest.cmake27
23 files changed, 108 insertions, 21 deletions
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 37be542..9e5b783 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -119,12 +119,19 @@
void GetScriptingCommands(cmState* state)
{
- state->AddBuiltinCommand("break", cmBreakCommand);
+ state->AddFlowControlCommand("break", cmBreakCommand);
+ state->AddFlowControlCommand("continue", cmContinueCommand);
+ state->AddFlowControlCommand("foreach", cmForEachCommand);
+ state->AddFlowControlCommand("function", cmFunctionCommand);
+ state->AddFlowControlCommand("if", cmIfCommand);
+ state->AddFlowControlCommand("macro", cmMacroCommand);
+ state->AddFlowControlCommand("return", cmReturnCommand);
+ state->AddFlowControlCommand("while", cmWhileCommand);
+
state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired);
state->AddBuiltinCommand("cmake_path", cmCMakePathCommand);
state->AddBuiltinCommand("cmake_policy", cmCMakePolicyCommand);
state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
- state->AddBuiltinCommand("continue", cmContinueCommand);
state->AddBuiltinCommand("exec_program", cmExecProgramCommand);
state->AddBuiltinCommand("execute_process", cmExecuteProcessCommand);
state->AddBuiltinCommand("file", cmFileCommand);
@@ -133,26 +140,21 @@ void GetScriptingCommands(cmState* state)
state->AddBuiltinCommand("find_package", cmFindPackage);
state->AddBuiltinCommand("find_path", cmFindPath);
state->AddBuiltinCommand("find_program", cmFindProgram);
- state->AddBuiltinCommand("foreach", cmForEachCommand);
- state->AddBuiltinCommand("function", cmFunctionCommand);
state->AddBuiltinCommand("get_cmake_property", cmGetCMakePropertyCommand);
state->AddBuiltinCommand("get_directory_property",
cmGetDirectoryPropertyCommand);
state->AddBuiltinCommand("get_filename_component",
cmGetFilenameComponentCommand);
state->AddBuiltinCommand("get_property", cmGetPropertyCommand);
- state->AddBuiltinCommand("if", cmIfCommand);
state->AddBuiltinCommand("include", cmIncludeCommand);
state->AddBuiltinCommand("include_guard", cmIncludeGuardCommand);
state->AddBuiltinCommand("list", cmListCommand);
- state->AddBuiltinCommand("macro", cmMacroCommand);
state->AddBuiltinCommand("make_directory", cmMakeDirectoryCommand);
state->AddBuiltinCommand("mark_as_advanced", cmMarkAsAdvancedCommand);
state->AddBuiltinCommand("math", cmMathCommand);
state->AddBuiltinCommand("message", cmMessageCommand);
state->AddBuiltinCommand("option", cmOptionCommand);
state->AddBuiltinCommand("cmake_parse_arguments", cmParseArgumentsCommand);
- state->AddBuiltinCommand("return", cmReturnCommand);
state->AddBuiltinCommand("separate_arguments", cmSeparateArgumentsCommand);
state->AddBuiltinCommand("set", cmSetCommand);
state->AddBuiltinCommand("set_directory_properties",
@@ -161,7 +163,6 @@ void GetScriptingCommands(cmState* state)
state->AddBuiltinCommand("site_name", cmSiteNameCommand);
state->AddBuiltinCommand("string", cmStringCommand);
state->AddBuiltinCommand("unset", cmUnsetCommand);
- state->AddBuiltinCommand("while", cmWhileCommand);
state->AddUnexpectedCommand(
"else",
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 71c82d6..1359009 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -163,8 +163,11 @@ bool cmFunctionFunctionBlocker::Replay(
f.FilePath = this->GetStartingContext().FilePath;
f.Line = this->GetStartingContext().Line;
mf.RecordPolicies(f.Policies);
- mf.GetState()->AddScriptedCommand(this->Args.front(), std::move(f));
- return true;
+ return mf.GetState()->AddScriptedCommand(
+ this->Args.front(),
+ BT<cmState::Command>(std::move(f),
+ mf.GetBacktrace().Push(this->GetStartingContext())),
+ mf);
}
} // anonymous namespace
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 5790e16..adebe02 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -24,6 +24,7 @@
#include "cmCommand.h"
#include "cmDynamicLoader.h"
#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -36,8 +37,6 @@
# include <malloc.h> /* for malloc/free on QNX */
#endif
-class cmListFileBacktrace;
-
namespace {
const char* LastName = nullptr;
@@ -256,10 +255,12 @@ bool cmLoadCommandCommand(std::vector<std::string> const& args,
// if the symbol is found call it to set the name on the
// function blocker
if (initFunction) {
- status.GetMakefile().GetState()->AddScriptedCommand(
+ return status.GetMakefile().GetState()->AddScriptedCommand(
args[0],
- cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)));
- return true;
+ BT<cmState::Command>(
+ cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)),
+ status.GetMakefile().GetBacktrace()),
+ status.GetMakefile());
}
status.SetError("Attempt to load command failed. "
"No init function found.");
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 98f88c1..8c4b2a7 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -171,8 +171,11 @@ bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
f.Functions = std::move(functions);
f.FilePath = this->GetStartingContext().FilePath;
mf.RecordPolicies(f.Policies);
- mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
- return true;
+ return mf.GetState()->AddScriptedCommand(
+ this->Args[0],
+ BT<cmState::Command>(std::move(f),
+ mf.GetBacktrace().Push(this->GetStartingContext())),
+ mf);
}
}
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index d5ac9ae..77665f1 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -436,6 +436,19 @@ void cmState::AddBuiltinCommand(std::string const& name,
});
}
+void cmState::AddFlowControlCommand(std::string const& name, Command command)
+{
+ this->FlowControlCommands.insert(name);
+ this->AddBuiltinCommand(name, std::move(command));
+}
+
+void cmState::AddFlowControlCommand(std::string const& name,
+ BuiltinCommand command)
+{
+ this->FlowControlCommands.insert(name);
+ this->AddBuiltinCommand(name, command);
+}
+
void cmState::AddDisallowedCommand(std::string const& name,
BuiltinCommand command,
cmPolicies::PolicyID policy,
@@ -465,7 +478,7 @@ void cmState::AddDisallowedCommand(std::string const& name,
void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
{
- this->AddBuiltinCommand(
+ this->AddFlowControlCommand(
name,
[name, error](std::vector<cmListFileArgument> const&,
cmExecutionStatus& status) -> bool {
@@ -480,16 +493,28 @@ void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
});
}
-void cmState::AddScriptedCommand(std::string const& name, Command command)
+bool cmState::AddScriptedCommand(std::string const& name, BT<Command> command,
+ cmMakefile& mf)
{
std::string sName = cmSystemTools::LowerCase(name);
+ if (this->FlowControlCommands.count(sName)) {
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Built-in flow control command \"", sName,
+ "\" cannot be overridden."),
+ command.Backtrace);
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
// if the command already exists, give a new name to the old command.
if (Command oldCmd = this->GetCommandByExactName(sName)) {
this->ScriptedCommands["_" + sName] = oldCmd;
}
- this->ScriptedCommands[sName] = std::move(command);
+ this->ScriptedCommands[sName] = std::move(command.Value);
+ return true;
}
cmState::Command cmState::GetCommand(std::string const& name) const
diff --git a/Source/cmState.h b/Source/cmState.h
index 2aa57e0..0744f64 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -9,6 +9,7 @@
#include <set>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "cmDefinitions.h"
@@ -24,6 +25,7 @@
class cmCacheManager;
class cmCommand;
class cmGlobVerificationManager;
+class cmMakefile;
class cmStateSnapshot;
class cmMessenger;
class cmExecutionStatus;
@@ -157,10 +159,13 @@ public:
std::unique_ptr<cmCommand> command);
void AddBuiltinCommand(std::string const& name, Command command);
void AddBuiltinCommand(std::string const& name, BuiltinCommand command);
+ void AddFlowControlCommand(std::string const& name, Command command);
+ void AddFlowControlCommand(std::string const& name, BuiltinCommand command);
void AddDisallowedCommand(std::string const& name, BuiltinCommand command,
cmPolicies::PolicyID policy, const char* message);
void AddUnexpectedCommand(std::string const& name, const char* error);
- void AddScriptedCommand(std::string const& name, Command command);
+ bool AddScriptedCommand(std::string const& name, BT<Command> command,
+ cmMakefile& mf);
void RemoveBuiltinCommand(std::string const& name);
void RemoveUserDefinedCommands();
std::vector<std::string> GetCommandNames() const;
@@ -223,6 +228,7 @@ private:
std::vector<std::string> EnabledLanguages;
std::unordered_map<std::string, Command> BuiltinCommands;
std::unordered_map<std::string, Command> ScriptedCommands;
+ std::unordered_set<std::string> FlowControlCommands;
cmPropertyMap GlobalProperties;
std::unique_ptr<cmCacheManager> CacheManager;
std::unique_ptr<cmGlobVerificationManager> GlobVerificationManager;
diff --git a/Tests/RunCMake/Syntax/Override.cmake b/Tests/RunCMake/Syntax/Override.cmake
new file mode 100644
index 0000000..af62db1
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Override.cmake
@@ -0,0 +1,6 @@
+function(override)
+ function(${FUNCTION_NAME})
+ endfunction()
+endfunction()
+override()
+message(FATAL_ERROR "This shouldn't happen")
diff --git a/Tests/RunCMake/Syntax/OverrideBreak-result.txt b/Tests/RunCMake/Syntax/OverrideBreak-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideBreak-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideContinue-result.txt b/Tests/RunCMake/Syntax/OverrideContinue-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideContinue-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideElse-result.txt b/Tests/RunCMake/Syntax/OverrideElse-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideElse-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideElseIf-result.txt b/Tests/RunCMake/Syntax/OverrideElseIf-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideElseIf-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideEndForeach-result.txt b/Tests/RunCMake/Syntax/OverrideEndForeach-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideEndForeach-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideEndFunction-result.txt b/Tests/RunCMake/Syntax/OverrideEndFunction-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideEndFunction-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideEndIf-result.txt b/Tests/RunCMake/Syntax/OverrideEndIf-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideEndIf-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideEndMacro-result.txt b/Tests/RunCMake/Syntax/OverrideEndMacro-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideEndMacro-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideEndWhile-result.txt b/Tests/RunCMake/Syntax/OverrideEndWhile-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideEndWhile-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideForeach-result.txt b/Tests/RunCMake/Syntax/OverrideForeach-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideForeach-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideFunction-result.txt b/Tests/RunCMake/Syntax/OverrideFunction-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideFunction-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideIf-result.txt b/Tests/RunCMake/Syntax/OverrideIf-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideIf-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideMacro-result.txt b/Tests/RunCMake/Syntax/OverrideMacro-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideMacro-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideReturn-result.txt b/Tests/RunCMake/Syntax/OverrideReturn-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideReturn-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/OverrideWhile-result.txt b/Tests/RunCMake/Syntax/OverrideWhile-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OverrideWhile-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/RunCMakeTest.cmake b/Tests/RunCMake/Syntax/RunCMakeTest.cmake
index 8d74dc1..3fc769d 100644
--- a/Tests/RunCMake/Syntax/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Syntax/RunCMakeTest.cmake
@@ -122,3 +122,30 @@ run_cmake(FunctionUnmatched)
run_cmake(FunctionUnmatchedForeach)
run_cmake(MacroUnmatched)
run_cmake(MacroUnmatchedForeach)
+
+function(run_override name)
+ string(TOLOWER "${name}" lname)
+ set(RunCMake_DEFAULT_stderr "^CMake Error at [^
+]*/Tests/RunCMake/Syntax/Override\\.cmake:[0-9]+ \\(function\\):
+ Built-in flow control command \"${lname}\" cannot be overridden\\.
+Call Stack \\(most recent call first\\):
+ [^
+]*/Tests/RunCMake/Syntax/Override\\.cmake:[0-9]+ \\(override\\)$")
+ run_cmake_command(Override${name} "${CMAKE_COMMAND}" -DFUNCTION_NAME=${name} -P "${RunCMake_SOURCE_DIR}/Override.cmake")
+endfunction()
+
+run_override(Break)
+run_override(Continue)
+run_override(Else)
+run_override(ElseIf)
+run_override(EndForeach)
+run_override(EndFunction)
+run_override(EndIf)
+run_override(EndMacro)
+run_override(EndWhile)
+run_override(Foreach)
+run_override(Function)
+run_override(If)
+run_override(Macro)
+run_override(Return)
+run_override(While)