From b4f19eebddff86559497bd3fd8045d2439f14279 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Fri, 24 May 2019 12:06:59 +0100 Subject: [PATCH] C++: Revert the getName() changes This reverts the `getName()` parts of 56e88cbac0 and 0a2e28858a. --- cpp/ql/src/semmle/code/cpp/Declaration.qll | 2 +- cpp/ql/src/semmle/code/cpp/Enum.qll | 5 ++ cpp/ql/src/semmle/code/cpp/FriendDecl.qll | 5 ++ cpp/ql/src/semmle/code/cpp/Function.qll | 2 + cpp/ql/src/semmle/code/cpp/ObjectiveC.qll | 3 ++ cpp/ql/src/semmle/code/cpp/Parameter.qll | 55 +++++++++++++++++----- cpp/ql/src/semmle/code/cpp/UserType.qll | 7 +-- cpp/ql/src/semmle/code/cpp/Variable.qll | 9 ++++ 8 files changed, 73 insertions(+), 15 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/Declaration.qll b/cpp/ql/src/semmle/code/cpp/Declaration.qll index ec2bb7b2906..8a2b446563c 100644 --- a/cpp/ql/src/semmle/code/cpp/Declaration.qll +++ b/cpp/ql/src/semmle/code/cpp/Declaration.qll @@ -116,7 +116,7 @@ abstract class Declaration extends Locatable, @declaration { * To test whether this declaration has a particular name in the global * namespace, use `hasGlobalName`. */ - string getName() { result = underlyingElement(this).(Q::Declaration).getName() } + abstract string getName(); /** Holds if this declaration has the given name. */ predicate hasName(string name) { name = this.getName() } diff --git a/cpp/ql/src/semmle/code/cpp/Enum.qll b/cpp/ql/src/semmle/code/cpp/Enum.qll index a501077cc3e..b5a06db8879 100644 --- a/cpp/ql/src/semmle/code/cpp/Enum.qll +++ b/cpp/ql/src/semmle/code/cpp/Enum.qll @@ -100,6 +100,11 @@ class EnumConstant extends Declaration, @enumconstant { result = this.getDeclaringEnum().getDeclaringType() } + /** + * Gets the name of this enumerator. + */ + override string getName() { enumconstants(underlyingElement(this),_,_,_,result,_) } + /** * Gets the value that this enumerator is initialized to, as a * string. This can be a value explicitly given to the enumerator, or an diff --git a/cpp/ql/src/semmle/code/cpp/FriendDecl.qll b/cpp/ql/src/semmle/code/cpp/FriendDecl.qll index 52e57d0199f..08c52a09cf5 100644 --- a/cpp/ql/src/semmle/code/cpp/FriendDecl.qll +++ b/cpp/ql/src/semmle/code/cpp/FriendDecl.qll @@ -35,6 +35,11 @@ class FriendDecl extends Declaration, @frienddecl { /** Gets the location of this friend declaration. */ override Location getLocation() { frienddecls(underlyingElement(this),_,_,result) } + /** Gets a descriptive string for this friend declaration. */ + override string getName() { + result = this.getDeclaringClass().getName() + "'s friend" + } + /** * Friend declarations do not have specifiers. It makes no difference * whether they are declared in a public, protected or private section of diff --git a/cpp/ql/src/semmle/code/cpp/Function.qll b/cpp/ql/src/semmle/code/cpp/Function.qll index e41b481ee63..2c4fe565b4d 100644 --- a/cpp/ql/src/semmle/code/cpp/Function.qll +++ b/cpp/ql/src/semmle/code/cpp/Function.qll @@ -17,6 +17,8 @@ private import semmle.code.cpp.internal.ResolveClass * in more detail in `Declaration.qll`. */ 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 diff --git a/cpp/ql/src/semmle/code/cpp/ObjectiveC.qll b/cpp/ql/src/semmle/code/cpp/ObjectiveC.qll index 3e3c52c35e8..aa7e9d4ddc5 100644 --- a/cpp/ql/src/semmle/code/cpp/ObjectiveC.qll +++ b/cpp/ql/src/semmle/code/cpp/ObjectiveC.qll @@ -148,6 +148,9 @@ deprecated class FinallyBlock extends Block { deprecated class Property extends Declaration { Property() { none() } + /** Gets the name of this property. */ + override string getName() { none() } + /** * Gets nothing (provided for compatibility with Declaration). * diff --git a/cpp/ql/src/semmle/code/cpp/Parameter.qll b/cpp/ql/src/semmle/code/cpp/Parameter.qll index 14f0ee462c5..c6fc33b9355 100644 --- a/cpp/ql/src/semmle/code/cpp/Parameter.qll +++ b/cpp/ql/src/semmle/code/cpp/Parameter.qll @@ -1,7 +1,6 @@ import semmle.code.cpp.Location import semmle.code.cpp.Declaration private import semmle.code.cpp.internal.ResolveClass -private import semmle.code.cpp.internal.QualifiedName as Q /** * A C/C++ function parameter or catch block parameter. @@ -14,6 +13,26 @@ private import semmle.code.cpp.internal.QualifiedName as Q * have multiple declarations. */ class Parameter extends LocalScopeVariable, @parameter { + + /** + * Gets the canonical name, or names, of this parameter. + * + * The canonical names are the first non-empty category from the + * following list: + * 1. The name given to the parameter at the function's definition or + * (for catch block parameters) at the catch block. + * 2. A name given to the parameter at a function declaration. + * 3. The name "p#i" where i is the index of the parameter. + */ + override string getName() { + exists (VariableDeclarationEntry vde + | vde = getANamedDeclarationEntry() and result = vde.getName() + | vde.isDefinition() or not getANamedDeclarationEntry().isDefinition()) + or + (not exists(getANamedDeclarationEntry()) and + result = "p#" + this.getIndex().toString()) + } + /** * Gets the name of this parameter, including it's type. * @@ -34,6 +53,27 @@ class Parameter extends LocalScopeVariable, @parameter { else result = typeString + nameString)) } + private VariableDeclarationEntry getANamedDeclarationEntry() { + result = getAnEffectiveDeclarationEntry() and result.getName() != "" + } + + /** + * Gets a declaration entry corresponding to this declaration. + * + * This predicate is the same as getADeclarationEntry(), except that for + * parameters of instantiated function templates, gives the declaration + * entry of the prototype instantiation of the parameter (as + * non-prototype instantiations don't have declaration entries of their + * own). + */ + private VariableDeclarationEntry getAnEffectiveDeclarationEntry() { + if getFunction().isConstructedFrom(_) + then exists (Function prototypeInstantiation + | prototypeInstantiation.getParameter(getIndex()) = result.getVariable() and + getFunction().isConstructedFrom(prototypeInstantiation)) + else result = getADeclarationEntry() + } + /** * Gets the name of this parameter in the given block (which should be * the body of a function with which the parameter is associated). @@ -55,9 +95,7 @@ class Parameter extends LocalScopeVariable, @parameter { * In other words, this predicate holds precisely when the result of * `getName()` is not "p#i" (where `i` is the index of the parameter). */ - predicate isNamed() { - exists(underlyingElement(this).(Q::Parameter).getANamedDeclarationEntry()) - } + predicate isNamed() { exists(getANamedDeclarationEntry()) } /** * Gets the function to which this parameter belongs, if it is a function @@ -97,13 +135,8 @@ class Parameter extends LocalScopeVariable, @parameter { * of the declaration locations. */ override Location getLocation() { - exists(VariableDeclarationEntry vde | - vde = underlyingElement(this).(Q::Parameter).getAnEffectiveDeclarationEntry() and - result = vde.getLocation() - | - vde.isDefinition() - or - not underlyingElement(this).(Q::Parameter).getAnEffectiveDeclarationEntry().isDefinition() + exists(VariableDeclarationEntry vde | vde = getAnEffectiveDeclarationEntry() and result = vde.getLocation() | + vde.isDefinition() or not getAnEffectiveDeclarationEntry().isDefinition() ) } } diff --git a/cpp/ql/src/semmle/code/cpp/UserType.qll b/cpp/ql/src/semmle/code/cpp/UserType.qll index 8f4643108b9..e3330f18121 100644 --- a/cpp/ql/src/semmle/code/cpp/UserType.qll +++ b/cpp/ql/src/semmle/code/cpp/UserType.qll @@ -9,9 +9,10 @@ private import semmle.code.cpp.internal.ResolveClass * `Enum`, and `TypedefType`. */ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @usertype { - override string getName() { - result = Declaration.super.getName() - } + /** + * Gets the name of this type. + */ + override string getName() { usertypes(underlyingElement(this),result,_) } /** * Gets the simple name of this type, without any template parameters. For example diff --git a/cpp/ql/src/semmle/code/cpp/Variable.qll b/cpp/ql/src/semmle/code/cpp/Variable.qll index 527c35d6ffe..98cff4169a4 100644 --- a/cpp/ql/src/semmle/code/cpp/Variable.qll +++ b/cpp/ql/src/semmle/code/cpp/Variable.qll @@ -41,6 +41,9 @@ class Variable extends Declaration, @variable { /** Holds if this variable is `volatile`. */ predicate isVolatile() { this.getType().isVolatile() } + /** Gets the name of this variable. */ + override string getName() { none() } + /** Gets the type of this variable. */ Type getType() { none() } @@ -294,6 +297,8 @@ deprecated class StackVariable extends Variable { * A local variable can be declared by a `DeclStmt` or a `ConditionDeclExpr`. */ class LocalVariable extends LocalScopeVariable, @localvariable { + override string getName() { localvariables(underlyingElement(this),_,result) } + override Type getType() { localvariables(underlyingElement(this),unresolveElement(result),_) } override Function getFunction() { @@ -306,6 +311,8 @@ class LocalVariable extends LocalScopeVariable, @localvariable { * A C/C++ variable which has global scope or namespace scope. */ class GlobalOrNamespaceVariable extends Variable, @globalvariable { + override string getName() { globalvariables(underlyingElement(this),_,result) } + override Type getType() { globalvariables(underlyingElement(this),unresolveElement(result),_) } override Element getEnclosingElement() { none() } @@ -353,6 +360,8 @@ class MemberVariable extends Variable, @membervariable { /** Holds if this member is public. */ predicate isPublic() { this.hasSpecifier("public") } + override string getName() { membervariables(underlyingElement(this),_,result) } + override Type getType() { if (strictcount(this.getAType()) = 1) then ( result = this.getAType()