Bug Summary

File:build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/mlir/lib/AsmParser/TypeParser.cpp
Warning:line 514, column 7
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name TypeParser.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-16/lib/clang/16.0.0 -D MLIR_CUDA_CONVERSIONS_ENABLED=1 -D MLIR_ROCM_CONVERSIONS_ENABLED=1 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/mlir/lib/AsmParser -I /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/mlir/lib/AsmParser -I include -I /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/include -I /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/mlir/include -I tools/mlir/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-16/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/= -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-10-03-140002-15933-1 -x c++ /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/mlir/lib/AsmParser/TypeParser.cpp
1//===- TypeParser.cpp - MLIR Type Parser Implementation -------------------===//
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// This file implements the parser for the MLIR Types.
10//
11//===----------------------------------------------------------------------===//
12
13#include "Parser.h"
14#include "mlir/IR/AffineMap.h"
15#include "mlir/IR/BuiltinTypes.h"
16#include "mlir/IR/OpDefinition.h"
17#include "mlir/IR/TensorEncoding.h"
18
19using namespace mlir;
20using namespace mlir::detail;
21
22/// Optionally parse a type.
23OptionalParseResult Parser::parseOptionalType(Type &type) {
24 // There are many different starting tokens for a type, check them here.
25 switch (getToken().getKind()) {
26 case Token::l_paren:
27 case Token::kw_memref:
28 case Token::kw_tensor:
29 case Token::kw_complex:
30 case Token::kw_tuple:
31 case Token::kw_vector:
32 case Token::inttype:
33 case Token::kw_bf16:
34 case Token::kw_f16:
35 case Token::kw_f32:
36 case Token::kw_f64:
37 case Token::kw_f80:
38 case Token::kw_f128:
39 case Token::kw_index:
40 case Token::kw_none:
41 case Token::exclamation_identifier:
42 return failure(!(type = parseType()));
43
44 default:
45 return llvm::None;
46 }
47}
48
49/// Parse an arbitrary type.
50///
51/// type ::= function-type
52/// | non-function-type
53///
54Type Parser::parseType() {
55 if (getToken().is(Token::l_paren))
56 return parseFunctionType();
57 return parseNonFunctionType();
58}
59
60/// Parse a function result type.
61///
62/// function-result-type ::= type-list-parens
63/// | non-function-type
64///
65ParseResult Parser::parseFunctionResultTypes(SmallVectorImpl<Type> &elements) {
66 if (getToken().is(Token::l_paren))
67 return parseTypeListParens(elements);
68
69 Type t = parseNonFunctionType();
70 if (!t)
71 return failure();
72 elements.push_back(t);
73 return success();
74}
75
76/// Parse a list of types without an enclosing parenthesis. The list must have
77/// at least one member.
78///
79/// type-list-no-parens ::= type (`,` type)*
80///
81ParseResult Parser::parseTypeListNoParens(SmallVectorImpl<Type> &elements) {
82 auto parseElt = [&]() -> ParseResult {
83 auto elt = parseType();
84 elements.push_back(elt);
85 return elt ? success() : failure();
86 };
87
88 return parseCommaSeparatedList(parseElt);
89}
90
91/// Parse a parenthesized list of types.
92///
93/// type-list-parens ::= `(` `)`
94/// | `(` type-list-no-parens `)`
95///
96ParseResult Parser::parseTypeListParens(SmallVectorImpl<Type> &elements) {
97 if (parseToken(Token::l_paren, "expected '('"))
98 return failure();
99
100 // Handle empty lists.
101 if (getToken().is(Token::r_paren))
102 return consumeToken(), success();
103
104 if (parseTypeListNoParens(elements) ||
105 parseToken(Token::r_paren, "expected ')'"))
106 return failure();
107 return success();
108}
109
110/// Parse a complex type.
111///
112/// complex-type ::= `complex` `<` type `>`
113///
114Type Parser::parseComplexType() {
115 consumeToken(Token::kw_complex);
116
117 // Parse the '<'.
118 if (parseToken(Token::less, "expected '<' in complex type"))
119 return nullptr;
120
121 SMLoc elementTypeLoc = getToken().getLoc();
122 auto elementType = parseType();
123 if (!elementType ||
124 parseToken(Token::greater, "expected '>' in complex type"))
125 return nullptr;
126 if (!elementType.isa<FloatType>() && !elementType.isa<IntegerType>())
127 return emitError(elementTypeLoc, "invalid element type for complex"),
128 nullptr;
129
130 return ComplexType::get(elementType);
131}
132
133/// Parse a function type.
134///
135/// function-type ::= type-list-parens `->` function-result-type
136///
137Type Parser::parseFunctionType() {
138 assert(getToken().is(Token::l_paren))(static_cast <bool> (getToken().is(Token::l_paren)) ? void
(0) : __assert_fail ("getToken().is(Token::l_paren)", "mlir/lib/AsmParser/TypeParser.cpp"
, 138, __extension__ __PRETTY_FUNCTION__))
;
139
140 SmallVector<Type, 4> arguments, results;
141 if (parseTypeListParens(arguments) ||
142 parseToken(Token::arrow, "expected '->' in function type") ||
143 parseFunctionResultTypes(results))
144 return nullptr;
145
146 return builder.getFunctionType(arguments, results);
147}
148
149/// Parse a memref type.
150///
151/// memref-type ::= ranked-memref-type | unranked-memref-type
152///
153/// ranked-memref-type ::= `memref` `<` dimension-list-ranked type
154/// (`,` layout-specification)? (`,` memory-space)? `>`
155///
156/// unranked-memref-type ::= `memref` `<*x` type (`,` memory-space)? `>`
157///
158/// stride-list ::= `[` (dimension (`,` dimension)*)? `]`
159/// strided-layout ::= `offset:` dimension `,` `strides: ` stride-list
160/// layout-specification ::= semi-affine-map | strided-layout | attribute
161/// memory-space ::= integer-literal | attribute
162///
163Type Parser::parseMemRefType() {
164 SMLoc loc = getToken().getLoc();
165 consumeToken(Token::kw_memref);
166
167 if (parseToken(Token::less, "expected '<' in memref type"))
168 return nullptr;
169
170 bool isUnranked;
171 SmallVector<int64_t, 4> dimensions;
172
173 if (consumeIf(Token::star)) {
174 // This is an unranked memref type.
175 isUnranked = true;
176 if (parseXInDimensionList())
177 return nullptr;
178
179 } else {
180 isUnranked = false;
181 if (parseDimensionListRanked(dimensions))
182 return nullptr;
183 }
184
185 // Parse the element type.
186 auto typeLoc = getToken().getLoc();
187 auto elementType = parseType();
188 if (!elementType)
189 return nullptr;
190
191 // Check that memref is formed from allowed types.
192 if (!BaseMemRefType::isValidElementType(elementType))
193 return emitError(typeLoc, "invalid memref element type"), nullptr;
194
195 MemRefLayoutAttrInterface layout;
196 Attribute memorySpace;
197
198 auto parseElt = [&]() -> ParseResult {
199 // Either it is MemRefLayoutAttrInterface or memory space attribute.
200 Attribute attr = parseAttribute();
201 if (!attr)
202 return failure();
203
204 if (attr.isa<MemRefLayoutAttrInterface>()) {
205 layout = attr.cast<MemRefLayoutAttrInterface>();
206 } else if (memorySpace) {
207 return emitError("multiple memory spaces specified in memref type");
208 } else {
209 memorySpace = attr;
210 return success();
211 }
212
213 if (isUnranked)
214 return emitError("cannot have affine map for unranked memref type");
215 if (memorySpace)
216 return emitError("expected memory space to be last in memref type");
217
218 return success();
219 };
220
221 // Parse a list of mappings and address space if present.
222 if (!consumeIf(Token::greater)) {
223 // Parse comma separated list of affine maps, followed by memory space.
224 if (parseToken(Token::comma, "expected ',' or '>' in memref type") ||
225 parseCommaSeparatedListUntil(Token::greater, parseElt,
226 /*allowEmptyList=*/false)) {
227 return nullptr;
228 }
229 }
230
231 if (isUnranked)
232 return getChecked<UnrankedMemRefType>(loc, elementType, memorySpace);
233
234 return getChecked<MemRefType>(loc, dimensions, elementType, layout,
235 memorySpace);
236}
237
238/// Parse any type except the function type.
239///
240/// non-function-type ::= integer-type
241/// | index-type
242/// | float-type
243/// | extended-type
244/// | vector-type
245/// | tensor-type
246/// | memref-type
247/// | complex-type
248/// | tuple-type
249/// | none-type
250///
251/// index-type ::= `index`
252/// float-type ::= `f16` | `bf16` | `f32` | `f64` | `f80` | `f128`
253/// none-type ::= `none`
254///
255Type Parser::parseNonFunctionType() {
256 switch (getToken().getKind()) {
257 default:
258 return (emitWrongTokenError("expected non-function type"), nullptr);
259 case Token::kw_memref:
260 return parseMemRefType();
261 case Token::kw_tensor:
262 return parseTensorType();
263 case Token::kw_complex:
264 return parseComplexType();
265 case Token::kw_tuple:
266 return parseTupleType();
267 case Token::kw_vector:
268 return parseVectorType();
269 // integer-type
270 case Token::inttype: {
271 auto width = getToken().getIntTypeBitwidth();
272 if (!width.has_value())
273 return (emitError("invalid integer width"), nullptr);
274 if (width.value() > IntegerType::kMaxWidth) {
275 emitError(getToken().getLoc(), "integer bitwidth is limited to ")
276 << IntegerType::kMaxWidth << " bits";
277 return nullptr;
278 }
279
280 IntegerType::SignednessSemantics signSemantics = IntegerType::Signless;
281 if (Optional<bool> signedness = getToken().getIntTypeSignedness())
282 signSemantics = *signedness ? IntegerType::Signed : IntegerType::Unsigned;
283
284 consumeToken(Token::inttype);
285 return IntegerType::get(getContext(), *width, signSemantics);
286 }
287
288 // float-type
289 case Token::kw_bf16:
290 consumeToken(Token::kw_bf16);
291 return builder.getBF16Type();
292 case Token::kw_f16:
293 consumeToken(Token::kw_f16);
294 return builder.getF16Type();
295 case Token::kw_f32:
296 consumeToken(Token::kw_f32);
297 return builder.getF32Type();
298 case Token::kw_f64:
299 consumeToken(Token::kw_f64);
300 return builder.getF64Type();
301 case Token::kw_f80:
302 consumeToken(Token::kw_f80);
303 return builder.getF80Type();
304 case Token::kw_f128:
305 consumeToken(Token::kw_f128);
306 return builder.getF128Type();
307
308 // index-type
309 case Token::kw_index:
310 consumeToken(Token::kw_index);
311 return builder.getIndexType();
312
313 // none-type
314 case Token::kw_none:
315 consumeToken(Token::kw_none);
316 return builder.getNoneType();
317
318 // extended type
319 case Token::exclamation_identifier:
320 return parseExtendedType();
321
322 // Handle completion of a dialect type.
323 case Token::code_complete:
324 if (getToken().isCodeCompletionFor(Token::exclamation_identifier))
325 return parseExtendedType();
326 return codeCompleteType();
327 }
328}
329
330/// Parse a tensor type.
331///
332/// tensor-type ::= `tensor` `<` dimension-list type `>`
333/// dimension-list ::= dimension-list-ranked | `*x`
334///
335Type Parser::parseTensorType() {
336 consumeToken(Token::kw_tensor);
337
338 if (parseToken(Token::less, "expected '<' in tensor type"))
339 return nullptr;
340
341 bool isUnranked;
342 SmallVector<int64_t, 4> dimensions;
343
344 if (consumeIf(Token::star)) {
345 // This is an unranked tensor type.
346 isUnranked = true;
347
348 if (parseXInDimensionList())
349 return nullptr;
350
351 } else {
352 isUnranked = false;
353 if (parseDimensionListRanked(dimensions))
354 return nullptr;
355 }
356
357 // Parse the element type.
358 auto elementTypeLoc = getToken().getLoc();
359 auto elementType = parseType();
360
361 // Parse an optional encoding attribute.
362 Attribute encoding;
363 if (consumeIf(Token::comma)) {
364 encoding = parseAttribute();
365 if (auto v = encoding.dyn_cast_or_null<VerifiableTensorEncoding>()) {
366 if (failed(v.verifyEncoding(dimensions, elementType,
367 [&] { return emitError(); })))
368 return nullptr;
369 }
370 }
371
372 if (!elementType || parseToken(Token::greater, "expected '>' in tensor type"))
373 return nullptr;
374 if (!TensorType::isValidElementType(elementType))
375 return emitError(elementTypeLoc, "invalid tensor element type"), nullptr;
376
377 if (isUnranked) {
378 if (encoding)
379 return emitError("cannot apply encoding to unranked tensor"), nullptr;
380 return UnrankedTensorType::get(elementType);
381 }
382 return RankedTensorType::get(dimensions, elementType, encoding);
383}
384
385/// Parse a tuple type.
386///
387/// tuple-type ::= `tuple` `<` (type (`,` type)*)? `>`
388///
389Type Parser::parseTupleType() {
390 consumeToken(Token::kw_tuple);
391
392 // Parse the '<'.
393 if (parseToken(Token::less, "expected '<' in tuple type"))
394 return nullptr;
395
396 // Check for an empty tuple by directly parsing '>'.
397 if (consumeIf(Token::greater))
398 return TupleType::get(getContext());
399
400 // Parse the element types and the '>'.
401 SmallVector<Type, 4> types;
402 if (parseTypeListNoParens(types) ||
403 parseToken(Token::greater, "expected '>' in tuple type"))
404 return nullptr;
405
406 return TupleType::get(getContext(), types);
407}
408
409/// Parse a vector type.
410///
411/// vector-type ::= `vector` `<` vector-dim-list vector-element-type `>`
412/// vector-dim-list := (static-dim-list `x`)? (`[` static-dim-list `]` `x`)?
413/// static-dim-list ::= decimal-literal (`x` decimal-literal)*
414///
415VectorType Parser::parseVectorType() {
416 consumeToken(Token::kw_vector);
417
418 if (parseToken(Token::less, "expected '<' in vector type"))
419 return nullptr;
420
421 SmallVector<int64_t, 4> dimensions;
422 unsigned numScalableDims;
423 if (parseVectorDimensionList(dimensions, numScalableDims))
424 return nullptr;
425 if (any_of(dimensions, [](int64_t i) { return i <= 0; }))
426 return emitError(getToken().getLoc(),
427 "vector types must have positive constant sizes"),
428 nullptr;
429
430 // Parse the element type.
431 auto typeLoc = getToken().getLoc();
432 auto elementType = parseType();
433 if (!elementType || parseToken(Token::greater, "expected '>' in vector type"))
434 return nullptr;
435
436 if (!VectorType::isValidElementType(elementType))
437 return emitError(typeLoc, "vector elements must be int/index/float type"),
438 nullptr;
439
440 return VectorType::get(dimensions, elementType, numScalableDims);
441}
442
443/// Parse a dimension list in a vector type. This populates the dimension list,
444/// and returns the number of scalable dimensions in `numScalableDims`.
445///
446/// vector-dim-list := (static-dim-list `x`)? (`[` static-dim-list `]` `x`)?
447/// static-dim-list ::= decimal-literal (`x` decimal-literal)*
448///
449ParseResult
450Parser::parseVectorDimensionList(SmallVectorImpl<int64_t> &dimensions,
451 unsigned &numScalableDims) {
452 numScalableDims = 0;
453 // If there is a set of fixed-length dimensions, consume it
454 while (getToken().is(Token::integer)) {
455 int64_t value;
456 if (parseIntegerInDimensionList(value))
457 return failure();
458 dimensions.push_back(value);
459 // Make sure we have an 'x' or something like 'xbf32'.
460 if (parseXInDimensionList())
461 return failure();
462 }
463 // If there is a set of scalable dimensions, consume it
464 if (consumeIf(Token::l_square)) {
465 while (getToken().is(Token::integer)) {
466 int64_t value;
467 if (parseIntegerInDimensionList(value))
468 return failure();
469 dimensions.push_back(value);
470 numScalableDims++;
471 // Check if we have reached the end of the scalable dimension list
472 if (consumeIf(Token::r_square)) {
473 // Make sure we have something like 'xbf32'.
474 return parseXInDimensionList();
475 }
476 // Make sure we have an 'x'
477 if (parseXInDimensionList())
478 return failure();
479 }
480 // If we make it here, we've finished parsing the dimension list
481 // without finding ']' closing the set of scalable dimensions
482 return emitWrongTokenError(
483 "missing ']' closing set of scalable dimensions");
484 }
485
486 return success();
487}
488
489/// Parse a dimension list of a tensor or memref type. This populates the
490/// dimension list, using -1 for the `?` dimensions if `allowDynamic` is set and
491/// errors out on `?` otherwise. Parsing the trailing `x` is configurable.
492///
493/// dimension-list ::= eps | dimension (`x` dimension)*
494/// dimension-list-with-trailing-x ::= (dimension `x`)*
495/// dimension ::= `?` | decimal-literal
496///
497/// When `allowDynamic` is not set, this is used to parse:
498///
499/// static-dimension-list ::= eps | decimal-literal (`x` decimal-literal)*
500/// static-dimension-list-with-trailing-x ::= (dimension `x`)*
501ParseResult
502Parser::parseDimensionListRanked(SmallVectorImpl<int64_t> &dimensions,
503 bool allowDynamic, bool withTrailingX) {
504 auto parseDim = [&]() -> LogicalResult {
505 auto loc = getToken().getLoc();
506 if (consumeIf(Token::question)) {
1
Taking false branch
507 if (!allowDynamic)
508 return emitError(loc, "expected static shape");
509 dimensions.push_back(-1);
510 } else {
511 int64_t value;
2
'value' declared without an initial value
512 if (failed(parseIntegerInDimensionList(value)))
3
Calling 'Parser::parseIntegerInDimensionList'
8
Returning from 'Parser::parseIntegerInDimensionList'
9
Taking false branch
513 return failure();
514 dimensions.push_back(value);
10
1st function call argument is an uninitialized value
515 }
516 return success();
517 };
518
519 if (withTrailingX) {
520 while (getToken().isAny(Token::integer, Token::question)) {
521 if (failed(parseDim()) || failed(parseXInDimensionList()))
522 return failure();
523 }
524 return success();
525 }
526
527 if (getToken().isAny(Token::integer, Token::question)) {
528 if (failed(parseDim()))
529 return failure();
530 while (getToken().is(Token::bare_identifier) &&
531 getTokenSpelling()[0] == 'x') {
532 if (failed(parseXInDimensionList()) || failed(parseDim()))
533 return failure();
534 }
535 }
536 return success();
537}
538
539ParseResult Parser::parseIntegerInDimensionList(int64_t &value) {
540 // Hexadecimal integer literals (starting with `0x`) are not allowed in
541 // aggregate type declarations. Therefore, `0xf32` should be processed as
542 // a sequence of separate elements `0`, `x`, `f32`.
543 if (getTokenSpelling().size() > 1 && getTokenSpelling()[1] == 'x') {
4
Assuming the condition is false
5
Taking false branch
544 // We can get here only if the token is an integer literal. Hexadecimal
545 // integer literals can only start with `0x` (`1x` wouldn't lex as a
546 // literal, just `1` would, at which point we don't get into this
547 // branch).
548 assert(getTokenSpelling()[0] == '0' && "invalid integer literal")(static_cast <bool> (getTokenSpelling()[0] == '0' &&
"invalid integer literal") ? void (0) : __assert_fail ("getTokenSpelling()[0] == '0' && \"invalid integer literal\""
, "mlir/lib/AsmParser/TypeParser.cpp", 548, __extension__ __PRETTY_FUNCTION__
))
;
549 value = 0;
550 state.lex.resetPointer(getTokenSpelling().data() + 1);
551 consumeToken();
552 } else {
553 // Make sure this integer value is in bound and valid.
554 Optional<uint64_t> dimension = getToken().getUInt64IntegerValue();
555 if (!dimension ||
6
Assuming the condition is true
556 *dimension > (uint64_t)std::numeric_limits<int64_t>::max())
557 return emitError("invalid dimension");
7
Returning without writing to 'value'
558 value = (int64_t)*dimension;
559 consumeToken(Token::integer);
560 }
561 return success();
562}
563
564/// Parse an 'x' token in a dimension list, handling the case where the x is
565/// juxtaposed with an element type, as in "xf32", leaving the "f32" as the next
566/// token.
567ParseResult Parser::parseXInDimensionList() {
568 if (getToken().isNot(Token::bare_identifier) || getTokenSpelling()[0] != 'x')
569 return emitWrongTokenError("expected 'x' in dimension list");
570
571 // If we had a prefix of 'x', lex the next token immediately after the 'x'.
572 if (getTokenSpelling().size() != 1)
573 state.lex.resetPointer(getTokenSpelling().data() + 1);
574
575 // Consume the 'x'.
576 consumeToken(Token::bare_identifier);
577
578 return success();
579}