mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
C++: Fix PR feedback
This commit is contained in:
@@ -886,8 +886,19 @@ class TemplateClass extends Class {
|
||||
* A class that is an instantiation of a template.
|
||||
*/
|
||||
class ClassTemplateInstantiation extends Class {
|
||||
TemplateClass tc;
|
||||
|
||||
ClassTemplateInstantiation() {
|
||||
exists(TemplateClass tc | tc.getAnInstantiation() = this)
|
||||
tc.getAnInstantiation() = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class template from which this instantiation was instantiated.
|
||||
*
|
||||
* Example: For `std::vector<float>()`, returns `std::vector<T>`.
|
||||
*/
|
||||
TemplateClass getTemplate() {
|
||||
result = tc
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import semmle.code.cpp.Element
|
||||
import semmle.code.cpp.Specifier
|
||||
import semmle.code.cpp.Namespace
|
||||
private import semmle.code.cpp.internal.IdentityString
|
||||
|
||||
/**
|
||||
* A C/C++ declaration: for example, a variable declaration, a type
|
||||
@@ -89,17 +88,6 @@ abstract class Declaration extends Locatable, @declaration {
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
/**
|
||||
* Gets a string that uniquely identifies this declaration, suitable for use when debugging queries. Only holds for
|
||||
* functions, user-defined types, global and namespace-scope variables, and member variables.
|
||||
*
|
||||
* This operation is very expensive, and should not be used in production queries. Consider using `hasName()` or
|
||||
* `hasQualifiedName()` for identifying known declarations in production queries.
|
||||
*/
|
||||
string getIdentityString() {
|
||||
none()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this declaration.
|
||||
*
|
||||
|
||||
@@ -5,7 +5,6 @@ import semmle.code.cpp.Parameter
|
||||
import semmle.code.cpp.exprs.Call
|
||||
import semmle.code.cpp.metrics.MetricFunction
|
||||
import semmle.code.cpp.Linkage
|
||||
private import semmle.code.cpp.internal.IdentityString
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
@@ -21,6 +20,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
override string getName() { functions(underlyingElement(this),result,_) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getIdentityString(Declaration)` from `semmle.code.cpp.Print` instead.
|
||||
* Gets the full signature of this function, including return type, parameter
|
||||
* types, and template arguments.
|
||||
*
|
||||
@@ -33,7 +33,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* "min<int>(int, int) -> int", and the full signature of the uninstantiated
|
||||
* template on the first line would be "min<T>(T, T) -> T".
|
||||
*/
|
||||
string getFullSignature() {
|
||||
deprecated string getFullSignature() {
|
||||
exists(string name, string templateArgs, string args |
|
||||
result = name + templateArgs + args + " -> " + getType().toString() and
|
||||
name = getQualifiedName() and
|
||||
@@ -56,48 +56,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
)
|
||||
}
|
||||
|
||||
override string getIdentityString() {
|
||||
result = getType().getTypeSpecifier() + getType().getDeclaratorPrefix() + " " + getScopePrefix(this) + getName() + getTemplateArgumentsString() + getDeclaratorSuffixBeforeQualifiers() + getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
private string getTemplateArgumentsString() {
|
||||
if exists(getATemplateArgument()) then (
|
||||
result = "<" +
|
||||
concat(int i |
|
||||
exists(getTemplateArgument(i)) |
|
||||
getTemplateArgument(i).getTypeIdentityString(), ", " order by i
|
||||
) + ">"
|
||||
)
|
||||
else
|
||||
result = ""
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
private string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = "(" +
|
||||
concat(int i |
|
||||
exists(getParameter(i).getType()) |
|
||||
getParameterTypeString(getParameter(i).getType()), ", " order by i
|
||||
) + ")" + getQualifierString()
|
||||
}
|
||||
|
||||
private string getQualifierString() {
|
||||
if exists(getACVQualifier()) then
|
||||
result = " " + concat(string qualifier | qualifier = getACVQualifier() | qualifier, " ")
|
||||
else
|
||||
result = ""
|
||||
}
|
||||
|
||||
private string getACVQualifier() {
|
||||
result = getASpecifier().getName() and
|
||||
(result = "const" or result = "volatile")
|
||||
}
|
||||
|
||||
private string getDeclaratorSuffix() {
|
||||
result = getType().getDeclaratorSuffixBeforeQualifiers() + getType().getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
/** Gets a specifier of this function. */
|
||||
override Specifier getASpecifier() {
|
||||
funspecifiers(underlyingElement(this),unresolveElement(result))
|
||||
@@ -1137,6 +1095,11 @@ class FunctionTemplateInstantiation extends Function {
|
||||
tf.getAnInstantiation() = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function template from which this instantiation was instantiated.
|
||||
*
|
||||
* Example: For `min<int>()`, returns `min<T>`.
|
||||
*/
|
||||
TemplateFunction getTemplate() {
|
||||
result = tf
|
||||
}
|
||||
|
||||
449
cpp/ql/src/semmle/code/cpp/Print.qll
Normal file
449
cpp/ql/src/semmle/code/cpp/Print.qll
Normal file
@@ -0,0 +1,449 @@
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* Gets a string containing the scope in which this declaration is declared.
|
||||
*/
|
||||
private string getScopePrefix(Declaration decl) {
|
||||
decl.isMember() and result = decl.getDeclaringType().(UserDumpType).getIdentityString() + "::" or
|
||||
(
|
||||
decl.isTopLevel() and
|
||||
exists (string parentName |
|
||||
parentName = decl.getNamespace().getQualifiedName() and
|
||||
(
|
||||
parentName != "" and result = parentName + "::" or
|
||||
parentName = "" and result = ""
|
||||
)
|
||||
)
|
||||
) or
|
||||
exists(UserType type |
|
||||
type = decl and type.isLocal() and result = "(" + type.getEnclosingFunction().(DumpFunction).getIdentityString() + ")::"
|
||||
) or
|
||||
decl instanceof TemplateParameter and result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the identity string of a type used as a parameter. Identical to `Type.getTypeIdentityString()`, except that
|
||||
* it returns `...` for `UnknownType`, which is used to represent variable arguments.
|
||||
*/
|
||||
private string getParameterTypeString(Type parameterType) {
|
||||
if parameterType instanceof UnknownType then
|
||||
result = "..."
|
||||
else
|
||||
result = parameterType.(DumpType).getTypeIdentityString()
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Declaration` extended to add methods for generating strings useful only for dumps and debugging.
|
||||
*/
|
||||
private abstract class DumpDeclaration extends Declaration {
|
||||
/**
|
||||
* Gets a string that uniquely identifies this declaration, suitable for use when debugging queries. Only holds for
|
||||
* functions, user-defined types, global and namespace-scope variables, and member variables.
|
||||
*
|
||||
* This operation is very expensive, and should not be used in production queries. Consider using `hasName()` or
|
||||
* `hasQualifiedName()` for identifying known declarations in production queries.
|
||||
*/
|
||||
string getIdentityString() {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Type` extended to add methods for generating strings useful only for dumps and debugging.
|
||||
*/
|
||||
private class DumpType extends Type
|
||||
{
|
||||
/**
|
||||
* Gets a string that uniquely identifies this type, suitable for use when debugging queries. All typedefs and
|
||||
* decltypes are expanded, and all symbol names are fully qualified.
|
||||
*
|
||||
* This operation is very expensive, and should not be used in production queries.
|
||||
*/
|
||||
final string getTypeIdentityString() {
|
||||
/*
|
||||
The identity string of a type is just the concatenation of the four components below. To create the type
|
||||
identity for a derived type, insert the declarator of the derived type between the `getDeclaratorPrefix()` and
|
||||
`getDeclaratorSuffixBeforeQualifiers()`. To create the type identity for a `SpecifiedType`, insert the qualifiers
|
||||
after `getDeclaratorSuffixBeforeQualifiers()`.
|
||||
*/
|
||||
result = getTypeSpecifier() + getDeclaratorPrefix() + getDeclaratorSuffixBeforeQualifiers() + getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the "type specifier" part of this type's name. This is generally the "leaf" type from which the type was
|
||||
* constructed.
|
||||
*
|
||||
* Examples:
|
||||
* - `int` -> `int`
|
||||
* - `int*` -> `int`
|
||||
* - `int (*&)(float, double) const` -> `int`
|
||||
*
|
||||
* This predicate is intended to be used only by the implementation of `getTypeIdentityString`.
|
||||
*/
|
||||
string getTypeSpecifier() {
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the portion of this type's declarator that comes before the declarator for any derived type.
|
||||
*
|
||||
* This predicate is intended to be used only by the implementation of `getTypeIdentityString`.
|
||||
*/
|
||||
string getDeclaratorPrefix() {
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the portion of this type's declarator that comes after the declarator for any derived type, but before any
|
||||
* qualifiers on the current type.
|
||||
*
|
||||
* This predicate is intended to be used only by the implementation of `getTypeIdentityString`.
|
||||
*/
|
||||
string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the portion of this type's declarator that comes after the declarator for any derived type and after any
|
||||
* qualifiers on the current type.
|
||||
*
|
||||
* This predicate is intended to be used only by the implementation of `getTypeIdentityString`.
|
||||
*/
|
||||
string getDeclaratorSuffix() {
|
||||
result = ""
|
||||
}
|
||||
}
|
||||
|
||||
private class BuiltInDumpType extends DumpType, BuiltInType {
|
||||
override string getTypeSpecifier() {
|
||||
result = toString()
|
||||
}
|
||||
}
|
||||
|
||||
private class IntegralDumpType extends BuiltInDumpType, IntegralType {
|
||||
override string getTypeSpecifier() {
|
||||
result = getCanonical().toString()
|
||||
}
|
||||
}
|
||||
|
||||
private class DerivedDumpType extends DumpType, DerivedType {
|
||||
override string getTypeSpecifier() {
|
||||
result = getBaseType().(DumpType).getTypeSpecifier()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class DecltypeDumpType extends DumpType, Decltype {
|
||||
override string getTypeSpecifier() {
|
||||
result = getBaseType().(DumpType).getTypeSpecifier()
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getBaseType().(DumpType).getDeclaratorPrefix()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class PointerIshDumpType extends DerivedDumpType {
|
||||
PointerIshDumpType() {
|
||||
this instanceof PointerType or
|
||||
this instanceof ReferenceType
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
exists(string declarator |
|
||||
result = getBaseType().(DumpType).getDeclaratorPrefix() + declarator and
|
||||
if getBaseType().getUnspecifiedType() instanceof ArrayType then
|
||||
declarator = "(" + getDeclaratorToken() + ")"
|
||||
else
|
||||
declarator = getDeclaratorToken()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token used when declaring this kind of type (e.g. `*`, `&`, `&&`)/
|
||||
*/
|
||||
string getDeclaratorToken() {
|
||||
result = ""
|
||||
}
|
||||
}
|
||||
|
||||
private class PointerDumpType extends PointerIshDumpType, PointerType {
|
||||
override string getDeclaratorToken() {
|
||||
result = "*"
|
||||
}
|
||||
}
|
||||
|
||||
private class LValueReferenceDumpType extends PointerIshDumpType, LValueReferenceType {
|
||||
override string getDeclaratorToken() {
|
||||
result = "&"
|
||||
}
|
||||
}
|
||||
|
||||
private class RValueReferenceDumpType extends PointerIshDumpType, RValueReferenceType {
|
||||
override string getDeclaratorToken() {
|
||||
result = "&&"
|
||||
}
|
||||
}
|
||||
|
||||
private class PointerToMemberDumpType extends DumpType, PointerToMemberType {
|
||||
override string getTypeSpecifier() {
|
||||
result = getBaseType().(DumpType).getTypeSpecifier()
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
exists(string declarator, string parenDeclarator, Type baseType |
|
||||
declarator = getClass().(DumpType).getTypeIdentityString() + "::*" and
|
||||
result = getBaseType().(DumpType).getDeclaratorPrefix() + " " + parenDeclarator and
|
||||
baseType = getBaseType().getUnspecifiedType() and
|
||||
if (baseType instanceof ArrayType) or (baseType instanceof RoutineType) then
|
||||
parenDeclarator = "(" + declarator
|
||||
else
|
||||
parenDeclarator = declarator
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
exists(Type baseType |
|
||||
baseType = getBaseType().getUnspecifiedType() and
|
||||
if (baseType instanceof ArrayType) or (baseType instanceof RoutineType) then
|
||||
result = ")" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
else
|
||||
result = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class ArrayDumpType extends DerivedDumpType, ArrayType {
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getBaseType().(DumpType).getDeclaratorPrefix()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
if exists(getArraySize()) then
|
||||
result = "[" + getArraySize().toString() + "]" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
else
|
||||
result = "[]" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
}
|
||||
}
|
||||
|
||||
private class FunctionPointerIshDumpType extends DerivedDumpType, FunctionPointerIshType {
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = ")" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getBaseType().(DumpType).getDeclaratorPrefix() + "(" + getDeclaratorToken()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token used when declaring this kind of type (e.g. `*`, `&`, `^`)/
|
||||
*/
|
||||
string getDeclaratorToken() {
|
||||
result = ""
|
||||
}
|
||||
}
|
||||
|
||||
private class FunctionPointerDumpType extends FunctionPointerIshDumpType, FunctionPointerType {
|
||||
override string getDeclaratorToken() {
|
||||
result = "*"
|
||||
}
|
||||
}
|
||||
|
||||
private class FunctionReferenceDumpType extends FunctionPointerIshDumpType, FunctionReferenceType {
|
||||
override string getDeclaratorToken() {
|
||||
result = "&"
|
||||
}
|
||||
}
|
||||
|
||||
private class BlockDumpType extends FunctionPointerIshDumpType, BlockType {
|
||||
override string getDeclaratorToken() {
|
||||
result = "^"
|
||||
}
|
||||
}
|
||||
|
||||
private class RoutineDumpType extends DumpType, RoutineType {
|
||||
override string getTypeSpecifier() {
|
||||
result = getReturnType().(DumpType).getTypeSpecifier()
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getReturnType().(DumpType).getDeclaratorPrefix()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = "(" +
|
||||
concat(int i |
|
||||
exists(getParameterType(i)) |
|
||||
getParameterTypeString(getParameterType(i)), ", " order by i
|
||||
) + ")"
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getReturnType().(DumpType).getDeclaratorSuffixBeforeQualifiers() + getReturnType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class SpecifiedDumpType extends DerivedDumpType, SpecifiedType {
|
||||
override string getDeclaratorPrefix() {
|
||||
exists(string basePrefix |
|
||||
basePrefix = getBaseType().(DumpType).getDeclaratorPrefix() and
|
||||
if getBaseType().getUnspecifiedType() instanceof RoutineType then
|
||||
result = basePrefix
|
||||
else
|
||||
result = basePrefix + " " + getSpecifierString().trim()
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
exists(string baseSuffix |
|
||||
baseSuffix = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() and
|
||||
if getBaseType().getUnspecifiedType() instanceof RoutineType then
|
||||
result = baseSuffix + " " + getSpecifierString().trim()
|
||||
else
|
||||
result = baseSuffix
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
private class UserDumpType extends DumpType, DumpDeclaration, UserType {
|
||||
override string getIdentityString() {
|
||||
exists(string simpleName |
|
||||
(
|
||||
if this instanceof Closure then
|
||||
simpleName = "(" + getSimpleName() + ")"
|
||||
else
|
||||
simpleName = getSimpleName()
|
||||
) and
|
||||
result = getScopePrefix(this) + simpleName + getTemplateArgumentsString()
|
||||
)
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
private string getTemplateArgumentsString() {
|
||||
if exists(this.(Class).getATemplateArgument()) then (
|
||||
result = "<" +
|
||||
strictconcat(int i |
|
||||
exists(this.(Class).getTemplateArgument(i)) |
|
||||
this.(Class).getTemplateArgument(i).(DumpType).getTypeIdentityString(), ", " order by i
|
||||
) + ">"
|
||||
)
|
||||
else
|
||||
result = ""
|
||||
}
|
||||
|
||||
override string getTypeSpecifier() {
|
||||
result = getIdentityString()
|
||||
}
|
||||
}
|
||||
|
||||
private class DumpVariable extends DumpDeclaration, Variable {
|
||||
override string getIdentityString() {
|
||||
exists(DumpType type |
|
||||
(this instanceof MemberVariable or this instanceof GlobalOrNamespaceVariable) and
|
||||
type = this.getType() and
|
||||
result = type.getTypeSpecifier() + type.getDeclaratorPrefix() + " " + getScopePrefix(this) + this.getName() + this.getTemplateArgumentsString() + type.getDeclaratorSuffixBeforeQualifiers() + type.getDeclaratorSuffix()
|
||||
)
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
private string getTemplateArgumentsString() {
|
||||
if exists(getATemplateArgument()) then (
|
||||
result = "<" +
|
||||
strictconcat(int i |
|
||||
exists(getTemplateArgument(i)) |
|
||||
getTemplateArgument(i).(DumpType).getTypeIdentityString(), ", " order by i
|
||||
) + ">"
|
||||
)
|
||||
else
|
||||
result = ""
|
||||
}
|
||||
}
|
||||
|
||||
private class DumpFunction extends DumpDeclaration, Function {
|
||||
override string getIdentityString() {
|
||||
result = getType().(DumpType).getTypeSpecifier() + getType().(DumpType).getDeclaratorPrefix() + " " + getScopePrefix(this) + getName() + getTemplateArgumentsString() + getDeclaratorSuffixBeforeQualifiers() + getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
private string getTemplateArgumentsString() {
|
||||
if exists(getATemplateArgument()) then (
|
||||
result = "<" +
|
||||
strictconcat(int i |
|
||||
exists(getTemplateArgument(i)) |
|
||||
getTemplateArgument(i).(DumpType).getTypeIdentityString(), ", " order by i
|
||||
) + ">"
|
||||
)
|
||||
else
|
||||
result = ""
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
private string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = "(" +
|
||||
concat(int i |
|
||||
exists(getParameter(i).getType()) |
|
||||
getParameterTypeString(getParameter(i).getType()), ", " order by i
|
||||
) + ")" + getQualifierString()
|
||||
}
|
||||
|
||||
private string getQualifierString() {
|
||||
if exists(getACVQualifier()) then
|
||||
result = " " + strictconcat(string qualifier | qualifier = getACVQualifier() | qualifier, " ")
|
||||
else
|
||||
result = ""
|
||||
}
|
||||
|
||||
private string getACVQualifier() {
|
||||
result = getASpecifier().getName() and
|
||||
(result = "const" or result = "volatile")
|
||||
}
|
||||
|
||||
private string getDeclaratorSuffix() {
|
||||
result = getType().(DumpType).getDeclaratorSuffixBeforeQualifiers() + getType().(DumpType).getDeclaratorSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string that uniquely identifies this declaration, suitable for use when debugging queries. Only holds for
|
||||
* functions, user-defined types, global and namespace-scope variables, and member variables.
|
||||
*
|
||||
* This operation is very expensive, and should not be used in production queries. Consider using `hasName()` or
|
||||
* `hasQualifiedName()` for identifying known declarations in production queries.
|
||||
*/
|
||||
string getIdentityString(Declaration decl) {
|
||||
result = decl.(DumpDeclaration).getIdentityString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string that uniquely identifies this type, suitable for use when debugging queries. All typedefs and
|
||||
* decltypes are expanded, and all symbol names are fully qualified.
|
||||
*
|
||||
* This operation is very expensive, and should not be used in production queries.
|
||||
*/
|
||||
string getTypeIdentityString(Type type) {
|
||||
result = type.(DumpType).getTypeIdentityString()
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import cpp
|
||||
private import semmle.code.cpp.Print
|
||||
|
||||
private newtype TPrintASTConfiguration = MkPrintASTConfiguration()
|
||||
|
||||
@@ -490,7 +491,7 @@ class FunctionNode extends ASTNode {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = func.getIdentityString()
|
||||
result = getIdentityString(func)
|
||||
}
|
||||
|
||||
override PrintASTNode getChild(int childIndex) {
|
||||
@@ -528,7 +529,7 @@ class FunctionNode extends ASTNode {
|
||||
file,
|
||||
line,
|
||||
column,
|
||||
function.getIdentityString()
|
||||
getIdentityString(function)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import semmle.code.cpp.Element
|
||||
import semmle.code.cpp.Member
|
||||
import semmle.code.cpp.Function
|
||||
private import semmle.code.cpp.internal.IdentityString
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
@@ -145,66 +144,6 @@ class Type extends Locatable, @type {
|
||||
*/
|
||||
string explain() { result = "type" } // Concrete base impl to allow filters on Type
|
||||
|
||||
/**
|
||||
* Gets a string that uniquely identifies this type, suitable for use when debugging queries. All typedefs and
|
||||
* decltypes are expanded, and all symbol names are fully qualified.
|
||||
*
|
||||
* This operation is very expensive, and should not be used in production queries.
|
||||
*/
|
||||
final string getTypeIdentityString() {
|
||||
/*
|
||||
The identity string of a type is just the concatenation of the four components below. To create the type
|
||||
identity for a derived type, insert the declarator of the derived type between the `getDeclaratorPrefix()` and
|
||||
`getDeclaratorSuffixBeforeQualifiers()`. To create the type identity for a `SpecifiedType`, insert the qualifiers
|
||||
after `getDeclaratorSuffixBeforeQualifiers()`.
|
||||
*/
|
||||
result = getTypeSpecifier() + getDeclaratorPrefix() + getDeclaratorSuffixBeforeQualifiers() + getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the "type specifier" part of this type's name. This is generally the "leaf" type from which the type was
|
||||
* constructed.
|
||||
*
|
||||
* Examples:
|
||||
* - `int` -> `int`
|
||||
* - `int*` -> `int`
|
||||
* - `int (*&)(float, double) const` -> `int`
|
||||
*
|
||||
* This predicate is intended to be used only by the implementation of `getTypeIdentityString`.
|
||||
*/
|
||||
string getTypeSpecifier() {
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the portion of this type's declarator that comes before the declarator for any derived type.
|
||||
*
|
||||
* This predicate is intended to be used only by the implementation of `getTypeIdentityString`.
|
||||
*/
|
||||
string getDeclaratorPrefix() {
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the portion of this type's declarator that comes after the declarator for any derived type, but before any
|
||||
* qualifiers on the current type.
|
||||
*
|
||||
* This predicate is intended to be used only by the implementation of `getTypeIdentityString`.
|
||||
*/
|
||||
string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the portion of this type's declarator that comes after the declarator for any derived type and after any
|
||||
* qualifiers on the current type.
|
||||
*
|
||||
* This predicate is intended to be used only by the implementation of `getTypeIdentityString`.
|
||||
*/
|
||||
string getDeclaratorSuffix() {
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this type is constant and only contains constant types.
|
||||
* For instance, a `char *const` is a constant type, but not deeply constant,
|
||||
@@ -373,10 +312,6 @@ class BuiltInType extends Type, @builtintype {
|
||||
|
||||
override string explain() { result = this.getName() }
|
||||
|
||||
override string getTypeSpecifier() {
|
||||
result = toString()
|
||||
}
|
||||
|
||||
override predicate isDeeplyConstBelow() { any() } // No subparts
|
||||
}
|
||||
|
||||
@@ -541,10 +476,6 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
|
||||
builtintypes(unresolveElement(result), _, canonicalKind, _, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
override string getTypeSpecifier() {
|
||||
result = getCanonical().toString()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -781,18 +712,6 @@ class DerivedType extends Type, @derivedtype {
|
||||
|
||||
override string getName() { derivedtypes(underlyingElement(this),result,_,_) }
|
||||
|
||||
override string getTypeSpecifier() {
|
||||
result = getBaseType().getTypeSpecifier()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = getBaseType().getDeclaratorSuffixBeforeQualifiers()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base type of this derived type.
|
||||
*
|
||||
@@ -893,18 +812,6 @@ class Decltype extends Type, @decltype {
|
||||
result = "decltype(...)"
|
||||
}
|
||||
|
||||
override string getTypeSpecifier() {
|
||||
result = getBaseType().getTypeSpecifier()
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getBaseType().getDeclaratorPrefix()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
override string getName() {
|
||||
none()
|
||||
}
|
||||
@@ -955,23 +862,6 @@ class PointerIshType extends DerivedType {
|
||||
derivedtypes(underlyingElement(this), _, 2, _) or
|
||||
derivedtypes(underlyingElement(this), _, 8, _)
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
exists(string declarator |
|
||||
result = getBaseType().getDeclaratorPrefix() + declarator and
|
||||
if getBaseType().getUnspecifiedType() instanceof ArrayType then
|
||||
declarator = "(" + getDeclaratorToken() + ")"
|
||||
else
|
||||
declarator = getDeclaratorToken()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token used when declaring this kind of type (e.g. `*`, `&`, `&&`)/
|
||||
*/
|
||||
string getDeclaratorToken() {
|
||||
result = ""
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -987,10 +877,6 @@ class PointerType extends PointerIshType {
|
||||
|
||||
override string explain() { result = "pointer to {" + this.getBaseType().explain() + "}" }
|
||||
|
||||
override string getDeclaratorToken() {
|
||||
result = "*"
|
||||
}
|
||||
|
||||
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
|
||||
|
||||
override Type resolveTypedefs() {
|
||||
@@ -1032,10 +918,6 @@ class ReferenceType extends PointerIshType {
|
||||
*/
|
||||
class LValueReferenceType extends ReferenceType {
|
||||
LValueReferenceType() { derivedtypes(underlyingElement(this),_,2,_) }
|
||||
|
||||
override string getDeclaratorToken() {
|
||||
result = "&"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1045,10 +927,6 @@ class RValueReferenceType extends ReferenceType {
|
||||
RValueReferenceType() { derivedtypes(underlyingElement(this),_,8,_) }
|
||||
|
||||
override string explain() { result = "rvalue " + super.explain() }
|
||||
|
||||
override string getDeclaratorToken() {
|
||||
result = "&&"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1075,30 +953,6 @@ class SpecifiedType extends DerivedType {
|
||||
|
||||
override string explain() { result = this.getSpecifierString() + "{" + this.getBaseType().explain() + "}" }
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
exists(string basePrefix |
|
||||
basePrefix = getBaseType().getDeclaratorPrefix() and
|
||||
if getBaseType().getUnspecifiedType() instanceof RoutineType then
|
||||
result = basePrefix
|
||||
else
|
||||
result = basePrefix + " " + getSpecifierString().trim()
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
exists(string baseSuffix |
|
||||
baseSuffix = getBaseType().getDeclaratorSuffixBeforeQualifiers() and
|
||||
if getBaseType().getUnspecifiedType() instanceof RoutineType then
|
||||
result = baseSuffix + " " + getSpecifierString().trim()
|
||||
else
|
||||
result = baseSuffix
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
override predicate isDeeplyConst() { this.getASpecifier().getName() = "const" and this.getBaseType().isDeeplyConstBelow() }
|
||||
|
||||
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConstBelow() }
|
||||
@@ -1156,17 +1010,6 @@ class ArrayType extends DerivedType {
|
||||
result = "array of {" + this.getBaseType().explain() + "}"
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getBaseType().getDeclaratorPrefix()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
if exists(getArraySize()) then
|
||||
result = "[" + getArraySize().toString() + "]" + getBaseType().getDeclaratorSuffixBeforeQualifiers()
|
||||
else
|
||||
result = "[]" + getBaseType().getDeclaratorSuffixBeforeQualifiers()
|
||||
}
|
||||
|
||||
override predicate isDeeplyConst() { this.getBaseType().isDeeplyConst() } // No such thing as a const array type
|
||||
|
||||
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
|
||||
@@ -1228,10 +1071,6 @@ class FunctionPointerType extends FunctionPointerIshType {
|
||||
}
|
||||
|
||||
override string explain() { result = "pointer to {" + this.getBaseType().(RoutineType).explain() + "}" }
|
||||
|
||||
override string getDeclaratorToken() {
|
||||
result = "*"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1247,10 +1086,6 @@ class FunctionReferenceType extends FunctionPointerIshType {
|
||||
}
|
||||
|
||||
override string explain() { result = "reference to {" + this.getBaseType().(RoutineType).explain() + "}" }
|
||||
|
||||
override string getDeclaratorToken() {
|
||||
result = "&"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1269,10 +1104,6 @@ class BlockType extends FunctionPointerIshType {
|
||||
}
|
||||
|
||||
override string explain() { result = "block of {" + this.getBaseType().(RoutineType).explain() + "}" }
|
||||
|
||||
override string getDeclaratorToken() {
|
||||
result = "^"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1285,25 +1116,6 @@ class FunctionPointerIshType extends DerivedType {
|
||||
derivedtypes(underlyingElement(this),_,10,_)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = ")" + getBaseType().getDeclaratorSuffixBeforeQualifiers()
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getBaseType().getDeclaratorPrefix() + "(" + getDeclaratorToken()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token used when declaring this kind of type (e.g. `*`, `&`, `^`)/
|
||||
*/
|
||||
string getDeclaratorToken() {
|
||||
result = ""
|
||||
}
|
||||
|
||||
/** the return type of this function pointer type */
|
||||
Type getReturnType() {
|
||||
exists(RoutineType t | derivedtypes(underlyingElement(this),_,_,unresolveElement(t)) and result = t.getReturnType())
|
||||
@@ -1359,36 +1171,6 @@ class PointerToMemberType extends Type, @ptrtomember {
|
||||
|
||||
override string explain() { result = "pointer to member of " + this.getClass().toString() + " with type {" + this.getBaseType().explain() + "}" }
|
||||
|
||||
override string getTypeSpecifier() {
|
||||
result = getBaseType().getTypeSpecifier()
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
exists(string declarator, string parenDeclarator, Type baseType |
|
||||
declarator = getClass().getTypeIdentityString() + "::*" and
|
||||
result = getBaseType().getDeclaratorPrefix() + " " + parenDeclarator and
|
||||
baseType = getBaseType().getUnspecifiedType() and
|
||||
if (baseType instanceof ArrayType) or (baseType instanceof RoutineType) then
|
||||
parenDeclarator = "(" + declarator
|
||||
else
|
||||
parenDeclarator = declarator
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
exists(Type baseType |
|
||||
baseType = getBaseType().getUnspecifiedType() and
|
||||
if (baseType instanceof ArrayType) or (baseType instanceof RoutineType) then
|
||||
result = ")" + getBaseType().getDeclaratorSuffixBeforeQualifiers()
|
||||
else
|
||||
result = getBaseType().getDeclaratorSuffixBeforeQualifiers()
|
||||
)
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getBaseType().getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
override predicate involvesTemplateParameter() {
|
||||
getBaseType().involvesTemplateParameter()
|
||||
}
|
||||
@@ -1416,27 +1198,6 @@ class RoutineType extends Type, @routinetype {
|
||||
"} with arguments (" + this.explainParameters(0) + ")"
|
||||
}
|
||||
|
||||
override string getTypeSpecifier() {
|
||||
result = getReturnType().getTypeSpecifier()
|
||||
}
|
||||
|
||||
override string getDeclaratorPrefix() {
|
||||
result = getReturnType().getDeclaratorPrefix()
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
override string getDeclaratorSuffixBeforeQualifiers() {
|
||||
result = "(" +
|
||||
concat(int i |
|
||||
exists(getParameterType(i)) |
|
||||
getParameterTypeString(getParameterType(i)), ", " order by i
|
||||
) + ")"
|
||||
}
|
||||
|
||||
override string getDeclaratorSuffix() {
|
||||
result = getReturnType().getDeclaratorSuffixBeforeQualifiers() + getReturnType().getDeclaratorSuffix()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string with the `explain()` values for the parameters of
|
||||
* this function, for instance "int,int".
|
||||
@@ -1535,4 +1296,3 @@ class TypeMention extends Locatable, @type_mention {
|
||||
|
||||
override Location getLocation() { type_mentions(underlyingElement(this), _, result, _)}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import semmle.code.cpp.Declaration
|
||||
import semmle.code.cpp.Type
|
||||
import semmle.code.cpp.Member
|
||||
import semmle.code.cpp.Function
|
||||
private import semmle.code.cpp.internal.IdentityString
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
@@ -92,35 +91,6 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
|
||||
|
||||
override string explain() { result = this.getName() }
|
||||
|
||||
override string getIdentityString() {
|
||||
exists(string simpleName |
|
||||
(
|
||||
if this instanceof Closure then
|
||||
simpleName = "(" + getSimpleName() + ")"
|
||||
else
|
||||
simpleName = getSimpleName()
|
||||
) and
|
||||
result = getScopePrefix(this) + simpleName + getTemplateArgumentsString()
|
||||
)
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
private string getTemplateArgumentsString() {
|
||||
if exists(this.(Class).getATemplateArgument()) then (
|
||||
result = "<" +
|
||||
concat(int i |
|
||||
exists(this.(Class).getTemplateArgument(i)) |
|
||||
this.(Class).getTemplateArgument(i).getTypeIdentityString(), ", " order by i
|
||||
) + ">"
|
||||
)
|
||||
else
|
||||
result = ""
|
||||
}
|
||||
|
||||
override string getTypeSpecifier() {
|
||||
result = getIdentityString()
|
||||
}
|
||||
|
||||
// further overridden in LocalClass
|
||||
override AccessHolder getEnclosingAccessHolder() {
|
||||
result = this.getDeclaringType()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import semmle.code.cpp.Element
|
||||
import semmle.code.cpp.exprs.Access
|
||||
import semmle.code.cpp.Initializer
|
||||
private import semmle.code.cpp.internal.IdentityString
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
@@ -76,27 +75,6 @@ class Variable extends Declaration, @variable {
|
||||
*/
|
||||
predicate declaredUsingAutoType() { autoderivation(underlyingElement(this), _) }
|
||||
|
||||
override string getIdentityString() {
|
||||
exists(Type type |
|
||||
(this instanceof MemberVariable or this instanceof GlobalOrNamespaceVariable) and
|
||||
type = this.getType() and
|
||||
result = type.getTypeSpecifier() + type.getDeclaratorPrefix() + " " + getScopePrefix(this) + this.getName() + this.getTemplateArgumentsString() + type.getDeclaratorSuffixBeforeQualifiers() + type.getDeclaratorSuffix()
|
||||
)
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
private string getTemplateArgumentsString() {
|
||||
if exists(getATemplateArgument()) then (
|
||||
result = "<" +
|
||||
concat(int i |
|
||||
exists(getTemplateArgument(i)) |
|
||||
getTemplateArgument(i).getTypeIdentityString(), ", " order by i
|
||||
) + ">"
|
||||
)
|
||||
else
|
||||
result = ""
|
||||
}
|
||||
|
||||
override VariableDeclarationEntry getADeclarationEntry() {
|
||||
result.getDeclaration() = this
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import semmle.code.cpp.Declaration
|
||||
import semmle.code.cpp.Type
|
||||
|
||||
/**
|
||||
* Gets a string containing the scope in which this declaration is declared.
|
||||
*/
|
||||
string getScopePrefix(Declaration decl) {
|
||||
decl.isMember() and result = decl.getDeclaringType().getIdentityString() + "::" or
|
||||
(
|
||||
decl.isTopLevel() and
|
||||
exists (string parentName |
|
||||
parentName = decl.getNamespace().getQualifiedName() and
|
||||
(
|
||||
parentName != "" and result = parentName + "::" or
|
||||
parentName = "" and result = ""
|
||||
)
|
||||
)
|
||||
) or
|
||||
exists(UserType type |
|
||||
type = decl and type.isLocal() and result = "(" + type.getEnclosingFunction().getIdentityString() + ")::"
|
||||
) or
|
||||
decl instanceof TemplateParameter and result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the identity string of a type used as a parameter. Identical to `Type.getTypeIdentityString()`, except that
|
||||
* it returns `...` for `UnknownType`, which is used to represent variable arguments.
|
||||
*/
|
||||
string getParameterTypeString(Type parameterType) {
|
||||
if parameterType instanceof UnknownType then
|
||||
result = "..."
|
||||
else
|
||||
result = parameterType.getTypeIdentityString()
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
private import IR
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IRConfiguration
|
||||
private import semmle.code.cpp.Print
|
||||
|
||||
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
|
||||
|
||||
@@ -130,7 +131,7 @@ class PrintableFunctionIR extends PrintableIRNode, TPrintableFunctionIR {
|
||||
}
|
||||
|
||||
override string getLabel() {
|
||||
result = funcIR.getFunction().getIdentityString()
|
||||
result = getIdentityString(funcIR.getFunction())
|
||||
}
|
||||
|
||||
override int getOrder() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
private import IR
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IRConfiguration
|
||||
private import semmle.code.cpp.Print
|
||||
|
||||
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
|
||||
|
||||
@@ -130,7 +131,7 @@ class PrintableFunctionIR extends PrintableIRNode, TPrintableFunctionIR {
|
||||
}
|
||||
|
||||
override string getLabel() {
|
||||
result = funcIR.getFunction().getIdentityString()
|
||||
result = getIdentityString(funcIR.getFunction())
|
||||
}
|
||||
|
||||
override int getOrder() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
private import IR
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IRConfiguration
|
||||
private import semmle.code.cpp.Print
|
||||
|
||||
private newtype TPrintIRConfiguration = MkPrintIRConfiguration()
|
||||
|
||||
@@ -130,7 +131,7 @@ class PrintableFunctionIR extends PrintableIRNode, TPrintableFunctionIR {
|
||||
}
|
||||
|
||||
override string getLabel() {
|
||||
result = funcIR.getFunction().getIdentityString()
|
||||
result = getIdentityString(funcIR.getFunction())
|
||||
}
|
||||
|
||||
override int getOrder() {
|
||||
|
||||
Reference in New Issue
Block a user