diff --git a/tensorflow/lite/core/subgraph.cc b/tensorflow/lite/core/subgraph.cc index 14e2a02c605..1219e9709da 100644 --- a/tensorflow/lite/core/subgraph.cc +++ b/tensorflow/lite/core/subgraph.cc @@ -1488,6 +1488,11 @@ TfLiteStatus Subgraph::ModifyGraphWithDelegate(TfLiteDelegate* delegate) { TFLITE_SCOPED_TAGGED_DEFAULT_PROFILE(profiler_.get(), "ModifyGraphWithDelegate"); + if (delegate == nullptr) { + ReportError("Null delegate."); + return kTfLiteDelegateError; + } + // Restore delegation state if applicable. TF_LITE_ENSURE_STATUS(RedoAllDelegates()); diff --git a/tensorflow/lite/core/subgraph.h b/tensorflow/lite/core/subgraph.h index 68a67265155..2ef76df9b3e 100644 --- a/tensorflow/lite/core/subgraph.h +++ b/tensorflow/lite/core/subgraph.h @@ -552,7 +552,8 @@ class Subgraph { // Returns one of the following status codes: // 1. kTfLiteOk: Delegation succeeded // 2. kTfLiteDelegateError: Delegation failed due to an error *in the - // delegate*. The Subgraph has been restored to its pre-delegation state. + // delegate*, or the delegate parameter was null. The Subgraph has been + // restored to its pre-delegation state. // NOTE: This reverts all delegates previously applied to the Subgraph. // 3. kTfLiteApplicationError : Delegation failed to be applied due to the // incompatibility with the TfLite runtime, e.g., the model graph is already diff --git a/tensorflow/lite/delegates/delegate_test.cc b/tensorflow/lite/delegates/delegate_test.cc index 9e857c550fb..7d579c579c7 100644 --- a/tensorflow/lite/delegates/delegate_test.cc +++ b/tensorflow/lite/delegates/delegate_test.cc @@ -42,6 +42,11 @@ using test_utils::TestFP16Delegation; namespace { +TEST_F(TestDelegate, NullDelegate) { + EXPECT_EQ(interpreter_->ModifyGraphWithDelegate(nullptr), + kTfLiteDelegateError); +} + TEST_F(TestDelegate, BasicDelegate) { delegate_ = std::unique_ptr(new SimpleDelegate({0, 1, 2})); interpreter_->ModifyGraphWithDelegate(delegate_->get_tf_lite_delegate()); @@ -916,6 +921,14 @@ TEST_P(TestFP16Delegation, NonDelegatedInterpreterWorks) { VerifyInvoke(); } +TEST_F(TestFP16Delegation, NullDelegate) { + EXPECT_EQ(interpreter_->ModifyGraphWithDelegate(nullptr), + kTfLiteDelegateError); + // Verify that resulting interpreter still works, despite null delegate. + ASSERT_EQ(interpreter_->AllocateTensors(), kTfLiteOk); + VerifyInvoke(); +} + TEST_P(TestFP16Delegation, DelegationWorks) { delegate_ = std::unique_ptr( new FP16Delegate(/**num_delegated_subsets**/ GetParam())); diff --git a/tensorflow/lite/interpreter.h b/tensorflow/lite/interpreter.h index 08228a9cc85..1c1a40d7be9 100644 --- a/tensorflow/lite/interpreter.h +++ b/tensorflow/lite/interpreter.h @@ -469,7 +469,8 @@ class Interpreter { /// Returns one of the following four status codes: /// 1. kTfLiteOk: Success. /// 2. kTfLiteDelegateError: Delegation failed due to an error in the - /// delegate. The Interpreter has been restored to its pre-delegation state. + /// delegate, or the delegate parameter was null. The Interpreter has been + /// restored to its pre-delegation state. /// NOTE: This undoes all delegates previously applied to the Interpreter. /// 3. kTfLiteApplicationError : Delegation failed to be applied due to the /// incompatibility with the TfLite runtime, e.g., the model graph is already