C++: Make vararg utilities internal for now.

This commit is contained in:
Dave Bartolomeo
2020-03-18 11:18:38 -04:00
parent 4fce20116e
commit fed1bce015
6 changed files with 69 additions and 56 deletions

View File

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

View File

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

View File

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

View File

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

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

View File

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