mirror of
https://github.com/github/codeql.git
synced 2025-12-21 11:16:30 +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. */
|
||||
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. */
|
||||
Type getAThrownType() { result = getADeclarationEntry().getAThrownType() }
|
||||
|
||||
|
||||
@@ -2,13 +2,6 @@ import semmle.code.cpp.exprs.Expr
|
||||
import semmle.code.cpp.Function
|
||||
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.
|
||||
*
|
||||
@@ -85,32 +78,6 @@ abstract class Call extends Expr, NameQualifiableElement {
|
||||
|
||||
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
|
||||
* 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
|
||||
* 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.
|
||||
@@ -292,12 +259,6 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
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() {
|
||||
this.getChild(_).mayBeImpure() or
|
||||
this.getTarget().mayHaveSideEffects() or
|
||||
@@ -417,10 +378,6 @@ class ExprCall extends Call, @callexpr {
|
||||
override string toString() { result = "call to expression" }
|
||||
|
||||
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 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.internal.CppType
|
||||
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.internal.TempVariableTag
|
||||
private import InstructionTag
|
||||
@@ -28,7 +29,7 @@ private int getEllipsisVariableByteSize() {
|
||||
max(Call call, int callSize |
|
||||
callSize =
|
||||
sum(int argIndex |
|
||||
call.isEllipsisArgumentIndex(argIndex)
|
||||
isEllipsisArgumentIndex(call, argIndex)
|
||||
|
|
||||
call.getArgument(argIndex).getType().getSize()
|
||||
)
|
||||
@@ -87,7 +88,7 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
|
||||
final private TranslatedParameter getParameter(int index) {
|
||||
result = getTranslatedParameter(func.getParameter(index))
|
||||
or
|
||||
index = func.getEllipsisParameterIndex() and
|
||||
index = getEllipsisParameterIndexForFunction(func) and
|
||||
result = getTranslatedEllipsisParameter(func)
|
||||
}
|
||||
|
||||
@@ -144,7 +145,7 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
|
||||
child = getParameter(paramIndex) and
|
||||
if
|
||||
exists(func.getParameter(paramIndex + 1)) or
|
||||
func.getEllipsisParameterIndex() = paramIndex + 1
|
||||
getEllipsisParameterIndexForFunction(func) = paramIndex + 1
|
||||
then result = getParameter(paramIndex + 1).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 semmle.code.cpp.ir.internal.VarArgs
|
||||
|
||||
from Call call, int argIndex, int paramIndex
|
||||
where
|
||||
paramIndex = call.getParameterIndexForArgument(argIndex)
|
||||
paramIndex = getParameterIndexForArgument(call, argIndex)
|
||||
select call, argIndex, paramIndex
|
||||
|
||||
Reference in New Issue
Block a user