From d54617d0068fc5acfa2079d1e8de8f38365564ab Mon Sep 17 00:00:00 2001 From: Gregor Jasny Date: Tue, 18 Nov 2014 16:34:32 +0100 Subject: [PATCH] break: Add policy CMP0055 to check calls strictly Reject break() without loop scope or any arguments. Signed-off-by: Gregor Jasny --- Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0055.rst | 17 +++++ Help/release/dev/break-command-strictness.rst | 6 ++ Source/cmBreakCommand.cxx | 68 ++++++++++++++++++- Source/cmPolicies.cxx | 5 ++ Source/cmPolicies.h | 1 + .../CMP0055-NEW-Out-of-Scope-result.txt | 1 + .../CMP0055-NEW-Out-of-Scope-stderr.txt | 4 ++ .../CMP0055/CMP0055-NEW-Out-of-Scope.cmake | 4 ++ .../CMP0055-NEW-Reject-Arguments-result.txt | 1 + .../CMP0055-NEW-Reject-Arguments-stderr.txt | 4 ++ .../CMP0055-NEW-Reject-Arguments.cmake | 6 ++ .../CMP0055-OLD-Out-of-Scope-result.txt | 1 + .../CMP0055-OLD-Out-of-Scope-stderr.txt | 1 + .../CMP0055/CMP0055-OLD-Out-of-Scope.cmake | 4 ++ .../CMP0055-OLD-Reject-Arguments-result.txt | 1 + .../CMP0055-OLD-Reject-Arguments-stderr.txt | 1 + .../CMP0055-OLD-Reject-Arguments.cmake | 6 ++ .../CMP0055-WARN-Out-of-Scope-result.txt | 1 + .../CMP0055-WARN-Out-of-Scope-stderr.txt | 9 +++ .../CMP0055/CMP0055-WARN-Out-of-Scope.cmake | 2 + .../CMP0055-WARN-Reject-Arguments-result.txt | 1 + .../CMP0055-WARN-Reject-Arguments-stderr.txt | 9 +++ .../CMP0055-WARN-Reject-Arguments.cmake | 4 ++ Tests/RunCMake/CMP0055/CMakeLists.txt | 3 + Tests/RunCMake/CMP0055/RunCMakeTest.cmake | 9 +++ Tests/RunCMake/CMakeLists.txt | 1 + 27 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 Help/policy/CMP0055.rst create mode 100644 Help/release/dev/break-command-strictness.rst create mode 100644 Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake create mode 100644 Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake create mode 100644 Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-stderr.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake create mode 100644 Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake create mode 100644 Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake create mode 100644 Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt create mode 100644 Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake create mode 100644 Tests/RunCMake/CMP0055/CMakeLists.txt create mode 100644 Tests/RunCMake/CMP0055/RunCMakeTest.cmake diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 7074bd5dc..742fd6362 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -112,3 +112,4 @@ All Policies /policy/CMP0052 /policy/CMP0053 /policy/CMP0054 + /policy/CMP0055 diff --git a/Help/policy/CMP0055.rst b/Help/policy/CMP0055.rst new file mode 100644 index 000000000..fe7ab6f6d --- /dev/null +++ b/Help/policy/CMP0055.rst @@ -0,0 +1,17 @@ +CMP0055 +------- + +Strict checking for the :command:`break` command. + +CMake 3.1 and lower allowed calls to the :command:`break` command +outside of a loop context and also ignored any given arguments. +This was undefined behavior. + +The OLD behavior for this policy is to allow :command:`break` to be placed +outside of loop contexts and ignores any arguments. The NEW behavior for this +policy is to issue an error if a misplaced break or any arguments are found. + +This policy was introduced in CMake version 3.2. +CMake version |release| warns when the policy is not set and uses +OLD behavior. Use the cmake_policy command to set it to OLD or +NEW explicitly. diff --git a/Help/release/dev/break-command-strictness.rst b/Help/release/dev/break-command-strictness.rst new file mode 100644 index 000000000..0723774ed --- /dev/null +++ b/Help/release/dev/break-command-strictness.rst @@ -0,0 +1,6 @@ +break-command-strictness +------------------------ + +* The :command:`break` command now rejects calls outside of a loop + context or that pass arguments to the command. + See policy :policy:`CMP0055`. diff --git a/Source/cmBreakCommand.cxx b/Source/cmBreakCommand.cxx index b70e40088..ff527db54 100644 --- a/Source/cmBreakCommand.cxx +++ b/Source/cmBreakCommand.cxx @@ -12,10 +12,76 @@ #include "cmBreakCommand.h" // cmBreakCommand -bool cmBreakCommand::InitialPass(std::vector const&, +bool cmBreakCommand::InitialPass(std::vector const &args, cmExecutionStatus &status) { + if(!this->Makefile->IsLoopBlock()) + { + bool issueMessage = true; + cmOStringStream e; + cmake::MessageType messageType = cmake::AUTHOR_WARNING; + switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) + { + case cmPolicies::WARN: + e << (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0055)) << "\n"; + break; + case cmPolicies::OLD: + issueMessage = false; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + messageType = cmake::FATAL_ERROR; + break; + } + + if(issueMessage) + { + e << "A BREAK command was found outside of a proper " + "FOREACH or WHILE loop scope."; + this->Makefile->IssueMessage(messageType, e.str()); + if(messageType == cmake::FATAL_ERROR) + { + return false; + } + } + } + status.SetBreakInvoked(true); + + if(!args.empty()) + { + bool issueMessage = true; + cmOStringStream e; + cmake::MessageType messageType = cmake::AUTHOR_WARNING; + switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) + { + case cmPolicies::WARN: + e << (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0055)) << "\n"; + break; + case cmPolicies::OLD: + issueMessage = false; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + messageType = cmake::FATAL_ERROR; + break; + } + + if(issueMessage) + { + e << "The BREAK command does not accept any arguments."; + this->Makefile->IssueMessage(messageType, e.str()); + if(messageType == cmake::FATAL_ERROR) + { + return false; + } + } + } + return true; } diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index a420f5958..64b87b730 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -364,6 +364,11 @@ cmPolicies::cmPolicies() CMP0054, "CMP0054", "Only interpret if() arguments as variables or keywords when unquoted.", 3,1,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0055, "CMP0055", + "Strict checking for break() command.", + 3,2,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 7c73da82b..46ecc22ad 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -111,6 +111,7 @@ public: CMP0053, ///< Simplify variable reference and escape sequence evaluation CMP0054, ///< Only interpret if() arguments as variables /// or keywords when unquoted. + CMP0055, ///< Strict checking for break() command. /** \brief Always the last entry. * diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt new file mode 100644 index 000000000..27e81405d --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CMP0055-NEW-Out-of-Scope.cmake:4 \(break\): + A BREAK command was found outside of a proper FOREACH or WHILE loop scope. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake new file mode 100644 index 000000000..53ac214ad --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0055 NEW) + +break() diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt new file mode 100644 index 000000000..32947af2a --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CMP0055-NEW-Reject-Arguments.cmake:5 \(break\): + The BREAK command does not accept any arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake new file mode 100644 index 000000000..52eaa6aa5 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake @@ -0,0 +1,6 @@ + +cmake_policy(SET CMP0055 NEW) + +foreach(i RANGE 1 2) + break(1) +endforeach() \ No newline at end of file diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-stderr.txt new file mode 100644 index 000000000..10f32932e --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake new file mode 100644 index 000000000..57195c248 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0055 OLD) + +break() diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt new file mode 100644 index 000000000..10f32932e --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake new file mode 100644 index 000000000..d8fdddf10 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake @@ -0,0 +1,6 @@ + +cmake_policy(SET CMP0055 OLD) + +foreach(i RANGE 1 2) + break(1) +endforeach() \ No newline at end of file diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt new file mode 100644 index 000000000..ad850ac93 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt @@ -0,0 +1,9 @@ +CMake Warning \(dev\) at CMP0055-WARN-Out-of-Scope.cmake:2 \(break\): + Policy CMP0055 is not set: Strict checking for break\(\) command. Run "cmake + --help-policy CMP0055" for policy details. Use the cmake_policy command to + set the policy and suppress this warning. + + A BREAK command was found outside of a proper FOREACH or WHILE loop scope. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake new file mode 100644 index 000000000..373a95a7c --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake @@ -0,0 +1,2 @@ + +break() diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt new file mode 100644 index 000000000..3cc686dc0 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt @@ -0,0 +1,9 @@ +CMake Warning \(dev\) at CMP0055-WARN-Reject-Arguments.cmake:3 \(break\): + Policy CMP0055 is not set: Strict checking for break\(\) command. Run "cmake + --help-policy CMP0055" for policy details. Use the cmake_policy command to + set the policy and suppress this warning. + + The BREAK command does not accept any arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake new file mode 100644 index 000000000..ec6b90f8a --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake @@ -0,0 +1,4 @@ + +foreach(i RANGE 1 2) + break(1) +endforeach() diff --git a/Tests/RunCMake/CMP0055/CMakeLists.txt b/Tests/RunCMake/CMP0055/CMakeLists.txt new file mode 100644 index 000000000..ef2163c29 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.1) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0055/RunCMakeTest.cmake b/Tests/RunCMake/CMP0055/RunCMakeTest.cmake new file mode 100644 index 000000000..efcfcab67 --- /dev/null +++ b/Tests/RunCMake/CMP0055/RunCMakeTest.cmake @@ -0,0 +1,9 @@ +include(RunCMake) + +run_cmake(CMP0055-OLD-Out-of-Scope) +run_cmake(CMP0055-NEW-Out-of-Scope) +run_cmake(CMP0055-WARN-Out-of-Scope) + +run_cmake(CMP0055-OLD-Reject-Arguments) +run_cmake(CMP0055-NEW-Reject-Arguments) +run_cmake(CMP0055-WARN-Reject-Arguments) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index c5825fe6c..8721ece57 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -49,6 +49,7 @@ add_RunCMake_test(CMP0050) add_RunCMake_test(CMP0051) add_RunCMake_test(CMP0053) add_RunCMake_test(CMP0054) +add_RunCMake_test(CMP0055) add_RunCMake_test(CTest) if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja") add_RunCMake_test(CompilerChange)