From 9a427931b7ee72064febdb0a693e20d0b72d0697 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 16 Mar 2021 22:01:51 +0000 Subject: [PATCH] Explicitly walk pointer types In a previous draft these could use getBaseType* --- ql/src/semmle/go/Types.qll | 11 ++++++++--- ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll | 7 +++++-- ql/src/semmle/go/controlflow/IR.qll | 7 +++++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/ql/src/semmle/go/Types.qll b/ql/src/semmle/go/Types.qll index cd51783237a..9e1d68e3dd1 100644 --- a/ql/src/semmle/go/Types.qll +++ b/ql/src/semmle/go/Types.qll @@ -379,7 +379,10 @@ class StructType extends @structtype, CompositeType { * hasEmbeddedField holds if there is an embedded field at int `depth`, with either type `tp` or `tp`'s pointer type. */ private predicate hasEmbeddedField(Type tp, int depth) { - exists(Field f | this.hasFieldCand(_, f, depth, true) | tp = f.getType().getBaseType*()) + exists(Field f | this.hasFieldCand(_, f, depth, true) | + tp = f.getType() or + tp = f.getType().(PointerType).getBaseType() + ) } /** @@ -389,8 +392,10 @@ class StructType extends @structtype, CompositeType { // embeddedParent is a field of 'this' at depth 'depth - 1' this.hasFieldCand(_, embeddedParent, depth - 1, true) and // embeddedParent's type has the result field - exists(StructType embeddedType | - embeddedType = embeddedParent.getType().getBaseType*().getUnderlyingType() + exists(StructType embeddedType, Type fieldType | + fieldType = embeddedParent.getType().getUnderlyingType() and + pragma[only_bind_into](embeddedType) = + [fieldType, fieldType.(PointerType).getBaseType().getUnderlyingType()] | result = embeddedType.getOwnField(name, isEmbedded) ) diff --git a/ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll b/ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll index 70685046777..a8e6cf77e96 100644 --- a/ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll +++ b/ql/src/semmle/go/controlflow/ControlFlowGraphImpl.qll @@ -48,8 +48,11 @@ private predicate isCond(Expr e) { e = any(ParenExpr par | isCond(par)).getExpr() } -private Type getSelectedStructType(PromotedFieldSelector e) { - pragma[only_bind_into](result) = e.getBase().getType().getBaseType*().getUnderlyingType() +private StructType getSelectedStructType(PromotedFieldSelector e) { + exists(Type baseType | baseType = e.getBase().getType().getUnderlyingType() | + pragma[only_bind_into](result) = + [baseType, baseType.(PointerType).getBaseType().getUnderlyingType()] + ) } private predicate implicitFieldSelection(PromotedFieldSelector e, int i, Field implicitField) { diff --git a/ql/src/semmle/go/controlflow/IR.qll b/ql/src/semmle/go/controlflow/IR.qll index 40de67819cc..736c9aee6de 100644 --- a/ql/src/semmle/go/controlflow/IR.qll +++ b/ql/src/semmle/go/controlflow/IR.qll @@ -279,8 +279,11 @@ module IR { PromotedFieldSelector() { this.refersTo(any(PromotedField f)) } } - private Type getSelectedStructType(PromotedFieldSelector e) { - pragma[only_bind_into](result) = e.getBase().getType().getBaseType*().getUnderlyingType() + private StructType getSelectedStructType(PromotedFieldSelector e) { + exists(Type baseType | baseType = e.getBase().getType().getUnderlyingType() | + pragma[only_bind_into](result) = + [baseType, baseType.(PointerType).getBaseType().getUnderlyingType()] + ) } private Instruction promotedFieldSelectorBase(PromotedFieldSelector se, Field field) {