cmMakefile: Restore nested error logic use of cmExecutionStatus

Since commit 14a8d61f (cmMakefile: Port nested error logic away from
cmExecutionStatus) we fail to continue processing function and macro
bodies after non-fatal errors.  A non-fatal error should not stop
foreach loops, macro bodies, nested bodies, or the outer script.
Add a test covering these cases, and revert the change to fix them.

Also revert commit 2af853de (cmMakefile: Simplify IssueMessage
implementation) because the assertion it added (which was removed by the
above commit and is restored by reverting it) is incorrect.  We do have
code paths that call cmMakefile::IssueMessage with an empty execution
stack, such as in CheckForUnusedVariables's LogUnused call.
This commit is contained in:
Brad King 2016-09-06 15:25:26 -04:00
parent 8317ea01aa
commit f1ad71d7f8
9 changed files with 62 additions and 16 deletions

View File

@ -40,12 +40,16 @@ public:
this->ReturnInvoked = false; this->ReturnInvoked = false;
this->BreakInvoked = false; this->BreakInvoked = false;
this->ContinueInvoked = false; this->ContinueInvoked = false;
this->NestedError = false;
} }
void SetNestedError(bool val) { this->NestedError = val; }
bool GetNestedError() { return this->NestedError; }
private: private:
bool ReturnInvoked; bool ReturnInvoked;
bool BreakInvoked; bool BreakInvoked;
bool ContinueInvoked; bool ContinueInvoked;
bool NestedError;
}; };
#endif #endif

View File

@ -76,7 +76,7 @@ public:
}; };
bool cmFunctionHelperCommand::InvokeInitialPass( bool cmFunctionHelperCommand::InvokeInitialPass(
const std::vector<cmListFileArgument>& args, cmExecutionStatus&) const std::vector<cmListFileArgument>& args, cmExecutionStatus& inStatus)
{ {
// Expand the argument list to the function. // Expand the argument list to the function.
std::vector<std::string> expandedArgs; std::vector<std::string> expandedArgs;
@ -129,11 +129,11 @@ bool cmFunctionHelperCommand::InvokeInitialPass(
for (unsigned int c = 0; c < this->Functions.size(); ++c) { for (unsigned int c = 0; c < this->Functions.size(); ++c) {
cmExecutionStatus status; cmExecutionStatus status;
if (!this->Makefile->ExecuteCommand(this->Functions[c], status) || if (!this->Makefile->ExecuteCommand(this->Functions[c], status) ||
(cmSystemTools::GetErrorOccuredFlag() && status.GetNestedError()) {
!cmSystemTools::GetFatalErrorOccured())) {
// The error message should have already included the call stack // The error message should have already included the call stack
// so we do not need to report an error here. // so we do not need to report an error here.
functionScope.Quiet(); functionScope.Quiet();
inStatus.SetNestedError(true);
return false; return false;
} }
if (status.GetReturnInvoked()) { if (status.GetReturnInvoked()) {

View File

@ -159,11 +159,11 @@ bool cmMacroHelperCommand::InvokeInitialPass(
} }
cmExecutionStatus status; cmExecutionStatus status;
if (!this->Makefile->ExecuteCommand(newLFF, status) || if (!this->Makefile->ExecuteCommand(newLFF, status) ||
(cmSystemTools::GetErrorOccuredFlag() && status.GetNestedError()) {
!cmSystemTools::GetFatalErrorOccured())) {
// The error message should have already included the call stack // The error message should have already included the call stack
// so we do not need to report an error here. // so we do not need to report an error here.
macroScope.Quiet(); macroScope.Quiet();
inStatus.SetNestedError(true);
return false; return false;
} }
if (status.GetReturnInvoked()) { if (status.GetReturnInvoked()) {

View File

@ -117,6 +117,11 @@ cmMakefile::~cmMakefile()
void cmMakefile::IssueMessage(cmake::MessageType t, void cmMakefile::IssueMessage(cmake::MessageType t,
std::string const& text) const std::string const& text) const
{ {
if (!this->ExecutionStatusStack.empty()) {
if ((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR)) {
this->ExecutionStatusStack.back()->SetNestedError(true);
}
}
this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace()); this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace());
} }
@ -277,19 +282,11 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
if (this->GetCMakeInstance()->GetTrace()) { if (this->GetCMakeInstance()->GetTrace()) {
this->PrintCommandTrace(lff); this->PrintCommandTrace(lff);
} }
// Try invoking the command.
bool hadPreviousNonFatalError = cmSystemTools::GetErrorOccuredFlag() &&
!cmSystemTools::GetFatalErrorOccured();
cmSystemTools::ResetErrorOccuredFlag();
bool invokeSucceeded = pcmd->InvokeInitialPass(lff.Arguments, status); bool invokeSucceeded = pcmd->InvokeInitialPass(lff.Arguments, status);
bool hadNestedError = cmSystemTools::GetErrorOccuredFlag() && bool hadNestedError = status.GetNestedError();
!cmSystemTools::GetFatalErrorOccured();
if (hadPreviousNonFatalError) {
cmSystemTools::SetErrorOccured();
}
if (!invokeSucceeded || hadNestedError) { if (!invokeSucceeded || hadNestedError) {
if (!hadNestedError && !cmSystemTools::GetFatalErrorOccured()) { if (!hadNestedError) {
// The command invocation requested that we report an error. // The command invocation requested that we report an error.
this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError()); this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError());
} }

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,13 @@
^CMake Error at ContinueAfterError.cmake:[0-9]+ \(message\):
error in loop body
Call Stack \(most recent call first\):
ContinueAfterError.cmake:[0-9]+ \(m\)
ContinueAfterError.cmake:[0-9]+ \(f\)
CMakeLists.txt:[0-9]+ \(include\)
+
CMake Error at ContinueAfterError.cmake:[0-9]+ \(message\):
error in loop body
Call Stack \(most recent call first\):
ContinueAfterError.cmake:[0-9]+ \(m\)
ContinueAfterError.cmake:[0-9]+ \(f\)
CMakeLists.txt:[0-9]+ \(include\)$

View File

@ -0,0 +1,11 @@
-- before f
-- start f
-- start m
-- start loop body
-- end loop body
-- start loop body
-- end loop body
-- end m
-- end f
-- after f
-- Configuring incomplete, errors occurred!

View File

@ -0,0 +1,19 @@
macro(m)
message(STATUS " start m")
foreach(i 1 2)
message(STATUS " start loop body")
message(SEND_ERROR "error in loop body")
message(STATUS " end loop body")
endforeach()
message(STATUS " end m")
endmacro()
function(f)
message(STATUS " start f")
m()
message(STATUS " end f")
endfunction()
message(STATUS "before f")
f()
message(STATUS "after f")

View File

@ -1,5 +1,6 @@
include(RunCMake) include(RunCMake)
run_cmake(ContinueAfterError)
run_cmake(CustomTargetAfterError) run_cmake(CustomTargetAfterError)
run_cmake(ErrorLogs) run_cmake(ErrorLogs)
run_cmake(FailCopyFileABI) run_cmake(FailCopyFileABI)