18
18
#include " gmock/gmock.h"
19
19
#include " gtest/gtest.h"
20
20
21
- #include < algorithm>
22
- #include < cstdlib>
23
- #include < memory>
24
-
25
21
using namespace llvm ;
26
22
using namespace mlir ;
27
23
28
- using testing::ElementsAre ;
24
+ using :: testing::StartsWith ;
29
25
30
26
StringLiteral IRWithResources = R"(
31
27
module @TestDialectResources attributes {
@@ -34,7 +30,7 @@ module @TestDialectResources attributes {
34
30
{-#
35
31
dialect_resources: {
36
32
builtin: {
37
- resource: "0x1000000001000000020000000300000004000000 "
33
+ resource: "0x2000000001000000020000000300000004000000 "
38
34
}
39
35
}
40
36
#-}
@@ -52,19 +48,19 @@ TEST(Bytecode, MultiModuleWithResource) {
52
48
std::string buffer;
53
49
llvm::raw_string_ostream ostream (buffer);
54
50
ASSERT_TRUE (succeeded (writeBytecodeToFile (module .get (), ostream)));
55
-
56
- // Make a sufficiently aligned copy of the buffer for reading it back.
57
51
ostream.flush ();
58
- constexpr std::size_t kAlignment = 16 ; // AsmResourceBlob alignment.
59
- auto deleter = [](char *ptr) { std::free (ptr); };
60
- std::unique_ptr<char , decltype (deleter)> aligned_buffer (
61
- static_cast <char *>(std::aligned_alloc (kAlignment , buffer.size ())),
62
- deleter);
63
- std::copy (buffer.begin (), buffer.end (), aligned_buffer.get ());
52
+
53
+ // Create copy of buffer which is aligned to requested resource alignment.
54
+ constexpr size_t kAlignment = 0x20 ;
55
+ size_t buffer_size = buffer.size ();
56
+ buffer.reserve (buffer_size + kAlignment - 1 );
57
+ size_t pad = ~(uintptr_t )buffer.data () + 1 & kAlignment - 1 ;
58
+ buffer.insert (0 , pad, ' ' );
59
+ StringRef aligned_buffer (buffer.data () + pad, buffer_size);
64
60
65
61
// Parse it back
66
- OwningOpRef<Operation *> roundTripModule = parseSourceString<Operation *>(
67
- {aligned_buffer. get (), buffer. size ()} , parseConfig);
62
+ OwningOpRef<Operation *> roundTripModule =
63
+ parseSourceString<Operation *>(aligned_buffer , parseConfig);
68
64
ASSERT_TRUE (roundTripModule);
69
65
70
66
// FIXME: Parsing external resources does not work on big-endian
@@ -92,3 +88,39 @@ TEST(Bytecode, MultiModuleWithResource) {
92
88
checkResourceAttribute (*module );
93
89
checkResourceAttribute (*roundTripModule);
94
90
}
91
+
92
+ TEST (Bytecode, InsufficientAlignmentFailure) {
93
+ MLIRContext context;
94
+ Builder builder (&context);
95
+ ParserConfig parseConfig (&context);
96
+ OwningOpRef<Operation *> module =
97
+ parseSourceString<Operation *>(IRWithResources, parseConfig);
98
+ ASSERT_TRUE (module );
99
+
100
+ // Write the module to bytecode
101
+ std::string buffer;
102
+ llvm::raw_string_ostream ostream (buffer);
103
+ ASSERT_TRUE (succeeded (writeBytecodeToFile (module .get (), ostream)));
104
+ ostream.flush ();
105
+
106
+ // Create copy of buffer which is insufficiently aligned.
107
+ constexpr size_t kAlignment = 0x20 ;
108
+ size_t buffer_size = buffer.size ();
109
+ buffer.reserve (buffer_size + kAlignment - 1 );
110
+ size_t pad = ~(uintptr_t )buffer.data () + kAlignment / 2 + 1 & kAlignment - 1 ;
111
+ buffer.insert (0 , pad, ' ' );
112
+ StringRef misaligned_buffer (buffer.data () + pad, buffer_size);
113
+
114
+ std::unique_ptr<Diagnostic> diagnostic;
115
+ context.getDiagEngine ().registerHandler ([&](Diagnostic &diag) {
116
+ diagnostic = std::make_unique<Diagnostic>(std::move (diag));
117
+ });
118
+
119
+ // Try to parse it back and check for alignment error.
120
+ OwningOpRef<Operation *> roundTripModule =
121
+ parseSourceString<Operation *>(misaligned_buffer, parseConfig);
122
+ EXPECT_FALSE (roundTripModule);
123
+ ASSERT_TRUE (diagnostic);
124
+ EXPECT_THAT (diagnostic->str (),
125
+ StartsWith (" expected bytecode buffer to be aligned to 32" ));
126
+ }
0 commit comments