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

View File

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

View File

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

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

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