From 86139dab4594f369e0a2c63b3d83ad31e8e92962 Mon Sep 17 00:00:00 2001
From: Pavel Samolysov <samolisov@gmail.com>
Date: Mon, 4 Mar 2019 12:46:44 +0300
Subject: [PATCH] Fix the implicitly constructions of ArraySlice from
 initializer lists

In 'ngraph_utils.cc', methods like 'const gtl::ArraySlice<DataType>&
NGraphNumericDTypes()' directly construct an instance of 'gtl::ArraySlice'
from an intializer list. This leads to the corruption of 'DataType'
instances held inside the array slice, and therefore no 'DataType' can
pass the following check within the 'TypeConstraintOk' method:

    DataType dt;

    if (GetNodeAttr(node->attrs(), type_attr_name, &dt) != Status::OK() ||
	      std::find(allowed_types.begin(), allowed_types.end(), dt) ==
		  allowed_types.end()) {

Since the 'allowed_types' array contains already destructed instances of 'DataType's.

The constructor of 'gtl::ArraySlice' that takes an initializer list has
the following comment (see
https://github.com/petewarden/tensorflow_makefile/blob/master/tensorflow/core/lib/gtl/array_slice.h):

// Implicitly constructs an ArraySlice from an initializer list. This makes it
// possible to pass a brace-enclosed initializer list to a function expecting
// an ArraySlice:
//   void Process(ArraySlice<int> x);
//   Process({1, 2, 3});
// The data referenced by the initializer_list must outlive this
// ArraySlice. For example, "ArraySlice<int> s={1,2};" and "return
// ArraySlice<int>({3,4});" are errors, as the resulting ArraySlice may
// reference data that is no longer valid.

So, an additional memory is required to store the held instances of
the 'DataType' class. This commit introduces 'std::vector' as the store
for 'DataType's. For backward compatibility, a static variable of
'ArraySlice<DataType>' is introduced in each method and the methods
return references to those variables.

Signed-off-by: Pavel Samolysov <samolisov@gmail.com>
---
 src/ngraph_utils.cc | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/ngraph_utils.cc b/src/ngraph_utils.cc
index 48838e30..3f8e131c 100644
--- a/src/ngraph_utils.cc
+++ b/src/ngraph_utils.cc
@@ -176,43 +176,49 @@ void print_node_histogram(const std::unordered_map<string, int>& histogram,
 }
 
 const gtl::ArraySlice<DataType>& NGraphDTypes() {
-  static gtl::ArraySlice<DataType> result{
+  static std::vector<DataType> vector{
       DT_FLOAT,  DT_DOUBLE, DT_INT8,   DT_INT16, DT_INT32, DT_INT64, DT_UINT8,
       DT_UINT16, DT_UINT32, DT_UINT64, DT_BOOL,  DT_QINT8, DT_QUINT8};
+  static gtl::ArraySlice<DataType> result{vector};
   return result;
 }
 
 const gtl::ArraySlice<DataType>& NGraphNumericDTypes() {
-  static gtl::ArraySlice<DataType> result{
-      DT_FLOAT, DT_DOUBLE, DT_INT8,   DT_INT16,  DT_INT32,
-      DT_INT64, DT_UINT8,  DT_UINT16, DT_UINT32, DT_UINT64};
+  static std::vector<DataType> vector{DT_FLOAT, DT_DOUBLE, DT_INT8,   DT_INT16,
+      DT_INT32, DT_INT64, DT_UINT8,  DT_UINT16, DT_UINT32, DT_UINT64};
+  static gtl::ArraySlice<DataType> result{vector};
   return result;
 }
 
 const gtl::ArraySlice<DataType>& NGraphNumericAndQuantizedDTypes() {
-  static gtl::ArraySlice<DataType> result{
+  static std::vector<DataType> vector{
       DT_FLOAT, DT_DOUBLE, DT_INT8,   DT_INT16,  DT_INT32, DT_INT64,
       DT_UINT8, DT_UINT16, DT_UINT32, DT_UINT64, DT_QINT8, DT_QUINT8};
+  static gtl::ArraySlice<DataType> result{vector};
   return result;
 }
 
 const gtl::ArraySlice<DataType>& NGraphIndexDTypes() {
-  static gtl::ArraySlice<DataType> result{DT_INT32, DT_INT64};
+  static std::vector<DataType> vector{DT_INT32, DT_INT64};
+  static gtl::ArraySlice<DataType> result{vector};
   return result;
 }
 
 const gtl::ArraySlice<DataType>& NGraphSupportedQuantizedDTypes() {
-  static gtl::ArraySlice<DataType> result{DT_QINT8, DT_QUINT8};
+  static std::vector<DataType> vector{DT_QINT8, DT_QUINT8};
+  static gtl::ArraySlice<DataType> result{vector};
   return result;
 }
 
 const gtl::ArraySlice<DataType>& NGraphRealDTypes() {
-  static gtl::ArraySlice<DataType> result{DT_FLOAT, DT_DOUBLE};
+  static std::vector<DataType> vector{DT_FLOAT, DT_DOUBLE};
+  static gtl::ArraySlice<DataType> result{vector};
   return result;
 }
 
 const gtl::ArraySlice<DataType>& NGraphBiasDTypes() {
-  static gtl::ArraySlice<DataType> result{DT_FLOAT, DT_QINT32};
+  static std::vector<DataType> vector{DT_FLOAT, DT_QINT32};
+  static gtl::ArraySlice<DataType> result{vector};
   return result;
 }