Skip to content

Commit 6ad8a4d

Browse files
committed
C#: Only use getTypeRef when there is not already a type available
1 parent a5bfeb6 commit 6ad8a4d

File tree

15 files changed

+187
-40
lines changed

15 files changed

+187
-40
lines changed

csharp/ql/lib/semmle/code/csharp/AnnotatedType.qll

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,21 @@ private int getElementTypeFlags(@has_type_annotation element) {
251251
result = strictsum(int b | type_annotation(element, b) | b)
252252
}
253253

254+
private predicate specificTypeParameterNullability(
255+
TypeParameterConstraints constraints, Type type, @nullability n
256+
) {
257+
specific_type_parameter_nullability(constraints, type, n)
258+
or
259+
specific_type_parameter_nullability(constraints, getTypeRef(type), n)
260+
}
261+
254262
private Annotations::Nullability getTypeParameterNullability(
255263
TypeParameterConstraints constraints, Type type
256264
) {
257-
if specific_type_parameter_nullability(constraints, getTypeRef(type), _)
258-
then
259-
specific_type_parameter_nullability(constraints, getTypeRef(type),
260-
Annotations::getNullability(result))
265+
if specificTypeParameterNullability(constraints, type, _)
266+
then specificTypeParameterNullability(constraints, type, Annotations::getNullability(result))
261267
else (
262-
specific_type_parameter_constraints(constraints, getTypeRef(type)) and
268+
type = constraints.getATypeConstraint() and
263269
result instanceof Annotations::NoNullability
264270
)
265271
}

csharp/ql/lib/semmle/code/csharp/Attribute.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,12 @@ private string getAttributeName(Attribute a) {
6262
*/
6363
class Attribute extends TopLevelExprParent, @attribute {
6464
/** Gets the type of this attribute. */
65-
Class getType() { attributes(this, _, getTypeRef(result), _) }
65+
Class getType() {
66+
attributes(this, _, result, _)
67+
or
68+
not attributes(this, _, any(Type t), _) and
69+
attributes(this, _, getTypeRef(result), _)
70+
}
6671

6772
/** Gets the element that this attribute is attached to. */
6873
Attributable getTarget() { attributes(this, _, _, result) }

csharp/ql/lib/semmle/code/csharp/Callable.qll

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,12 @@ class Method extends Callable, Virtualizable, Attributable, @method {
236236

237237
override ValueOrRefType getDeclaringType() { methods(this, _, result, _, _) }
238238

239-
override Type getReturnType() { methods(this, _, _, getTypeRef(result), _) }
239+
override Type getReturnType() {
240+
methods(this, _, _, result, _)
241+
or
242+
not methods(this, _, _, any(Type t), _) and
243+
methods(this, _, _, getTypeRef(result), _)
244+
}
240245

241246
override Method getUnboundDeclaration() { methods(this, _, _, _, result) }
242247

@@ -453,7 +458,12 @@ class Operator extends Callable, Member, Attributable, Overridable, @operator {
453458

454459
override ValueOrRefType getDeclaringType() { operators(this, _, _, result, _, _) }
455460

456-
override Type getReturnType() { operators(this, _, _, _, getTypeRef(result), _) }
461+
override Type getReturnType() {
462+
operators(this, _, _, _, result, _)
463+
or
464+
not operators(this, _, _, _, any(Type t), _) and
465+
operators(this, _, _, _, getTypeRef(result), _)
466+
}
457467

458468
override Operator getUnboundDeclaration() { operators(this, _, _, _, _, result) }
459469

csharp/ql/lib/semmle/code/csharp/Event.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ class Event extends DeclarationWithAccessors, @event {
2323

2424
override ValueOrRefType getDeclaringType() { events(this, _, result, _, _) }
2525

26-
override DelegateType getType() { events(this, _, _, getTypeRef(result), _) }
26+
override DelegateType getType() {
27+
events(this, _, _, result, _)
28+
or
29+
not events(this, _, _, any(Type t), _) and
30+
events(this, _, _, getTypeRef(result), _)
31+
}
2732

2833
/** Gets an `add` or `remove` accessor of this event, if any. */
2934
EventAccessor getAnEventAccessor() { result.getDeclaration() = this }

csharp/ql/lib/semmle/code/csharp/Generics.qll

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,11 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
261261
*/
262262
class TypeParameterConstraints extends Element, @type_parameter_constraints {
263263
/** Gets a specific type constraint, if any. */
264-
Type getATypeConstraint() { specific_type_parameter_constraints(this, getTypeRef(result)) }
264+
Type getATypeConstraint() {
265+
specific_type_parameter_constraints(this, result)
266+
or
267+
specific_type_parameter_constraints(this, getTypeRef(result))
268+
}
265269

266270
/** Gets an annotated specific type constraint, if any. */
267271
AnnotatedType getAnAnnotatedTypeConstraint() { result.appliesToTypeConstraint(this) }
@@ -413,9 +417,19 @@ class ConstructedType extends ValueOrRefType, ConstructedGeneric {
413417

414418
override Location getALocation() { result = this.getUnboundDeclaration().getALocation() }
415419

416-
override Type getTypeArgument(int n) { type_arguments(getTypeRef(result), n, this) }
420+
override Type getTypeArgument(int n) {
421+
type_arguments(result, n, this)
422+
or
423+
not type_arguments(any(Type t), n, this) and
424+
type_arguments(getTypeRef(result), n, this)
425+
}
417426

418-
override UnboundGenericType getUnboundGeneric() { constructed_generic(this, getTypeRef(result)) }
427+
override UnboundGenericType getUnboundGeneric() {
428+
constructed_generic(this, result)
429+
or
430+
not constructed_generic(this, any(Type t)) and
431+
constructed_generic(this, getTypeRef(result))
432+
}
419433

420434
final override Type getChild(int n) { result = this.getTypeArgument(n) }
421435

@@ -587,7 +601,12 @@ class UnboundGenericMethod extends Method, UnboundGeneric {
587601
class ConstructedMethod extends Method, ConstructedGeneric {
588602
override Location getALocation() { result = this.getUnboundDeclaration().getALocation() }
589603

590-
override Type getTypeArgument(int n) { type_arguments(getTypeRef(result), n, this) }
604+
override Type getTypeArgument(int n) {
605+
type_arguments(result, n, this)
606+
or
607+
not type_arguments(any(Type t), n, this) and
608+
type_arguments(getTypeRef(result), n, this)
609+
}
591610

592611
override UnboundGenericMethod getUnboundGeneric() { constructed_generic(this, result) }
593612

csharp/ql/lib/semmle/code/csharp/Member.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,12 @@ class Overridable extends Declaration, TOverridable {
215215
* to members that can be declared on an interface, i.e. methods, properties,
216216
* indexers and events.
217217
*/
218-
Interface getExplicitlyImplementedInterface() { explicitly_implements(this, getTypeRef(result)) }
218+
Interface getExplicitlyImplementedInterface() {
219+
explicitly_implements(this, result)
220+
or
221+
not explicitly_implements(this, any(Interface i)) and
222+
explicitly_implements(this, getTypeRef(result))
223+
}
219224

220225
/**
221226
* Holds if this member implements an interface member explicitly.

csharp/ql/lib/semmle/code/csharp/Property.qll

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,12 @@ class Property extends DotNet::Property, DeclarationWithGetSetAccessors, @proper
120120

121121
override ValueOrRefType getDeclaringType() { properties(this, _, result, _, _) }
122122

123-
override Type getType() { properties(this, _, _, getTypeRef(result), _) }
123+
override Type getType() {
124+
properties(this, _, _, result, _)
125+
or
126+
not properties(this, _, _, any(Type t), _) and
127+
properties(this, _, _, getTypeRef(result), _)
128+
}
124129

125130
/**
126131
* Holds if this property is automatically implemented. For example, `P1`
@@ -260,7 +265,12 @@ class Indexer extends DeclarationWithGetSetAccessors, Parameterizable, @indexer
260265

261266
override ValueOrRefType getDeclaringType() { indexers(this, _, result, _, _) }
262267

263-
override Type getType() { indexers(this, _, _, getTypeRef(result), _) }
268+
override Type getType() {
269+
indexers(this, _, _, result, _)
270+
or
271+
not indexers(this, _, _, any(Type t), _) and
272+
indexers(this, _, _, getTypeRef(result), _)
273+
}
264274

265275
override IndexerAccess getAnAccess() { result.getTarget() = this }
266276

csharp/ql/lib/semmle/code/csharp/Stmt.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,12 @@ class CatchClause extends Stmt, @catch {
984984
* }
985985
* ```
986986
*/
987-
ExceptionClass getCaughtExceptionType() { catch_type(this, getTypeRef(result), _) }
987+
ExceptionClass getCaughtExceptionType() {
988+
catch_type(this, result, _)
989+
or
990+
not catch_type(this, any(Type t), _) and
991+
catch_type(this, getTypeRef(result), _)
992+
}
988993

989994
/**
990995
* Gets the `catch` filter clause, if any. For example, the filter expression

csharp/ql/lib/semmle/code/csharp/Type.qll

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,16 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
110110
parent_namespace_declaration(this, result)
111111
}
112112

113+
private Class getExplicitBaseClass() {
114+
extend(this, result)
115+
or
116+
not extend(this, any(Class c)) and
117+
extend(this, getTypeRef(result))
118+
}
119+
113120
/** Gets the immediate base class of this class, if any. */
114121
final Class getBaseClass() {
115-
extend(this, getTypeRef(result))
122+
result = this.getExplicitBaseClass()
116123
or
117124
not extend(this, _) and
118125
not isObjectClass(this) and
@@ -122,7 +129,11 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
122129
}
123130

124131
/** Gets an immediate base interface of this type, if any. */
125-
Interface getABaseInterface() { implement(this, getTypeRef(result)) }
132+
Interface getABaseInterface() {
133+
implement(this, result)
134+
or
135+
implement(this, getTypeRef(result))
136+
}
126137

127138
/** Gets an immediate base type of this type, if any. */
128139
override ValueOrRefType getABaseType() {
@@ -672,7 +683,12 @@ class Enum extends ValueType, @enum_type {
672683
* }
673684
* ```
674685
*/
675-
IntegralType getUnderlyingType() { enum_underlying_type(this, getTypeRef(result)) }
686+
IntegralType getUnderlyingType() {
687+
enum_underlying_type(this, result)
688+
or
689+
not enum_underlying_type(this, any(Type t)) and
690+
enum_underlying_type(this, getTypeRef(result))
691+
}
676692

677693
/**
678694
* Gets an `enum` constant declared in this `enum`, for example `Even`
@@ -855,7 +871,12 @@ class Interface extends RefType, @interface_type {
855871
*/
856872
class DelegateType extends RefType, Parameterizable, @delegate_type {
857873
/** Gets the return type of this delegate. */
858-
Type getReturnType() { delegate_return_type(this, getTypeRef(result)) }
874+
Type getReturnType() {
875+
delegate_return_type(this, result)
876+
or
877+
not delegate_return_type(this, any(Type t)) and
878+
delegate_return_type(this, getTypeRef(result))
879+
}
859880

860881
/** Gets the annotated return type of this delegate. */
861882
AnnotatedType getAnnotatedReturnType() { result.appliesTo(this) }
@@ -939,7 +960,12 @@ class UnmanagedCallingConvention extends CallingConvention {
939960
*/
940961
class FunctionPointerType extends Type, Parameterizable, @function_pointer_type {
941962
/** Gets the return type of this function pointer. */
942-
Type getReturnType() { function_pointer_return_type(this, getTypeRef(result)) }
963+
Type getReturnType() {
964+
function_pointer_return_type(this, result)
965+
or
966+
not function_pointer_return_type(this, any(Type t)) and
967+
function_pointer_return_type(this, getTypeRef(result))
968+
}
943969

944970
/** Gets the calling convention. */
945971
CallingConvention getCallingConvention() {
@@ -950,6 +976,9 @@ class FunctionPointerType extends Type, Parameterizable, @function_pointer_type
950976

951977
/** Gets the unmanaged calling convention at index `i`. */
952978
Type getUnmanagedCallingConvention(int i) {
979+
has_unmanaged_calling_conventions(this, i, result)
980+
or
981+
not has_unmanaged_calling_conventions(this, i, any(Type t)) and
953982
has_unmanaged_calling_conventions(this, i, getTypeRef(result))
954983
}
955984

@@ -979,7 +1008,12 @@ class NullableType extends ValueType, ConstructedType, @nullable_type {
9791008
* Gets the underlying value type of this nullable type.
9801009
* For example `int` in `int?`.
9811010
*/
982-
Type getUnderlyingType() { nullable_underlying_type(this, getTypeRef(result)) }
1011+
Type getUnderlyingType() {
1012+
nullable_underlying_type(this, result)
1013+
or
1014+
not nullable_underlying_type(this, any(Type t)) and
1015+
nullable_underlying_type(this, getTypeRef(result))
1016+
}
9831017

9841018
override UnboundGenericStruct getUnboundGeneric() {
9851019
result.hasQualifiedName("System", "Nullable<>")
@@ -1021,7 +1055,12 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
10211055
predicate isMultiDimensional() { this.getRank() > 1 }
10221056

10231057
/** Gets the element type of this array, for example `int` in `int[]`. */
1024-
override Type getElementType() { array_element_type(this, _, _, getTypeRef(result)) }
1058+
override Type getElementType() {
1059+
array_element_type(this, _, _, result)
1060+
or
1061+
not array_element_type(this, _, _, any(Type t)) and
1062+
array_element_type(this, _, _, getTypeRef(result))
1063+
}
10251064

10261065
/** Holds if this array type has the same shape (dimension and rank) as `that` array type. */
10271066
predicate hasSameShapeAs(ArrayType that) {
@@ -1076,7 +1115,12 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
10761115
* A pointer type, for example `char*`.
10771116
*/
10781117
class PointerType extends DotNet::PointerType, Type, @pointer_type {
1079-
override Type getReferentType() { pointer_referent_type(this, getTypeRef(result)) }
1118+
override Type getReferentType() {
1119+
pointer_referent_type(this, result)
1120+
or
1121+
not pointer_referent_type(this, any(Type t)) and
1122+
pointer_referent_type(this, getTypeRef(result))
1123+
}
10801124

10811125
override string toStringWithTypes() { result = DotNet::PointerType.super.toStringWithTypes() }
10821126

@@ -1134,7 +1178,12 @@ class UnknownType extends Type, @unknown_type {
11341178
*/
11351179
class TupleType extends ValueType, @tuple_type {
11361180
/** Gets the underlying type of this tuple, which is of type `System.ValueTuple`. */
1137-
Struct getUnderlyingType() { tuple_underlying_type(this, getTypeRef(result)) }
1181+
Struct getUnderlyingType() {
1182+
tuple_underlying_type(this, result)
1183+
or
1184+
not tuple_underlying_type(this, any(Type t)) and
1185+
tuple_underlying_type(this, getTypeRef(result))
1186+
}
11381187

11391188
/**
11401189
* Gets the `n`th element of this tuple, indexed from 0.
@@ -1196,7 +1245,11 @@ class TypeMention extends @type_mention {
11961245
Type type;
11971246
@type_mention_parent parent;
11981247

1199-
TypeMention() { type_mention(this, getTypeRef(type), parent) }
1248+
TypeMention() {
1249+
type_mention(this, type, parent)
1250+
or
1251+
type_mention(this, getTypeRef(type), parent)
1252+
}
12001253

12011254
/** Gets the type being mentioned. */
12021255
Type getType() { result = type }

csharp/ql/lib/semmle/code/csharp/TypeRef.qll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ import csharp
88

99
/** A typeref is a reference to a type in some assembly. */
1010
private class TypeRef extends @typeref {
11+
/** Gets the name of type being referenced. */
1112
string getName() { typerefs(this, result) }
1213

14+
/** Gets a textual representation of this type reference. */
1315
string toString() { result = this.getName() }
1416

17+
/** Gets the type being referenced. */
1518
Type getReferencedType() {
1619
typeref_type(this, result)
1720
or
@@ -27,8 +30,4 @@ private class TypeRef extends @typeref {
2730
* This is used for extensionals that can be supplied
2831
* as either type references or types.
2932
*/
30-
@type_or_ref getTypeRef(Type type) {
31-
result = type
32-
or
33-
result.(TypeRef).getReferencedType() = type
34-
}
33+
TypeRef getTypeRef(Type type) { result.getReferencedType() = type }

0 commit comments

Comments
 (0)