mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
C++: Make vararg utilities internal for now.
This commit is contained in:
@@ -364,12 +364,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
|||||||
/** Holds if this function is a varargs function. */
|
/** Holds if this function is a varargs function. */
|
||||||
predicate isVarargs() { hasSpecifier("varargs") }
|
predicate isVarargs() { hasSpecifier("varargs") }
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the index of the `...` parameter, if any. If present, the value will always be equal to
|
|
||||||
* `getNumberOfParameters()`.
|
|
||||||
*/
|
|
||||||
int getEllipsisParameterIndex() { isVarargs() and result = getNumberOfParameters() }
|
|
||||||
|
|
||||||
/** Gets a type that is specified to be thrown by the function. */
|
/** Gets a type that is specified to be thrown by the function. */
|
||||||
Type getAThrownType() { result = getADeclarationEntry().getAThrownType() }
|
Type getAThrownType() { result = getADeclarationEntry().getAThrownType() }
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,6 @@ import semmle.code.cpp.exprs.Expr
|
|||||||
import semmle.code.cpp.Function
|
import semmle.code.cpp.Function
|
||||||
private import semmle.code.cpp.dataflow.EscapesTree
|
private import semmle.code.cpp.dataflow.EscapesTree
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the index of the `...` parameter, if any.
|
|
||||||
*/
|
|
||||||
private int getEllipsisParameterIndex(RoutineType type) {
|
|
||||||
type.getParameterType(result) instanceof UnknownType
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A C/C++ call.
|
* A C/C++ call.
|
||||||
*
|
*
|
||||||
@@ -85,32 +78,6 @@ abstract class Call extends Expr, NameQualifiableElement {
|
|||||||
|
|
||||||
override string toString() { none() }
|
override string toString() { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the index of the `...` parameter, if any. This will be one greater than the index of the
|
|
||||||
* last declared positional parameter.
|
|
||||||
*/
|
|
||||||
abstract int getEllipsisParameterIndex();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the index of the parameter that will be initialized with the value of the argument
|
|
||||||
* specified by `argIndex`. For ordinary positional parameters, the argument and parameter indices
|
|
||||||
* will be equal. For a call to a varargs function, all arguments passed to the `...` will be
|
|
||||||
* mapped to the index returned by `getEllipsisParameterIndex()`.
|
|
||||||
*/
|
|
||||||
final int getParameterIndexForArgument(int argIndex) {
|
|
||||||
exists(getArgument(argIndex)) and
|
|
||||||
if argIndex >= getEllipsisParameterIndex()
|
|
||||||
then result = getEllipsisParameterIndex()
|
|
||||||
else result = argIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the argument specified by `index` is an argument to the `...` of a varargs function.
|
|
||||||
*/
|
|
||||||
final predicate isEllipsisArgumentIndex(int index) {
|
|
||||||
exists(getArgument(index)) and index >= getEllipsisParameterIndex()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if this call passes the variable accessed by `va` by
|
* Holds if this call passes the variable accessed by `va` by
|
||||||
* reference as the `i`th argument.
|
* reference as the `i`th argument.
|
||||||
@@ -229,7 +196,7 @@ class FunctionCall extends Call, @funbindexpr {
|
|||||||
* constructor calls, this predicate instead gets the `Class` of the constructor
|
* constructor calls, this predicate instead gets the `Class` of the constructor
|
||||||
* being called.
|
* being called.
|
||||||
*/
|
*/
|
||||||
private Type getTargetType() { result = Call.super.getType().stripType() }
|
Type getTargetType() { result = Call.super.getType().stripType() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the expected return type of the function called by this call.
|
* Gets the expected return type of the function called by this call.
|
||||||
@@ -292,12 +259,6 @@ class FunctionCall extends Call, @funbindexpr {
|
|||||||
else result = "call to unknown function"
|
else result = "call to unknown function"
|
||||||
}
|
}
|
||||||
|
|
||||||
final override int getEllipsisParameterIndex() {
|
|
||||||
if getTargetType() instanceof RoutineType
|
|
||||||
then result = getEllipsisParameterIndex(getTargetType())
|
|
||||||
else result = getTarget().getEllipsisParameterIndex()
|
|
||||||
}
|
|
||||||
|
|
||||||
override predicate mayBeImpure() {
|
override predicate mayBeImpure() {
|
||||||
this.getChild(_).mayBeImpure() or
|
this.getChild(_).mayBeImpure() or
|
||||||
this.getTarget().mayHaveSideEffects() or
|
this.getTarget().mayHaveSideEffects() or
|
||||||
@@ -417,10 +378,6 @@ class ExprCall extends Call, @callexpr {
|
|||||||
override string toString() { result = "call to expression" }
|
override string toString() { result = "call to expression" }
|
||||||
|
|
||||||
override Function getTarget() { none() }
|
override Function getTarget() { none() }
|
||||||
|
|
||||||
final override int getEllipsisParameterIndex() {
|
|
||||||
result = getEllipsisParameterIndex(getExpr().getType().stripType())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -63,8 +63,6 @@ deprecated class MessageExpr extends Expr, Call {
|
|||||||
override Expr getArgument(int n) { none() }
|
override Expr getArgument(int n) { none() }
|
||||||
|
|
||||||
override int getPrecedence() { none() }
|
override int getPrecedence() { none() }
|
||||||
|
|
||||||
final override int getEllipsisParameterIndex() { none() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import semmle.code.cpp.ir.implementation.raw.IR
|
|||||||
private import semmle.code.cpp.ir.implementation.Opcode
|
private import semmle.code.cpp.ir.implementation.Opcode
|
||||||
private import semmle.code.cpp.ir.internal.CppType
|
private import semmle.code.cpp.ir.internal.CppType
|
||||||
private import semmle.code.cpp.ir.internal.IRUtilities
|
private import semmle.code.cpp.ir.internal.IRUtilities
|
||||||
|
private import semmle.code.cpp.ir.internal.VarArgs
|
||||||
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||||
private import semmle.code.cpp.ir.internal.TempVariableTag
|
private import semmle.code.cpp.ir.internal.TempVariableTag
|
||||||
private import InstructionTag
|
private import InstructionTag
|
||||||
@@ -28,7 +29,7 @@ private int getEllipsisVariableByteSize() {
|
|||||||
max(Call call, int callSize |
|
max(Call call, int callSize |
|
||||||
callSize =
|
callSize =
|
||||||
sum(int argIndex |
|
sum(int argIndex |
|
||||||
call.isEllipsisArgumentIndex(argIndex)
|
isEllipsisArgumentIndex(call, argIndex)
|
||||||
|
|
|
|
||||||
call.getArgument(argIndex).getType().getSize()
|
call.getArgument(argIndex).getType().getSize()
|
||||||
)
|
)
|
||||||
@@ -87,7 +88,7 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
|
|||||||
final private TranslatedParameter getParameter(int index) {
|
final private TranslatedParameter getParameter(int index) {
|
||||||
result = getTranslatedParameter(func.getParameter(index))
|
result = getTranslatedParameter(func.getParameter(index))
|
||||||
or
|
or
|
||||||
index = func.getEllipsisParameterIndex() and
|
index = getEllipsisParameterIndexForFunction(func) and
|
||||||
result = getTranslatedEllipsisParameter(func)
|
result = getTranslatedEllipsisParameter(func)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +145,7 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
|
|||||||
child = getParameter(paramIndex) and
|
child = getParameter(paramIndex) and
|
||||||
if
|
if
|
||||||
exists(func.getParameter(paramIndex + 1)) or
|
exists(func.getParameter(paramIndex + 1)) or
|
||||||
func.getEllipsisParameterIndex() = paramIndex + 1
|
getEllipsisParameterIndexForFunction(func) = paramIndex + 1
|
||||||
then result = getParameter(paramIndex + 1).getFirstInstruction()
|
then result = getParameter(paramIndex + 1).getFirstInstruction()
|
||||||
else result = getConstructorInitList().getFirstInstruction()
|
else result = getConstructorInitList().getFirstInstruction()
|
||||||
)
|
)
|
||||||
|
|||||||
62
cpp/ql/src/semmle/code/cpp/ir/internal/VarArgs.qll
Normal file
62
cpp/ql/src/semmle/code/cpp/ir/internal/VarArgs.qll
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* Utilities for determining which parameters and arguments correspond to the `...` parameter for
|
||||||
|
* varargs functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import cpp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index of the `...` parameter, if any. If present, the value will always be equal to
|
||||||
|
* `func.getNumberOfParameters()`.
|
||||||
|
*/
|
||||||
|
int getEllipsisParameterIndexForFunction(Function func) {
|
||||||
|
func.isVarargs() and result = func.getNumberOfParameters()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index of the `...` parameter, if any.
|
||||||
|
*/
|
||||||
|
int getEllipsisParameterIndexForRoutineType(RoutineType type) {
|
||||||
|
// Since the extractor doesn't record this information directly, we look for routine types whose
|
||||||
|
// last parameter type is `UnknownType`.
|
||||||
|
type.getParameterType(result) instanceof UnknownType and
|
||||||
|
result = strictcount(type.getAParameterType()) - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index of the `...` parameter, if any. This will be one greater than the index of the
|
||||||
|
* last declared positional parameter.
|
||||||
|
*/
|
||||||
|
int getEllipsisParameterIndex(Call call) {
|
||||||
|
exists(FunctionCall funcCall |
|
||||||
|
funcCall = call and
|
||||||
|
if funcCall.getTargetType() instanceof RoutineType
|
||||||
|
then result = getEllipsisParameterIndexForRoutineType(funcCall.getTargetType())
|
||||||
|
else result = getEllipsisParameterIndexForFunction(funcCall.getTarget())
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(ExprCall exprCall |
|
||||||
|
exprCall = call and
|
||||||
|
result = getEllipsisParameterIndexForRoutineType(exprCall.getExpr().getType().stripType())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index of the parameter that will be initialized with the value of the argument
|
||||||
|
* specified by `argIndex`. For ordinary positional parameters, the argument and parameter indices
|
||||||
|
* will be equal. For a call to a varargs function, all arguments passed to the `...` will be
|
||||||
|
* mapped to the index returned by `getEllipsisParameterIndex()`.
|
||||||
|
*/
|
||||||
|
int getParameterIndexForArgument(Call call, int argIndex) {
|
||||||
|
exists(call.getArgument(argIndex)) and
|
||||||
|
if argIndex >= getEllipsisParameterIndex(call)
|
||||||
|
then result = getEllipsisParameterIndex(call)
|
||||||
|
else result = argIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the argument specified by `index` is an argument to the `...` of a varargs function.
|
||||||
|
*/
|
||||||
|
predicate isEllipsisArgumentIndex(Call call, int index) {
|
||||||
|
exists(call.getArgument(index)) and index >= getEllipsisParameterIndex(call)
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import cpp
|
import cpp
|
||||||
|
import semmle.code.cpp.ir.internal.VarArgs
|
||||||
|
|
||||||
from Call call, int argIndex, int paramIndex
|
from Call call, int argIndex, int paramIndex
|
||||||
where
|
where
|
||||||
paramIndex = call.getParameterIndexForArgument(argIndex)
|
paramIndex = getParameterIndexForArgument(call, argIndex)
|
||||||
select call, argIndex, paramIndex
|
select call, argIndex, paramIndex
|
||||||
|
|||||||
Reference in New Issue
Block a user