Skip to content

Python: Enhance points-to to support type-hint analysis.#1728

Merged
taus-semmle merged 3 commits into
github:masterfrom
markshannon:python-points-to-support-type-checking
Aug 15, 2019
Merged

Python: Enhance points-to to support type-hint analysis.#1728
taus-semmle merged 3 commits into
github:masterfrom
markshannon:python-points-to-support-type-checking

Conversation

@markshannon

Copy link
Copy Markdown
Contributor

Three changes to better track type hint objects during points-to.

  1. Changes the handling of instantiation for classes that may return instances of other classes.
    • We now track the instance, but return "unknown class" from .getClass().
    • This remains correct, but allows us to track values with complex classes, like those in the typing module.
  2. Track subscripts where the value being subscripted is likely to be a type-hint. That is, a class or a attribute of the typing module.
  3. A couple of fixes to the object model that came to light during these changes.
    • Fix some toString() implementations
    • Fix super-type calculation where MRO is missing or broken.

@markshannon markshannon force-pushed the python-points-to-support-type-checking branch from b41a9be to 1327e42 Compare August 12, 2019 13:28

@taus-semmle taus-semmle left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A few comments and questions, otherwise LGTM.

this = TSpecificInstance(_, result, _)
exists(ClassObjectInternal cls, ClassDecl decl |
this = TSpecificInstance(_, cls, _) and
decl = cls.getClassDeclaration() |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are these ClassObjectInternals guaranteed to have a ClassDecl? I'm wondering if we'll lose instances where TSpecificInstance(_, cls, _) exists, but cls.getClassDeclaration() fails (and where previously we would have used cls regardless).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If it doesn't have a ClassDecl then we won't be able to compute an MRO. Currently that applies to DynamicallyCreatedClass. Potentially getASuperType() could be improved for those, but this makes things no worse in that case.

result = Types::getMro(this).getAnItem()
result = this.getBaseType(_)
or
result = this.getASuperType().getBaseType(_)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I had to stare at this line for a while to convince myself that it was doing the right thing. Would it make more sense to do result = this.getBaseType(_).getASuperType() instead? This, at least, would make the recursion a bit more apparent (i.e. an improper supertype is either the class itself, one of its base classes, or an improper supertype of one of its base classes). I would also move result = this to be the first disjunct in that case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Alternatively, we could add getABaseType to ClassValue (same as what ClassObject has right now) and use getABaseType*().

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

taus-semmle
taus-semmle previously approved these changes Aug 15, 2019
@markshannon markshannon force-pushed the python-points-to-support-type-checking branch from 241d169 to 902871b Compare August 15, 2019 10:38
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.

2 participants