mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 17:35:35 +02:00
Bug 452416 - Handle variadic functions in variable read/write analysis
Change-Id: Ib28574d3cdc14fc380e6ceb8b2ba4a240b2316c6 Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
parent
fd11d42d89
commit
6a87e3014d
3 changed files with 40 additions and 6 deletions
|
@ -215,4 +215,16 @@ public class VariableReadWriteFlagsTest extends AST2TestBase {
|
|||
a.assertReadWriteFlags("ap->m()", "ap", READ);
|
||||
a.assertReadWriteFlags("(*ap).m()", "ap", READ);
|
||||
}
|
||||
|
||||
// void variadic(...);
|
||||
// void test() {
|
||||
// int waldo;
|
||||
// variadic(waldo);
|
||||
// variadic(&waldo);
|
||||
// }
|
||||
public void testVariadicFunctionCall_452416() throws Exception {
|
||||
AssertionHelper a = getCPPAssertionHelper();
|
||||
a.assertReadWriteFlags("variadic(waldo)", "waldo", READ);
|
||||
a.assertReadWriteFlags("variadic(&waldo)", "waldo", READ | WRITE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.eclipse.cdt.core.dom.ast.IFunction;
|
|||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||
|
@ -191,14 +192,15 @@ public abstract class VariableReadWriteFlags {
|
|||
if (functionNameExpression != null) {
|
||||
final IType type= functionNameExpression.getExpressionType();
|
||||
if (type instanceof IFunctionType) {
|
||||
return rwArgumentForFunctionCall((IFunctionType) type, i, indirection);
|
||||
return rwArgumentForFunctionCall((IFunctionType) type, i, args[i], indirection);
|
||||
} else if (funcCall instanceof IASTImplicitNameOwner) {
|
||||
IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) funcCall).getImplicitNames();
|
||||
if (implicitNames.length == 1) {
|
||||
IASTImplicitName name = implicitNames[0];
|
||||
IBinding binding = name.resolveBinding();
|
||||
if (binding instanceof IFunction) {
|
||||
return rwArgumentForFunctionCall(((IFunction) binding).getType(), i, indirection);
|
||||
return rwArgumentForFunctionCall(((IFunction) binding).getType(), i,
|
||||
args[i], indirection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,10 +211,29 @@ public abstract class VariableReadWriteFlags {
|
|||
return READ | WRITE; // Fallback
|
||||
}
|
||||
|
||||
protected int rwArgumentForFunctionCall(IFunctionType type, int parameterIdx, int indirection) {
|
||||
private IType getArgumentType(IASTInitializerClause argument) {
|
||||
if (argument instanceof ICPPASTInitializerClause) {
|
||||
return ((ICPPASTInitializerClause) argument).getEvaluation().getTypeOrFunctionSet(argument);
|
||||
} else if (argument instanceof IASTExpression) {
|
||||
return ((IASTExpression) argument).getExpressionType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int rwArgumentForFunctionCall(IFunctionType type, int parameterIdx,
|
||||
IASTInitializerClause argument, int indirection) {
|
||||
IType[] ptypes= type.getParameterTypes();
|
||||
IType parameterType = null;
|
||||
if (ptypes != null && ptypes.length > parameterIdx) {
|
||||
return rwAssignmentToType(ptypes[parameterIdx], indirection);
|
||||
parameterType = ptypes[parameterIdx];
|
||||
} else if (type.takesVarArgs()) {
|
||||
// Since variadic functions take their arguments by value, synthesize a parameter type
|
||||
// equal to the argument type.
|
||||
parameterType = getArgumentType(argument);
|
||||
}
|
||||
|
||||
if (parameterType != null) {
|
||||
return rwAssignmentToType(parameterType, indirection);
|
||||
}
|
||||
return READ | WRITE; // Fallback
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
|
@ -78,9 +79,9 @@ public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags {
|
|||
if (b instanceof ICPPConstructor) {
|
||||
final ICPPConstructor ctor = (ICPPConstructor) b;
|
||||
int idx= 0;
|
||||
for (IASTNode child : parent.getArguments()) {
|
||||
for (IASTInitializerClause child : parent.getArguments()) {
|
||||
if (child == node) {
|
||||
return rwArgumentForFunctionCall(ctor.getType(), idx, indirection);
|
||||
return rwArgumentForFunctionCall(ctor.getType(), idx, child, indirection);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue