1 //===- llvm/unittest/AsmParser/AsmParserTest.cpp - asm parser unittests ---===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/StringRef.h" 10 #include "llvm/AsmParser/Parser.h" 11 #include "llvm/AsmParser/SlotMapping.h" 12 #include "llvm/IR/Constants.h" 13 #include "llvm/IR/DataLayout.h" 14 #include "llvm/IR/DebugInfoMetadata.h" 15 #include "llvm/IR/LLVMContext.h" 16 #include "llvm/IR/Module.h" 17 #include "llvm/Support/Error.h" 18 #include "llvm/Support/SourceMgr.h" 19 #include "gtest/gtest.h" 20 21 using namespace llvm; 22 23 namespace { 24 25 TEST(AsmParserTest, NullTerminatedInput) { 26 LLVMContext Ctx; 27 StringRef Source = "; Empty module \n"; 28 SMDiagnostic Error; 29 auto Mod = parseAssemblyString(Source, Error, Ctx); 30 31 EXPECT_TRUE(Mod != nullptr); 32 EXPECT_TRUE(Error.getMessage().empty()); 33 } 34 35 #ifdef GTEST_HAS_DEATH_TEST 36 #ifndef NDEBUG 37 38 TEST(AsmParserTest, NonNullTerminatedInput) { 39 LLVMContext Ctx; 40 StringRef Source = "; Empty module \n\1\2"; 41 SMDiagnostic Error; 42 std::unique_ptr<Module> Mod; 43 EXPECT_DEATH(Mod = parseAssemblyString(Source.substr(0, Source.size() - 2), 44 Error, Ctx), 45 "Buffer is not null terminated!"); 46 } 47 48 #endif 49 #endif 50 51 TEST(AsmParserTest, SlotMappingTest) { 52 LLVMContext Ctx; 53 StringRef Source = "@0 = global i32 0\n !0 = !{}\n !42 = !{i32 42}"; 54 SMDiagnostic Error; 55 SlotMapping Mapping; 56 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping); 57 58 EXPECT_TRUE(Mod != nullptr); 59 EXPECT_TRUE(Error.getMessage().empty()); 60 61 ASSERT_EQ(Mapping.GlobalValues.getNext(), 1u); 62 EXPECT_TRUE(isa<GlobalVariable>(Mapping.GlobalValues.get(0))); 63 64 EXPECT_EQ(Mapping.MetadataNodes.size(), 2u); 65 EXPECT_EQ(Mapping.MetadataNodes.count(0), 1u); 66 EXPECT_EQ(Mapping.MetadataNodes.count(42), 1u); 67 EXPECT_EQ(Mapping.MetadataNodes.count(1), 0u); 68 } 69 70 TEST(AsmParserTest, TypeAndConstantValueParsing) { 71 LLVMContext Ctx; 72 SMDiagnostic Error; 73 StringRef Source = "define void @test() {\n entry:\n ret void\n}"; 74 auto Mod = parseAssemblyString(Source, Error, Ctx); 75 ASSERT_TRUE(Mod != nullptr); 76 auto &M = *Mod; 77 78 const Value *V; 79 V = parseConstantValue("double 3.5", Error, M); 80 ASSERT_TRUE(V); 81 EXPECT_TRUE(V->getType()->isDoubleTy()); 82 ASSERT_TRUE(isa<ConstantFP>(V)); 83 EXPECT_TRUE(cast<ConstantFP>(V)->isExactlyValue(3.5)); 84 85 V = parseConstantValue("i32 42", Error, M); 86 ASSERT_TRUE(V); 87 EXPECT_TRUE(V->getType()->isIntegerTy()); 88 ASSERT_TRUE(isa<ConstantInt>(V)); 89 EXPECT_TRUE(cast<ConstantInt>(V)->equalsInt(42)); 90 91 V = parseConstantValue("<4 x i32> <i32 0, i32 1, i32 2, i32 3>", Error, M); 92 ASSERT_TRUE(V); 93 EXPECT_TRUE(V->getType()->isVectorTy()); 94 ASSERT_TRUE(isa<ConstantDataVector>(V)); 95 96 V = parseConstantValue("<4 x i32> splat (i32 -2)", Error, M); 97 ASSERT_TRUE(V); 98 EXPECT_TRUE(V->getType()->isVectorTy()); 99 ASSERT_TRUE(isa<ConstantDataVector>(V)); 100 101 V = parseConstantValue("<4 x i32> zeroinitializer", Error, M); 102 ASSERT_TRUE(V); 103 EXPECT_TRUE(V->getType()->isVectorTy()); 104 ASSERT_TRUE(isa<Constant>(V)); 105 EXPECT_TRUE(cast<Constant>(V)->isNullValue()); 106 107 V = parseConstantValue("<4 x i32> poison", Error, M); 108 ASSERT_TRUE(V); 109 EXPECT_TRUE(V->getType()->isVectorTy()); 110 ASSERT_TRUE(isa<PoisonValue>(V)); 111 112 V = parseConstantValue("i32 add (i32 1, i32 2)", Error, M); 113 ASSERT_TRUE(V); 114 ASSERT_TRUE(isa<ConstantInt>(V)); 115 116 V = parseConstantValue("ptr blockaddress(@test, %entry)", Error, M); 117 ASSERT_TRUE(V); 118 ASSERT_TRUE(isa<BlockAddress>(V)); 119 120 V = parseConstantValue("ptr undef", Error, M); 121 ASSERT_TRUE(V); 122 ASSERT_TRUE(isa<UndefValue>(V)); 123 124 V = parseConstantValue("ptr poison", Error, M); 125 ASSERT_TRUE(V); 126 ASSERT_TRUE(isa<PoisonValue>(V)); 127 128 EXPECT_FALSE(parseConstantValue("duble 3.25", Error, M)); 129 EXPECT_EQ(Error.getMessage(), "expected type"); 130 131 EXPECT_FALSE(parseConstantValue("i32 3.25", Error, M)); 132 EXPECT_EQ(Error.getMessage(), "floating point constant invalid for type"); 133 134 EXPECT_FALSE(parseConstantValue("ptr @foo", Error, M)); 135 EXPECT_EQ(Error.getMessage(), "expected a constant value"); 136 137 EXPECT_FALSE(parseConstantValue("i32 3, ", Error, M)); 138 EXPECT_EQ(Error.getMessage(), "expected end of string"); 139 } 140 141 TEST(AsmParserTest, TypeAndConstantValueWithSlotMappingParsing) { 142 LLVMContext Ctx; 143 SMDiagnostic Error; 144 StringRef Source = 145 "%st = type { i32, i32 }\n" 146 "@v = common global [50 x %st] zeroinitializer, align 16\n" 147 "%0 = type { i32, i32, i32, i32 }\n" 148 "@g = common global [50 x %0] zeroinitializer, align 16\n" 149 "define void @marker4(i64 %d) {\n" 150 "entry:\n" 151 " %conv = trunc i64 %d to i32\n" 152 " store i32 %conv, ptr getelementptr inbounds " 153 " ([50 x %st], ptr @v, i64 0, i64 1, i32 0), align 16\n" 154 " store i32 %conv, ptr getelementptr inbounds " 155 " ([50 x %0], ptr @g, i64 0, i64 1, i32 0), align 16\n" 156 " ret void\n" 157 "}"; 158 SlotMapping Mapping; 159 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping); 160 ASSERT_TRUE(Mod != nullptr); 161 auto &M = *Mod; 162 163 const Value *V; 164 V = parseConstantValue("ptr getelementptr inbounds ([50 x %st], ptr " 165 "@v, i64 0, i64 1, i32 0)", 166 Error, M, &Mapping); 167 ASSERT_TRUE(V); 168 ASSERT_TRUE(isa<ConstantExpr>(V)); 169 170 V = parseConstantValue("ptr getelementptr inbounds ([50 x %0], ptr " 171 "@g, i64 0, i64 1, i32 0)", 172 Error, M, &Mapping); 173 ASSERT_TRUE(V); 174 ASSERT_TRUE(isa<ConstantExpr>(V)); 175 } 176 177 TEST(AsmParserTest, TypeWithSlotMappingParsing) { 178 LLVMContext Ctx; 179 SMDiagnostic Error; 180 StringRef Source = 181 "%st = type { i32, i32 }\n" 182 "@v = common global [50 x %st] zeroinitializer, align 16\n" 183 "%0 = type { i32, i32, i32, i32 }\n" 184 "@g = common global [50 x %0] zeroinitializer, align 16\n" 185 "define void @marker4(i64 %d) {\n" 186 "entry:\n" 187 " %conv = trunc i64 %d to i32\n" 188 " store i32 %conv, ptr getelementptr inbounds " 189 " ([50 x %st], ptr @v, i64 0, i64 0, i32 0), align 16\n" 190 " store i32 %conv, ptr getelementptr inbounds " 191 " ([50 x %0], ptr @g, i64 0, i64 0, i32 0), align 16\n" 192 " ret void\n" 193 "}"; 194 SlotMapping Mapping; 195 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping); 196 ASSERT_TRUE(Mod != nullptr); 197 auto &M = *Mod; 198 199 // Check we properly parse integer types. 200 Type *Ty; 201 Ty = parseType("i32", Error, M, &Mapping); 202 ASSERT_TRUE(Ty); 203 ASSERT_TRUE(Ty->isIntegerTy()); 204 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 205 206 // Check we properly parse integer types with exotic size. 207 Ty = parseType("i13", Error, M, &Mapping); 208 ASSERT_TRUE(Ty); 209 ASSERT_TRUE(Ty->isIntegerTy()); 210 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 13); 211 212 // Check we properly parse floating point types. 213 Ty = parseType("float", Error, M, &Mapping); 214 ASSERT_TRUE(Ty); 215 ASSERT_TRUE(Ty->isFloatTy()); 216 217 Ty = parseType("double", Error, M, &Mapping); 218 ASSERT_TRUE(Ty); 219 ASSERT_TRUE(Ty->isDoubleTy()); 220 221 // Check we properly parse struct types. 222 // Named struct. 223 Ty = parseType("%st", Error, M, &Mapping); 224 ASSERT_TRUE(Ty); 225 ASSERT_TRUE(Ty->isStructTy()); 226 227 // Check the details of the struct. 228 StructType *ST = cast<StructType>(Ty); 229 ASSERT_TRUE(ST->getNumElements() == 2); 230 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { 231 Ty = ST->getElementType(i); 232 ASSERT_TRUE(Ty->isIntegerTy()); 233 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 234 } 235 236 // Anonymous struct. 237 Ty = parseType("%0", Error, M, &Mapping); 238 ASSERT_TRUE(Ty); 239 ASSERT_TRUE(Ty->isStructTy()); 240 241 // Check the details of the struct. 242 ST = cast<StructType>(Ty); 243 ASSERT_TRUE(ST->getNumElements() == 4); 244 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { 245 Ty = ST->getElementType(i); 246 ASSERT_TRUE(Ty->isIntegerTy()); 247 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 248 } 249 250 // Check we properly parse vector types. 251 Ty = parseType("<5 x i32>", Error, M, &Mapping); 252 ASSERT_TRUE(Ty); 253 ASSERT_TRUE(Ty->isVectorTy()); 254 255 // Check the details of the vector. 256 auto *VT = cast<FixedVectorType>(Ty); 257 ASSERT_TRUE(VT->getNumElements() == 5); 258 ASSERT_TRUE(VT->getPrimitiveSizeInBits().getFixedValue() == 160); 259 Ty = VT->getElementType(); 260 ASSERT_TRUE(Ty->isIntegerTy()); 261 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 262 263 // Opaque struct. 264 Ty = parseType("%opaque", Error, M, &Mapping); 265 ASSERT_TRUE(Ty); 266 ASSERT_TRUE(Ty->isStructTy()); 267 268 ST = cast<StructType>(Ty); 269 ASSERT_TRUE(ST->isOpaque()); 270 271 // Check we properly parse pointer types. 272 Ty = parseType("ptr", Error, M, &Mapping); 273 ASSERT_TRUE(Ty); 274 ASSERT_TRUE(Ty->isPointerTy()); 275 276 // Check that we reject types with garbage. 277 Ty = parseType("i32 garbage", Error, M, &Mapping); 278 ASSERT_TRUE(!Ty); 279 } 280 281 TEST(AsmParserTest, TypeAtBeginningWithSlotMappingParsing) { 282 LLVMContext Ctx; 283 SMDiagnostic Error; 284 StringRef Source = 285 "%st = type { i32, i32 }\n" 286 "@v = common global [50 x %st] zeroinitializer, align 16\n" 287 "%0 = type { i32, i32, i32, i32 }\n" 288 "@g = common global [50 x %0] zeroinitializer, align 16\n" 289 "define void @marker4(i64 %d) {\n" 290 "entry:\n" 291 " %conv = trunc i64 %d to i32\n" 292 " store i32 %conv, ptr getelementptr inbounds " 293 " ([50 x %st], ptr @v, i64 0, i64 0, i32 0), align 16\n" 294 " store i32 %conv, ptr getelementptr inbounds " 295 " ([50 x %0], ptr @g, i64 0, i64 0, i32 0), align 16\n" 296 " ret void\n" 297 "}"; 298 SlotMapping Mapping; 299 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping); 300 ASSERT_TRUE(Mod != nullptr); 301 auto &M = *Mod; 302 unsigned Read; 303 304 // Check we properly parse integer types. 305 Type *Ty; 306 Ty = parseTypeAtBeginning("i32", Read, Error, M, &Mapping); 307 ASSERT_TRUE(Ty); 308 ASSERT_TRUE(Ty->isIntegerTy()); 309 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 310 ASSERT_TRUE(Read == 3); 311 312 // Check we properly parse integer types with exotic size. 313 Ty = parseTypeAtBeginning("i13", Read, Error, M, &Mapping); 314 ASSERT_TRUE(Ty); 315 ASSERT_TRUE(Ty->isIntegerTy()); 316 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 13); 317 ASSERT_TRUE(Read == 3); 318 319 // Check we properly parse floating point types. 320 Ty = parseTypeAtBeginning("float", Read, Error, M, &Mapping); 321 ASSERT_TRUE(Ty); 322 ASSERT_TRUE(Ty->isFloatTy()); 323 ASSERT_TRUE(Read == 5); 324 325 Ty = parseTypeAtBeginning("double", Read, Error, M, &Mapping); 326 ASSERT_TRUE(Ty); 327 ASSERT_TRUE(Ty->isDoubleTy()); 328 ASSERT_TRUE(Read == 6); 329 330 // Check we properly parse struct types. 331 // Named struct. 332 Ty = parseTypeAtBeginning("%st", Read, Error, M, &Mapping); 333 ASSERT_TRUE(Ty); 334 ASSERT_TRUE(Ty->isStructTy()); 335 ASSERT_TRUE(Read == 3); 336 337 // Check the details of the struct. 338 StructType *ST = cast<StructType>(Ty); 339 ASSERT_TRUE(ST->getNumElements() == 2); 340 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { 341 Ty = ST->getElementType(i); 342 ASSERT_TRUE(Ty->isIntegerTy()); 343 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 344 } 345 346 // Anonymous struct. 347 Ty = parseTypeAtBeginning("%0", Read, Error, M, &Mapping); 348 ASSERT_TRUE(Ty); 349 ASSERT_TRUE(Ty->isStructTy()); 350 ASSERT_TRUE(Read == 2); 351 352 // Check the details of the struct. 353 ST = cast<StructType>(Ty); 354 ASSERT_TRUE(ST->getNumElements() == 4); 355 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { 356 Ty = ST->getElementType(i); 357 ASSERT_TRUE(Ty->isIntegerTy()); 358 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 359 } 360 361 // Check we properly parse vector types. 362 Ty = parseTypeAtBeginning("<5 x i32>", Read, Error, M, &Mapping); 363 ASSERT_TRUE(Ty); 364 ASSERT_TRUE(Ty->isVectorTy()); 365 ASSERT_TRUE(Read == 9); 366 367 // Check the details of the vector. 368 auto *VT = cast<FixedVectorType>(Ty); 369 ASSERT_TRUE(VT->getNumElements() == 5); 370 ASSERT_TRUE(VT->getPrimitiveSizeInBits().getFixedValue() == 160); 371 Ty = VT->getElementType(); 372 ASSERT_TRUE(Ty->isIntegerTy()); 373 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 374 375 // Opaque struct. 376 Ty = parseTypeAtBeginning("%opaque", Read, Error, M, &Mapping); 377 ASSERT_TRUE(Ty); 378 ASSERT_TRUE(Ty->isStructTy()); 379 ASSERT_TRUE(Read == 7); 380 381 ST = cast<StructType>(Ty); 382 ASSERT_TRUE(ST->isOpaque()); 383 384 // Check we properly parse pointer types. 385 // One indirection. 386 Ty = parseTypeAtBeginning("ptr", Read, Error, M, &Mapping); 387 ASSERT_TRUE(Ty); 388 ASSERT_TRUE(Ty->isPointerTy()); 389 ASSERT_TRUE(Read == 3); 390 391 // Check that we reject types with garbage. 392 Ty = parseTypeAtBeginning("i32 garbage", Read, Error, M, &Mapping); 393 ASSERT_TRUE(Ty); 394 ASSERT_TRUE(Ty->isIntegerTy()); 395 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 396 // We go to the next token, i.e., we read "i32" + ' '. 397 ASSERT_TRUE(Read == 4); 398 } 399 400 TEST(AsmParserTest, InvalidDataLayoutStringCallback) { 401 LLVMContext Ctx; 402 SMDiagnostic Error; 403 // Note the invalid i8:7 part 404 // Overalign i32 as marker so we can check that indeed this DL was used, 405 // and not some default. 406 StringRef InvalidDLStr = 407 "e-m:e-p:64:64-i8:7-i16:16-i32:64-i64:64-f80:128-n8:16:32:64"; 408 StringRef FixedDLStr = 409 "e-m:e-p:64:64-i8:8-i16:16-i32:64-i64:64-f80:128-n8:16:32:64"; 410 Expected<DataLayout> ExpectedFixedDL = DataLayout::parse(FixedDLStr); 411 ASSERT_TRUE(!ExpectedFixedDL.takeError()); 412 DataLayout FixedDL = ExpectedFixedDL.get(); 413 std::string Source = ("target datalayout = \"" + InvalidDLStr + "\"\n").str(); 414 MemoryBufferRef SourceBuffer(Source, "<string>"); 415 416 // Check that we reject the source without a DL override. 417 SlotMapping Mapping1; 418 auto Mod1 = parseAssembly(SourceBuffer, Error, Ctx, &Mapping1); 419 EXPECT_TRUE(Mod1 == nullptr); 420 421 // Check that we pass the correct DL str to the callback, 422 // that fixing the DL str from the callback works, 423 // and that the resulting module has the correct DL. 424 SlotMapping Mapping2; 425 auto Mod2 = parseAssembly( 426 SourceBuffer, Error, Ctx, &Mapping2, 427 [&](StringRef Triple, StringRef DLStr) -> std::optional<std::string> { 428 EXPECT_EQ(DLStr, InvalidDLStr); 429 return std::string{FixedDLStr}; 430 }); 431 ASSERT_TRUE(Mod2 != nullptr); 432 EXPECT_EQ(Mod2->getDataLayout(), FixedDL); 433 } 434 435 TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) { 436 LLVMContext Ctx; 437 SMDiagnostic Error; 438 StringRef Source = ""; 439 SlotMapping Mapping; 440 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping); 441 ASSERT_TRUE(Mod != nullptr); 442 auto &M = *Mod; 443 unsigned Read; 444 445 ASSERT_EQ(Mapping.MetadataNodes.size(), 0u); 446 447 DIExpression *Expr; 448 449 Expr = parseDIExpressionBodyAtBeginning("()", Read, Error, M, &Mapping); 450 ASSERT_TRUE(Expr); 451 ASSERT_EQ(Expr->getNumElements(), 0u); 452 453 Expr = parseDIExpressionBodyAtBeginning("(0)", Read, Error, M, &Mapping); 454 ASSERT_TRUE(Expr); 455 ASSERT_EQ(Expr->getNumElements(), 1u); 456 457 Expr = parseDIExpressionBodyAtBeginning("(DW_OP_LLVM_fragment, 0, 1)", Read, 458 Error, M, &Mapping); 459 ASSERT_TRUE(Expr); 460 ASSERT_EQ(Expr->getNumElements(), 3u); 461 462 Expr = parseDIExpressionBodyAtBeginning( 463 "(DW_OP_LLVM_fragment, 0, 1) trailing source", Read, Error, M, &Mapping); 464 ASSERT_TRUE(Expr); 465 ASSERT_EQ(Expr->getNumElements(), 3u); 466 ASSERT_EQ(Read, StringRef("(DW_OP_LLVM_fragment, 0, 1) ").size()); 467 468 Error = {}; 469 Expr = parseDIExpressionBodyAtBeginning("i32", Read, Error, M, &Mapping); 470 ASSERT_FALSE(Expr); 471 ASSERT_EQ(Error.getMessage(), "expected '(' here"); 472 473 Error = {}; 474 Expr = parseDIExpressionBodyAtBeginning( 475 "!DIExpression(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping); 476 ASSERT_FALSE(Expr); 477 ASSERT_EQ(Error.getMessage(), "expected '(' here"); 478 479 ASSERT_EQ(Mapping.MetadataNodes.size(), 0u); 480 } 481 482 } // end anonymous namespace 483