C++: Fix PR feedback

This commit is contained in:
Dave Bartolomeo
2019-01-28 14:25:13 -08:00
parent 7b54db8ca9
commit eb7016620b
13 changed files with 484 additions and 394 deletions

View File

@@ -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
}
}

View File

@@ -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.
*

View File

@@ -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
}

View 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()
}

View File

@@ -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)
)
}

View File

@@ -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, _)}
}

View File

@@ -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()

View File

@@ -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
}

View File

@@ -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()
}

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() {