1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <gtest/gtest.h> 18 19 #include "data_type-inl.h" 20 21 #include "base/array_ref.h" 22 #include "base/macros.h" 23 #include "dex/primitive.h" 24 25 namespace art { 26 27 template <DataType::Type data_type, Primitive::Type primitive_type> 28 static void CheckConversion() { 29 static_assert(data_type == DataTypeFromPrimitive(primitive_type), "Conversion check."); 30 static_assert(DataType::Size(data_type) == Primitive::ComponentSize(primitive_type), 31 "Size check."); 32 } 33 34 TEST(DataType, SizeAgainstPrimitive) { 35 CheckConversion<DataType::Type::kVoid, Primitive::kPrimVoid>(); 36 CheckConversion<DataType::Type::kBool, Primitive::kPrimBoolean>(); 37 CheckConversion<DataType::Type::kInt8, Primitive::kPrimByte>(); 38 CheckConversion<DataType::Type::kUint16, Primitive::kPrimChar>(); 39 CheckConversion<DataType::Type::kInt16, Primitive::kPrimShort>(); 40 CheckConversion<DataType::Type::kInt32, Primitive::kPrimInt>(); 41 CheckConversion<DataType::Type::kInt64, Primitive::kPrimLong>(); 42 CheckConversion<DataType::Type::kFloat32, Primitive::kPrimFloat>(); 43 CheckConversion<DataType::Type::kFloat64, Primitive::kPrimDouble>(); 44 CheckConversion<DataType::Type::kReference, Primitive::kPrimNot>(); 45 } 46 47 TEST(DataType, Names) { 48 #define CHECK_NAME(type) EXPECT_STREQ(#type, DataType::PrettyDescriptor(DataType::Type::k##type)) 49 CHECK_NAME(Void); 50 CHECK_NAME(Bool); 51 CHECK_NAME(Int8); 52 CHECK_NAME(Uint16); 53 CHECK_NAME(Int16); 54 CHECK_NAME(Int32); 55 CHECK_NAME(Int64); 56 CHECK_NAME(Float32); 57 CHECK_NAME(Float64); 58 CHECK_NAME(Reference); 59 #undef CHECK_NAME 60 } 61 62 TEST(DataType, IsTypeConversionImplicit) { 63 static const DataType::Type kIntegralTypes[] = { 64 DataType::Type::kBool, 65 DataType::Type::kUint8, 66 DataType::Type::kInt8, 67 DataType::Type::kUint16, 68 DataType::Type::kInt16, 69 DataType::Type::kInt32, 70 DataType::Type::kInt64, 71 }; 72 const ArrayRef<const DataType::Type> kIntegralInputTypes(kIntegralTypes); 73 // Note: kBool cannot be used as a result type. 74 DCHECK_EQ(kIntegralTypes[0], DataType::Type::kBool); 75 const ArrayRef<const DataType::Type> kIntegralResultTypes = kIntegralInputTypes.SubArray(1u); 76 77 static const bool kImplicitIntegralConversions[][arraysize(kIntegralTypes)] = { 78 // Bool Uint8 Int8 Uint16 Int16 Int32 Int64 79 { /* Bool N/A */ true, true, true, true, true, false }, 80 { /* Uint8 N/A */ true, false, true, true, true, false }, 81 { /* Int8 N/A */ false, true, false, true, true, false }, 82 { /* Uint16 N/A */ false, false, true, false, true, false }, 83 { /* Int16 N/A */ false, false, false, true, true, false }, 84 { /* Int32 N/A */ false, false, false, false, true, false }, 85 { /* Int64 N/A */ false, false, false, false, false, true }, 86 }; 87 static_assert(arraysize(kIntegralTypes) == arraysize(kImplicitIntegralConversions), "size check"); 88 89 for (size_t input_index = 0; input_index != kIntegralInputTypes.size(); ++input_index) { 90 DataType::Type input_type = kIntegralInputTypes[input_index]; 91 for (size_t result_index = 1u; result_index != kIntegralResultTypes.size(); ++result_index) { 92 DataType::Type result_type = kIntegralResultTypes[result_index]; 93 EXPECT_EQ(kImplicitIntegralConversions[input_index][result_index], 94 DataType::IsTypeConversionImplicit(input_type, result_type)) 95 << input_type << " " << result_type; 96 } 97 } 98 for (DataType::Type input_type : kIntegralInputTypes) { 99 EXPECT_FALSE(DataType::IsTypeConversionImplicit(input_type, DataType::Type::kFloat32)); 100 EXPECT_FALSE(DataType::IsTypeConversionImplicit(input_type, DataType::Type::kFloat64)); 101 } 102 for (DataType::Type result_type : kIntegralResultTypes) { 103 EXPECT_FALSE(DataType::IsTypeConversionImplicit(DataType::Type::kFloat32, result_type)); 104 EXPECT_FALSE(DataType::IsTypeConversionImplicit(DataType::Type::kFloat64, result_type)); 105 } 106 EXPECT_TRUE( 107 DataType::IsTypeConversionImplicit(DataType::Type::kFloat32, DataType::Type::kFloat32)); 108 EXPECT_FALSE( 109 DataType::IsTypeConversionImplicit(DataType::Type::kFloat32, DataType::Type::kFloat64)); 110 EXPECT_FALSE( 111 DataType::IsTypeConversionImplicit(DataType::Type::kFloat64, DataType::Type::kFloat32)); 112 EXPECT_TRUE( 113 DataType::IsTypeConversionImplicit(DataType::Type::kFloat64, DataType::Type::kFloat64)); 114 } 115 116 } // namespace art 117