|
14 | 14 | #include "llvm/Pass.h"
|
15 | 15 | #include "llvm/Support/RandomNumberGenerator.h"
|
16 | 16 | #include "llvm/Support/SourceMgr.h"
|
| 17 | +#include "llvm/Support/raw_ostream.h" |
17 | 18 | #include "gtest/gtest.h"
|
18 | 19 |
|
19 | 20 | #include <random>
|
@@ -326,4 +327,80 @@ TEST(ModuleTest, GlobalList) {
|
326 | 327 | EXPECT_EQ(M->global_size(), 1u);
|
327 | 328 | }
|
328 | 329 |
|
| 330 | +TEST(ModuleTest, MoveAssign) { |
| 331 | + // This tests that we can move-assign modules, we parse two modules and |
| 332 | + // move assign the second one to the first one, and check that the print |
| 333 | + // is equal to what we loaded. |
| 334 | + LLVMContext C; |
| 335 | + SMDiagnostic Err; |
| 336 | + LLVMContext Context; |
| 337 | + std::unique_ptr<Module> M1 = parseAssemblyString(R"( |
| 338 | +; ModuleID = '<string>' |
| 339 | +source_filename = "<string1>" |
| 340 | +
|
| 341 | +@GV1 = external global i32 |
| 342 | +
|
| 343 | +@GA1 = alias void (), ptr @Foo1 |
| 344 | +
|
| 345 | +define void @Foo1() { |
| 346 | + ret void |
| 347 | +} |
| 348 | +
|
| 349 | +!llvm.module.flags = !{!0} |
| 350 | +!llvm.dbg.cu = !{!1} |
| 351 | +!foo1 = !{!3} |
| 352 | +!bar1 = !{!4} |
| 353 | +
|
| 354 | +!0 = !{i32 2, !"Debug Info Version", i32 3} |
| 355 | +!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang1", isOptimized: true, flags: "-O2", runtimeVersion: 0, splitDebugFilename: "abc.debug", emissionKind: LineTablesOnly) |
| 356 | +!2 = !DIFile(filename: "path/to/file1", directory: "/path/to/dir1") |
| 357 | +!3 = !DILocation(line: 12, column: 34, scope: !4) |
| 358 | +!4 = distinct !DISubprogram(name: "foo1", scope: null, spFlags: DISPFlagDefinition, unit: !1) |
| 359 | +)", |
| 360 | + Err, Context); |
| 361 | + ASSERT_TRUE(M1.get()); |
| 362 | + |
| 363 | + StringLiteral M2Str = R"( |
| 364 | +; ModuleID = '<string>' |
| 365 | +source_filename = "<string2>" |
| 366 | +
|
| 367 | +@GV2 = external global i32 |
| 368 | +
|
| 369 | +@GA2 = alias void (), ptr @Foo2 |
| 370 | +
|
| 371 | +define void @Foo2() { |
| 372 | + ret void |
| 373 | +} |
| 374 | +
|
| 375 | +!llvm.module.flags = !{!0} |
| 376 | +!llvm.dbg.cu = !{!1} |
| 377 | +!foo2 = !{!3} |
| 378 | +!bar2 = !{!4} |
| 379 | +
|
| 380 | +!0 = !{i32 2, !"Debug Info Version", i32 3} |
| 381 | +!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang2", isOptimized: true, flags: "-O2", runtimeVersion: 0, splitDebugFilename: "abc.debug", emissionKind: LineTablesOnly) |
| 382 | +!2 = !DIFile(filename: "path/to/file2", directory: "/path/to/dir2") |
| 383 | +!3 = !DILocation(line: 1234, column: 56, scope: !4) |
| 384 | +!4 = distinct !DISubprogram(name: "foo2", scope: null, spFlags: DISPFlagDefinition, unit: !1) |
| 385 | +)"; |
| 386 | + { |
| 387 | + std::unique_ptr<Module> M2 = parseAssemblyString(M2Str, Err, Context); |
| 388 | + ASSERT_TRUE(M2.get()); |
| 389 | + auto *GV1 = M1->getNamedValue("GV1"); |
| 390 | + ASSERT_TRUE(GV1); |
| 391 | + auto *GV2 = M2->getNamedValue("GV2"); |
| 392 | + ASSERT_TRUE(GV2); |
| 393 | + ASSERT_EQ(GV2->getParent(), &*M2); |
| 394 | + *M1 = std::move(*M2); |
| 395 | + ASSERT_EQ(GV2->getParent(), &*M1); |
| 396 | + } |
| 397 | + |
| 398 | + std::string M1Print; |
| 399 | + { |
| 400 | + llvm::raw_string_ostream Os(M1Print); |
| 401 | + Os << "\n" << *M1; |
| 402 | + } |
| 403 | + ASSERT_EQ(M2Str, M1Print); |
| 404 | +} |
| 405 | + |
329 | 406 | } // end namespace
|
0 commit comments