Merge pull request #990 from hvitved/csharp/cfg/get-a-thrown-exception

C#: Reduce size of `getAThrownException()`
This commit is contained in:
Calum Grant
2019-03-06 12:31:00 +00:00
committed by GitHub
3 changed files with 60 additions and 2 deletions

View File

@@ -19,6 +19,11 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
/** Gets the enclosing callable of this element, if any. */
Callable getEnclosingCallable() { none() }
/** Gets the assembly that this element was compiled into. */
Assembly getAssembly() {
result = this.getEnclosingCallable().getDeclaringType().getALocation()
}
/**
* Gets a control flow node for this element. That is, a node in the
* control flow graph that corresponds to this element.

View File

@@ -185,14 +185,28 @@ private class Overflowable extends UnaryOperation {
}
}
private class CoreLib extends Assembly {
CoreLib() { this = any(SystemExceptionClass c).getALocation() }
}
/**
* Holds if assembly `a` was definitely compiled with core library `core`.
*/
pragma[noinline]
private predicate assemblyCompiledWithCoreLib(Assembly a, CoreLib core) {
a.getAnAttribute().getType().getBaseClass*().(SystemAttributeClass).getALocation() = core
}
/** A control flow element that is inside a `try` block. */
private class TriedControlFlowElement extends ControlFlowElement {
TriedControlFlowElement() { this = any(TryStmt try).getATriedElement() }
TryStmt try;
TriedControlFlowElement() { this = try.getATriedElement() }
/**
* Gets an exception class that is potentially thrown by this element, if any.
*/
Class getAThrownException() {
private Class getAThrownException0() {
this instanceof Overflowable and
result instanceof SystemOverflowExceptionClass
or
@@ -249,6 +263,40 @@ private class TriedControlFlowElement extends ControlFlowElement {
this instanceof StringLiteral and
result instanceof SystemOutOfMemoryExceptionClass
}
private CoreLib getCoreLibFromACatchClause() {
exists(SpecificCatchClause scc | scc = try.getACatchClause() |
result = scc.getCaughtExceptionType().getBaseClass*().(SystemExceptionClass).getALocation()
)
}
private CoreLib getCoreLib() {
result = this.getCoreLibFromACatchClause()
or
not exists(this.getCoreLibFromACatchClause()) and
assemblyCompiledWithCoreLib(this.getAssembly(), result)
}
pragma[noinline]
private Class getAThrownExceptionFromPlausibleCoreLib(string name) {
result = this.getAThrownException0() and
name = result.getQualifiedName() and
(
not exists(this.getCoreLib())
or
this.getCoreLib() = result.getALocation()
)
}
Class getAThrownException() {
exists(string name | result = this.getAThrownExceptionFromPlausibleCoreLib(name) |
result = min(Class c |
c = this.getAThrownExceptionFromPlausibleCoreLib(name)
|
c order by c.getLocation().(Assembly).getFullName()
)
)
}
}
pragma[noinline]

View File

@@ -56,6 +56,11 @@ class SystemArrayClass extends SystemClass {
SystemArrayClass() { this.hasName("Array") }
}
/** `System.Attribute` class. */
class SystemAttributeClass extends SystemClass {
SystemAttributeClass() { this.hasName("Attribute") }
}
/** The `System.Boolean` structure. */
class SystemBooleanStruct extends BoolType {
/** Gets the `Parse(string)` method. */