Skip to content

Fix for #7128 Methods with return type [object] should return null for an empty result #7138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 2, 2018

Conversation

BrucePay
Copy link
Collaborator

@BrucePay BrucePay commented Jun 21, 2018

PR Summary

Fix: #7128

If a method was typed to return [object] but no actual value was returned then you would get an index-out-of-range exception because the code expected a value in the result collection but there was none. The fix is to check to see if the array is empty. If it is, then return default(T).

PR Checklist

@BrucePay BrucePay requested a review from lzybkr June 21, 2018 22:37
@BrucePay BrucePay requested a review from daxian-dbw as a code owner June 21, 2018 22:37
static [object] Bar2() { return & {} }
}
# Test instance method
[Foo]::new().Bar1() | Should -BeNullOrEmpty
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could explicitly check result type. I believe it make sense to use testcase for two return types (object and int/string) to ensure that default(T) works as expected.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only time this code path is hit is if the method returns [object]. All of the other cases are already handled elsewhere. And the object returned is null. How do you propose checking it's type?

Copy link
Collaborator

@iSazonov iSazonov Jun 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, it was my misunderstanding of default(T).

Should it be Should -BeNull?

@iSazonov
Copy link
Collaborator

If a method is "find a file" what it may indicate that "file not found" if it can not return null?

@@ -519,7 +519,10 @@ internal T InvokeAsMemberFunctionT<T>(object instance, object[] args)
invocationInfo: null,
propagateAllExceptionsToTop: true,
args: args);
Diagnostics.Assert(result.Count == 1, "Code generation ensures we return the correct type");
if (result.Count == 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the change, but it feels really dirty because in an indirect way, it allows a method to not return a value, similar to the parser allowing the method to omit a return statement.

Unfortunately I can't think of a cleaner fix. I suppose it's worth adding a comment explaining that this is not to allow methods to omit a return statement.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - it feels dirty to me but pipeline semantics make it necessary. I like the idea of adding a comment to explain it.

Copy link
Contributor

@lzybkr lzybkr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that a fix in the compiler is slightly nicer from a performance point of view - you would omit the check for non-object returning methods, but that fix is slightly more involved.

I would have asked for that if we could rely on the syntax, but the bug is still an issue with expressions:

class C {
    static [object] f() {
        $o = & {} 
        return $o
    }
}
[C]::f()

@daxian-dbw daxian-dbw merged commit dbaa1ad into PowerShell:master Jul 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Returning nothing (Automation.Null) from an [object]-typed custom-class method breaks
4 participants