1 //===- unittest/IceParseInstsTest.cpp - test instruction errors -----------===// 2 // 3 // The Subzero Code Generator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <string> 11 12 #pragma clang diagnostic push 13 #pragma clang diagnostic ignored "-Wunused-parameter" 14 #include "llvm/ADT/STLExtras.h" 15 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" 16 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" 17 #pragma clang diagnostic pop 18 19 #include "BitcodeMunge.h" 20 #include "unittests/Bitcode/NaClMungeTest.h" 21 22 using namespace llvm; 23 using namespace naclmungetest; 24 25 namespace { 26 27 // The ParseError constant is passed to the BitcodeMunger to prevent translation 28 // when we expect a Parse error. 29 constexpr bool ParseError = true; 30 31 // Note: alignment stored as 0 or log2(Alignment)+1. 32 uint64_t getEncAlignPower(unsigned Power) { 33 return Power + 1; 34 } 35 uint64_t getEncAlignZero() { return 0; } 36 37 /// Test how we report a call arg that refers to nonexistent call argument 38 TEST(IceParseInstsTest, NonexistentCallArg) { 39 const uint64_t BitcodeRecords[] = { 40 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, 41 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, 42 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, 43 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, 44 3, naclbitc::TYPE_CODE_VOID, Terminator, 45 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, 0, Terminator, 46 0, naclbitc::BLK_CODE_EXIT, Terminator, 47 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 1, 3, Terminator, 48 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 3, Terminator, 49 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, 50 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, 51 // Note: 100 is a bad value index in next line. 52 3, naclbitc::FUNC_CODE_INST_CALL, 0, 4, 2, 100, Terminator, 53 3, naclbitc::FUNC_CODE_INST_RET, Terminator, 54 0, naclbitc::BLK_CODE_EXIT, Terminator, 55 0, naclbitc::BLK_CODE_EXIT, Terminator 56 }; 57 58 // Show bitcode objdump for BitcodeRecords. 59 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords)); 60 EXPECT_FALSE(DumpMunger.runTest()); 61 EXPECT_EQ(" 66:4| 3: <34, 0, 4, 2, 100> | call void @f0(i32 " 62 "%p0, i32 @f0);\n" 63 "Error(66:4): Invalid relative value id: 100 (Must be <= 4)\n", 64 DumpMunger.getLinesWithSubstring("66:4")); 65 66 // Show that we get appropriate error when parsing in Subzero. 67 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords)); 68 EXPECT_FALSE(Munger.runTest(ParseError)); 69 EXPECT_EQ("Error(66:4): Invalid function record: <34 0 4 2 100>\n", 70 Munger.getTestResults()); 71 72 // Show that we generate a fatal error when not allowing error recovery. 73 Ice::ClFlags::Flags.setAllowErrorRecovery(false); 74 EXPECT_DEATH(Munger.runTest(ParseError), ".*ERROR: Unable to continue.*"); 75 } 76 77 /// Test how we recognize alignments in alloca instructions. 78 TEST(IceParseInstsTests, AllocaAlignment) { 79 const uint64_t BitcodeRecords[] = { 80 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, 81 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, 82 3, naclbitc::TYPE_CODE_NUMENTRY, 4, Terminator, 83 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, 84 3, naclbitc::TYPE_CODE_VOID, Terminator, 85 3, naclbitc::TYPE_CODE_FUNCTION, 0, 1, 0, Terminator, 86 3, naclbitc::TYPE_CODE_INTEGER, 8, Terminator, 87 0, naclbitc::BLK_CODE_EXIT, Terminator, 88 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 3, Terminator, 89 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, 90 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, 91 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(0), Terminator, 92 3, naclbitc::FUNC_CODE_INST_RET, Terminator, 93 0, naclbitc::BLK_CODE_EXIT, Terminator, 94 0, naclbitc::BLK_CODE_EXIT, Terminator}; 95 96 const uint64_t ReplaceIndex = 11; // index for FUNC_CODE_INST_ALLOCA 97 98 // Show text when alignment is 1. 99 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords)); 100 EXPECT_TRUE(DumpMunger.runTest()); 101 EXPECT_EQ(" 62:4| 3: <19, 1, 1> | %v0 = alloca i8, i32 " 102 "%p0, align 1;\n", 103 DumpMunger.getLinesWithSubstring("62:4")); 104 105 // Show that we can handle alignment of 1. 106 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords)); 107 EXPECT_TRUE(Munger.runTest()); 108 109 // Show what happens when changing alignment to 0. 110 const uint64_t Align0[] = { 111 ReplaceIndex, NaClMungedBitcode::Replace, 112 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignZero(), Terminator, 113 }; 114 EXPECT_TRUE(Munger.runTest(ARRAY(Align0))); 115 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align0))); 116 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n", 117 DumpMunger.getLinesWithSubstring("alloca")); 118 119 // Show what happens when changing alignment to 2**30. 120 const uint64_t Align30[] = { 121 ReplaceIndex, NaClMungedBitcode::Replace, 122 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(30), Terminator, 123 }; 124 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError)); 125 EXPECT_EQ("Error(62:4): Invalid function record: <19 1 31>\n", 126 Munger.getTestResults()); 127 128 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30))); 129 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 0;\n", 130 DumpMunger.getLinesWithSubstring("alloca")); 131 EXPECT_EQ( 132 "Error(62:4): Alignment can't be greater than 2**29. Found: 2**30\n", 133 DumpMunger.getLinesWithSubstring("Error")); 134 135 // Show what happens when changing alignment to 2**29. 136 const uint64_t Align29[] = { 137 ReplaceIndex, NaClMungedBitcode::Replace, 138 3, naclbitc::FUNC_CODE_INST_ALLOCA, 1, getEncAlignPower(29), Terminator, 139 }; 140 EXPECT_TRUE(Munger.runTest(ARRAY(Align29))); 141 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align29))); 142 EXPECT_EQ(" %v0 = alloca i8, i32 %p0, align 536870912;\n", 143 DumpMunger.getLinesWithSubstring("alloca")); 144 } 145 146 // Test how we recognize alignments in load i32 instructions. 147 TEST(IceParseInstsTests, LoadI32Alignment) { 148 const uint64_t BitcodeRecords[] = { 149 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, 150 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, 151 3, naclbitc::TYPE_CODE_NUMENTRY, 2, Terminator, 152 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, 153 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 0, Terminator, 154 0, naclbitc::BLK_CODE_EXIT, Terminator, 155 3, naclbitc::MODULE_CODE_FUNCTION, 1, 0, 0, 3, Terminator, 156 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, 157 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, 158 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(0), 0, Terminator, 159 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator, 160 0, naclbitc::BLK_CODE_EXIT, Terminator, 161 0, naclbitc::BLK_CODE_EXIT, Terminator}; 162 163 const uint64_t ReplaceIndex = 9; // index for FUNC_CODE_INST_LOAD 164 165 // Show text when alignment is 1. 166 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords)); 167 EXPECT_TRUE(DumpMunger.runTest()); 168 EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load i32* %p0, " 169 "align 1;\n", 170 DumpMunger.getLinesWithSubstring("58:4")); 171 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords)); 172 EXPECT_TRUE(Munger.runTest()); 173 174 // Show what happens when changing alignment to 0. 175 const uint64_t Align0[] = { 176 ReplaceIndex, NaClMungedBitcode::Replace, 177 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator, 178 }; 179 EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError)); 180 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n", 181 Munger.getTestResults()); 182 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0))); 183 EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n" 184 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", 185 DumpMunger.getLinesWithSubstring("load")); 186 187 // Show what happens when changing alignment to 4. 188 const uint64_t Align4[] = { 189 ReplaceIndex, NaClMungedBitcode::Replace, 190 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator, 191 }; 192 EXPECT_FALSE(Munger.runTest(ARRAY(Align4), ParseError)); 193 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 3 0>\n", 194 Munger.getTestResults()); 195 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align4))); 196 EXPECT_EQ(" %v0 = load i32* %p0, align 4;\n" 197 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", 198 DumpMunger.getLinesWithSubstring("load")); 199 200 // Show what happens when changing alignment to 2**29. 201 const uint64_t Align29[] = { 202 ReplaceIndex, NaClMungedBitcode::Replace, 203 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator, 204 }; 205 EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError)); 206 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n", 207 Munger.getTestResults()); 208 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29))); 209 EXPECT_EQ(" %v0 = load i32* %p0, align 536870912;\n" 210 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", 211 DumpMunger.getLinesWithSubstring("load")); 212 213 // Show what happens when changing alignment to 2**30. 214 const uint64_t Align30[] = { 215 ReplaceIndex, NaClMungedBitcode::Replace, 216 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator, 217 }; 218 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError)); 219 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n", 220 Munger.getTestResults()); 221 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30))); 222 EXPECT_EQ(" %v0 = load i32* %p0, align 0;\n" 223 "Error(58:4): load: Illegal alignment for i32. Expects: 1\n", 224 DumpMunger.getLinesWithSubstring("load")); 225 } 226 227 // Test how we recognize alignments in load float instructions. 228 TEST(IceParseInstsTests, LoadFloatAlignment) { 229 const uint64_t BitcodeRecords[] = { 230 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, 231 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, 232 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, 233 3, naclbitc::TYPE_CODE_FLOAT, Terminator, 234 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, 235 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 1, Terminator, 236 0, naclbitc::BLK_CODE_EXIT, Terminator, 237 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 3, Terminator, 238 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, 239 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, 240 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(0), 0, Terminator, 241 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator, 242 0, naclbitc::BLK_CODE_EXIT, Terminator, 243 0, naclbitc::BLK_CODE_EXIT, Terminator}; 244 245 const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_LOAD 246 247 // Show text when alignment is 1. 248 NaClObjDumpMunger DumpMunger(ARRAY_TERM(BitcodeRecords)); 249 EXPECT_TRUE(DumpMunger.runTest()); 250 EXPECT_EQ(" 58:4| 3: <20, 1, 1, 0> | %v0 = load float* " 251 "%p0, align 1;\n", 252 DumpMunger.getLinesWithSubstring("58:4")); 253 IceTest::SubzeroBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords)); 254 EXPECT_TRUE(Munger.runTest()); 255 256 // Show what happens when changing alignment to 0. 257 const uint64_t Align0[] = { 258 ReplaceIndex, NaClMungedBitcode::Replace, 259 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignZero(), 0, Terminator, 260 }; 261 EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError)); 262 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 0 0>\n", 263 Munger.getTestResults()); 264 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0))); 265 EXPECT_EQ( 266 " %v0 = load float* %p0, align 0;\n" 267 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n", 268 DumpMunger.getLinesWithSubstring("load")); 269 270 // Show what happens when changing alignment to 4. 271 const uint64_t Align4[] = { 272 ReplaceIndex, NaClMungedBitcode::Replace, 273 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(2), 0, Terminator, 274 }; 275 EXPECT_TRUE(Munger.runTest(ARRAY(Align4))); 276 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align4))); 277 EXPECT_EQ(" %v0 = load float* %p0, align 4;\n", 278 DumpMunger.getLinesWithSubstring("load")); 279 280 const uint64_t Align29[] = { 281 ReplaceIndex, NaClMungedBitcode::Replace, 282 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(29), 0, Terminator, 283 }; 284 EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError)); 285 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 30 0>\n", 286 Munger.getTestResults()); 287 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29))); 288 EXPECT_EQ( 289 " %v0 = load float* %p0, align 536870912;\n" 290 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n", 291 DumpMunger.getLinesWithSubstring("load")); 292 293 // Show what happens when changing alignment to 2**30. 294 const uint64_t Align30[] = { 295 ReplaceIndex, NaClMungedBitcode::Replace, 296 3, naclbitc::FUNC_CODE_INST_LOAD, 1, getEncAlignPower(30), 0, Terminator, 297 }; 298 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError)); 299 EXPECT_EQ("Error(58:4): Invalid function record: <20 1 31 0>\n", 300 Munger.getTestResults()); 301 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30))); 302 EXPECT_EQ( 303 " %v0 = load float* %p0, align 0;\n" 304 "Error(58:4): load: Illegal alignment for float. Expects: 1 or 4\n", 305 DumpMunger.getLinesWithSubstring("load")); 306 } 307 308 // Test how we recognize alignments in store instructions. 309 TEST(NaClParseInstsTests, StoreAlignment) { 310 const uint64_t BitcodeRecords[] = { 311 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator, 312 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 2, Terminator, 313 3, naclbitc::TYPE_CODE_NUMENTRY, 3, Terminator, 314 3, naclbitc::TYPE_CODE_FLOAT, Terminator, 315 3, naclbitc::TYPE_CODE_INTEGER, 32, Terminator, 316 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, 1, 0, Terminator, 317 0, naclbitc::BLK_CODE_EXIT, Terminator, 318 3, naclbitc::MODULE_CODE_FUNCTION, 2, 0, 0, 3, Terminator, 319 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, 320 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, 321 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(0), Terminator, 322 3, naclbitc::FUNC_CODE_INST_RET, 1, Terminator, 323 0, naclbitc::BLK_CODE_EXIT, Terminator, 324 0, naclbitc::BLK_CODE_EXIT, Terminator}; 325 326 const uint64_t ReplaceIndex = 10; // index for FUNC_CODE_INST_STORE 327 328 // Show text when alignment is 1. 329 NaClObjDumpMunger DumpMunger(BitcodeRecords, array_lengthof(BitcodeRecords), 330 Terminator); 331 EXPECT_TRUE(DumpMunger.runTest("Good Store Alignment 1")); 332 EXPECT_EQ(" 62:4| 3: <24, 2, 1, 1> | store float %p1, " 333 "float* %p0, \n", 334 DumpMunger.getLinesWithSubstring("62:4")); 335 IceTest::SubzeroBitcodeMunger Munger( 336 BitcodeRecords, array_lengthof(BitcodeRecords), Terminator); 337 EXPECT_TRUE(Munger.runTest()); 338 339 // Show what happens when changing alignment to 0. 340 const uint64_t Align0[] = { 341 ReplaceIndex, NaClMungedBitcode::Replace, 342 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignZero(), Terminator, 343 }; 344 EXPECT_FALSE(Munger.runTest(ARRAY(Align0), ParseError)); 345 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 0>\n", 346 Munger.getTestResults()); 347 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align0))); 348 EXPECT_EQ( 349 " store float %p1, float* %p0, align 0;\n" 350 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", 351 DumpMunger.getLinesWithSubstring("store")); 352 353 // Show what happens when changing alignment to 4. 354 const uint64_t Align4[] = { 355 ReplaceIndex, NaClMungedBitcode::Replace, 356 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(2), Terminator, 357 }; 358 EXPECT_TRUE(Munger.runTest(ARRAY(Align4))); 359 EXPECT_TRUE(DumpMunger.runTestForAssembly(ARRAY(Align4))); 360 361 // Show what happens when changing alignment to 8. 362 const uint64_t Align8[] = { 363 ReplaceIndex, NaClMungedBitcode::Replace, 364 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(3), Terminator, 365 }; 366 EXPECT_FALSE(Munger.runTest(ARRAY(Align8), ParseError)); 367 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 4>\n", 368 Munger.getTestResults()); 369 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align8))); 370 EXPECT_EQ( 371 " store float %p1, float* %p0, align 8;\n" 372 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", 373 DumpMunger.getLinesWithSubstring("store")); 374 375 // Show what happens when changing alignment to 2**29. 376 const uint64_t Align29[] = { 377 ReplaceIndex, NaClMungedBitcode::Replace, 378 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(29), Terminator, 379 }; 380 EXPECT_FALSE(Munger.runTest(ARRAY(Align29), ParseError)); 381 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 30>\n", 382 Munger.getTestResults()); 383 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align29))); 384 EXPECT_EQ( 385 " store float %p1, float* %p0, align 536870912;\n" 386 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", 387 DumpMunger.getLinesWithSubstring("store")); 388 389 const uint64_t Align30[] = { 390 ReplaceIndex, NaClMungedBitcode::Replace, 391 // Note: alignment stored as 0 or log2(Alignment)+1. 392 3, naclbitc::FUNC_CODE_INST_STORE, 2, 1, getEncAlignPower(30), Terminator, 393 }; 394 EXPECT_FALSE(Munger.runTest(ARRAY(Align30), ParseError)); 395 EXPECT_EQ("Error(62:4): Invalid function record: <24 2 1 31>\n", 396 Munger.getTestResults()); 397 EXPECT_FALSE(DumpMunger.runTestForAssembly(ARRAY(Align30))); 398 EXPECT_EQ( 399 " store float %p1, float* %p0, align 0;\n" 400 "Error(62:4): store: Illegal alignment for float. Expects: 1 or 4\n", 401 DumpMunger.getLinesWithSubstring("store")); 402 } 403 404 } // end of anonymous namespace 405