diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index 1f262c84877..8876f797803 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -331,7 +331,7 @@ class Class extends TClass, AstNode, ModuleMember { } /** Gets the type of one of the members that this class is defined to be a union of. */ - Type getUnionMember() { + TypeExpr getUnionMember() { toGenerated(result) = cls.getChild(_).(Generated::TypeUnionBody).getChild(_) } } diff --git a/ql/src/codeql_ql/ast/internal/Type.qll b/ql/src/codeql_ql/ast/internal/Type.qll index 0e936e80af7..a47f0c6fdd7 100644 --- a/ql/src/codeql_ql/ast/internal/Type.qll +++ b/ql/src/codeql_ql/ast/internal/Type.qll @@ -4,18 +4,23 @@ private import codeql_ql.ast.internal.TreeSitter private import codeql_ql.ast.internal.Module private newtype TType = - TClass(Class c) or + TClass(Class c) { isActualClass(c) } or TNewType(NewType n) or TNewTypeBranch(NewTypeBranch b) or TPrimitive(string s) { primTypeName(s) } or - // TUnion(...) or + TUnion(Class c) { exists(c.getUnionMember()) } or TDontCare() or - TClassChar(Class c) or - TClassDomain(Class c) or + TClassChar(Class c) { isActualClass(c) } or + TClassDomain(Class c) { isActualClass(c) } or TDatabase(string s) { exists(TypeExpr t | t.isDBType() and s = t.getClassName()) } private predicate primTypeName(string s) { s = ["int", "float", "string", "boolean", "date"] } +private predicate isActualClass(Class c) { + not exists(c.getAliasType()) and + not exists(c.getUnionMember()) +} + /** * A type, such as `int` or `Node`. */ @@ -133,6 +138,8 @@ class NewTypeType extends Type, TNewType { override NewType getDeclaration() { result = decl } + NewTypeBranchType getABranch() { result = TNewTypeBranch(decl.getABranch()) } + override string getName() { result = decl.getName() } } @@ -145,7 +152,11 @@ class NewTypeBranchType extends Type, TNewTypeBranch { override string getName() { result = decl.getName() } - override Type getASuperType() { result = TNewType(decl.getParent()) } + override Type getASuperType() { + result = TNewType(decl.getParent()) + or + result.(UnionType).getUnionMember() = this + } override Type getAnInternalSuperType() { result = getASuperType() @@ -154,6 +165,18 @@ class NewTypeBranchType extends Type, TNewTypeBranch { } } +class UnionType extends Type, TUnion { + Class decl; + + UnionType() { this = TUnion(decl) } + + override Class getDeclaration() { result = decl } + + override string getName() { result = decl.getName() } + + Type getUnionMember() { result = decl.getUnionMember().getResolvedType() } +} + class DatabaseType extends Type, TDatabase { string name; @@ -207,6 +230,18 @@ private predicate defines(FileOrModule m, string name, Type t, boolean public) { public = getPublicBool(ty.getParent()) ) or + exists(Class ty | t = TUnion(ty) | + getEnclosingModule(ty) = m and + ty.getName() = name and + public = getPublicBool(ty) + ) + or + exists(Class ty | t = ty.getAliasType().getResolvedType() | + getEnclosingModule(ty) = m and + ty.getName() = name and + public = getPublicBool(ty) + ) + or exists(Import im | getEnclosingModule(im) = m and not exists(im.importedAs()) and