Check type for forward reference definition

The types of forward references are checked that they match with other
uses, but they do not check they match with the definition.

    func @forward_reference_type_check() -> (i8) {
      br ^bb2

    ^bb1:
      return %1 : i8

    ^bb2:
      %1 = "bar"() : () -> (f32)
      br ^bb1
    }

Would be parsed and the use site of '%1' would be silently changed to
'f32'.

This commit adds a test for this case, and a check during parsing for
the types to match.

Patch by Matthew Parkinson <mattpark@microsoft.com>

Closes D79317.
This commit is contained in:
Renato Golin 2020-05-05 10:03:26 +01:00
parent ed7db68c35
commit 5010b5b7e6
2 changed files with 23 additions and 0 deletions

View File

@ -3625,6 +3625,14 @@ ParseResult OperationParser::addDefinition(SSAUseInfo useInfo, Value value) {
.append("previously defined here");
}
if (existing.getType() != value.getType()) {
return emitError(useInfo.loc)
.append("definition of SSA value '", useInfo.name, "#",
useInfo.number, "' has type ", value.getType())
.attachNote(getEncodedSourceLocation(entries[useInfo.number].second))
.append("previously used here with type ", existing.getType());
}
// If it was a forward reference, update everything that used it to use
// the actual definition instead, delete the forward ref, and remove it
// from our set of forward references we track.

View File

@ -1512,3 +1512,18 @@ func @duplicate_dictionary_attr_key() {
// expected-error @+1 {{duplicate key in dictionary attribute}}
"foo.op"() {a, a} : () -> ()
}
// -----
func @forward_reference_type_check() -> (i8) {
br ^bb2
^bb1:
// expected-note @+1 {{previously used here with type 'i8'}}
return %1 : i8
^bb2:
// expected-error @+1 {{definition of SSA value '%1#0' has type 'f32'}}
%1 = "bar"() : () -> (f32)
br ^bb1
}