THRIFT-4137 Fix remaining undefined behavior invalid vptr casts in Thrift Compiler
diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
index f5d292f..4de4307 100644
--- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
@@ -2573,7 +2573,7 @@
   }
 
   if (ttype->is_set()) {
-    t_type* tkey = get_true_type(((t_list*)ttype)->get_elem_type());
+    t_type* tkey = get_true_type(((t_set*)ttype)->get_elem_type());
     if (tkey->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)tkey)->get_base();
       switch (tbase) {
diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc
index db70dc5..80b8eef 100644
--- a/compiler/cpp/src/thrift/generate/t_java_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc
@@ -2685,7 +2685,7 @@
     } else if (type->is_set()) {
       indent(out)
           << "new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, ";
-      t_type* elem_type = ((t_list*)type)->get_elem_type();
+      t_type* elem_type = ((t_set*)type)->get_elem_type();
       generate_field_value_meta_data(out, elem_type);
     } else { // map
       indent(out)
@@ -3748,7 +3748,7 @@
     } else if (ttype->is_list()) {
       indent(out) << "org.apache.thrift.protocol.TList " << obj
                   << " = new org.apache.thrift.protocol.TList("
-                  << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", iprot.readI32());"
+                  << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", iprot.readI32());"
                   << endl;
     }
   }
diff --git a/compiler/cpp/src/thrift/generate/t_json_generator.cc b/compiler/cpp/src/thrift/generate/t_json_generator.cc
index 36e9216..f3d67e0 100644
--- a/compiler/cpp/src/thrift/generate/t_json_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_json_generator.cc
@@ -273,10 +273,14 @@
     write_key_and_string("valueTypeId", get_type_name(vtype));
     write_type_spec_object("keyType", ktype);
     write_type_spec_object("valueType", vtype);
-  } else if (ttype->is_list() || ttype->is_set()) {
+  } else if (ttype->is_list()) {
     t_type* etype = ((t_list*)ttype)->get_elem_type();
     write_key_and_string("elemTypeId", get_type_name(etype));
     write_type_spec_object("elemType", etype);
+  } else if (ttype->is_set()) {
+    t_type* etype = ((t_set*)ttype)->get_elem_type();
+    write_key_and_string("elemTypeId", get_type_name(etype));
+    write_type_spec_object("elemType", etype);
   }
 }
 
diff --git a/compiler/cpp/src/thrift/generate/t_xml_generator.cc b/compiler/cpp/src/thrift/generate/t_xml_generator.cc
index b35f351..e7e01fd 100644
--- a/compiler/cpp/src/thrift/generate/t_xml_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_xml_generator.cc
@@ -391,11 +391,16 @@
   if (type == "id") {
     write_attribute("type-module", ttype->get_program()->get_name());
     write_attribute("type-id", ttype->get_name());
-  } else if (type == "list" || type == "set") {
+  } else if (type == "list") {
     t_type* etype = ((t_list*)ttype)->get_elem_type();
     write_element_start("elemType");
     write_type(etype);
     write_element_end();
+  } else if (type == "set") {
+    t_type* etype = ((t_set*)ttype)->get_elem_type();
+    write_element_start("elemType");
+    write_type(etype);
+    write_element_end();
   } else if (type == "map") {
     t_type* ktype = ((t_map*)ttype)->get_key_type();
     write_element_start("keyType");
diff --git a/compiler/cpp/src/thrift/parse/t_scope.h b/compiler/cpp/src/thrift/parse/t_scope.h
index e196200..02aa550 100644
--- a/compiler/cpp/src/thrift/parse/t_scope.h
+++ b/compiler/cpp/src/thrift/parse/t_scope.h
@@ -31,6 +31,7 @@
 #include "thrift/parse/t_base_type.h"
 #include "thrift/parse/t_map.h"
 #include "thrift/parse/t_list.h"
+#include "thrift/parse/t_set.h"
 
 namespace plugin_output {
 template <typename From, typename To>
@@ -81,12 +82,18 @@
         resolve_const_value(v_iter->first, ((t_map*)ttype)->get_key_type());
         resolve_const_value(v_iter->second, ((t_map*)ttype)->get_val_type());
       }
-    } else if (ttype->is_list() || ttype->is_set()) {
+    } else if (ttype->is_list()) {
       const std::vector<t_const_value*>& val = const_val->get_list();
       std::vector<t_const_value*>::const_iterator v_iter;
       for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
         resolve_const_value((*v_iter), ((t_list*)ttype)->get_elem_type());
       }
+    } else if (ttype->is_set()) {
+      const std::vector<t_const_value*>& val = const_val->get_list();
+      std::vector<t_const_value*>::const_iterator v_iter;
+      for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
+        resolve_const_value((*v_iter), ((t_set*)ttype)->get_elem_type());
+      }
     } else if (ttype->is_struct()) {
       t_struct* tstruct = (t_struct*)ttype;
       const std::map<t_const_value*, t_const_value*>& map = const_val->get_map();