diff --git a/mlir/lib/Parser/Parser.cpp b/mlir/lib/Parser/Parser.cpp --- a/mlir/lib/Parser/Parser.cpp +++ b/mlir/lib/Parser/Parser.cpp @@ -1676,6 +1676,7 @@ if (parseToken(Token::l_brace, "expected '{' in attribute dictionary")) return failure(); + llvm::SmallDenseSet seenKeys; auto parseElt = [&]() -> ParseResult { // The name of an attribute can either be a bare identifier, or a string. Optional nameId; @@ -1686,6 +1687,8 @@ nameId = builder.getIdentifier(getTokenSpelling()); else return emitError("expected attribute name"); + if (!seenKeys.insert(*nameId).second) + return emitError("duplicate key in dictionary attribute"); consumeToken(); // Try to parse the '=' for the attribute value. diff --git a/mlir/test/IR/invalid.mlir b/mlir/test/IR/invalid.mlir --- a/mlir/test/IR/invalid.mlir +++ b/mlir/test/IR/invalid.mlir @@ -1489,3 +1489,10 @@ } : () -> () return } + +// ----- + +func @duplicate_dictionary_attr_key() { + // expected-error @+1 {{duplicate key in dictionary attribute}} + "foo.op"() {a, a} : () -> () +}