@Override public ProgramState apply(ProgramState input) { return input.put(variableTree.symbol(), sv); } });
@VisibleForTesting Iterable<ProgramState> startingStates(String signature, ProgramState currentState, boolean isStaticMethod) { // TODO : deal with parameter annotations, equals methods etc. int parameterIdx = 0; ProgramState state = currentState; if(!isStaticMethod) { // Add a sv for "this" SymbolicValue thisSV = constraintManager.createSymbolicValue((Instruction) null); state = currentState.addConstraint(thisSV, ObjectConstraint.NOT_NULL) .addConstraint(thisSV, new TypedConstraint(signature.substring(0, signature.indexOf('#')))).put(0, thisSV); parameterIdx = 1; } org.objectweb.asm.Type[] argumentTypes = org.objectweb.asm.Type.getArgumentTypes(signature.substring(signature.indexOf('('))); for (org.objectweb.asm.Type argumentType: argumentTypes) { SymbolicValue sv = constraintManager.createSymbolicValue((Instruction) null); methodBehavior.addParameter(sv); state = state.put(parameterIdx, sv); state = setDoubleOrLong(state, sv, argumentType.getSize() == 2); parameterIdx += argumentType.getSize(); } return Collections.singletonList(state); }
private void executeLogicalAssignment(AssignmentExpressionTree tree) { ExpressionTree variable = tree.variable(); // FIXME handle also assignments with this SONARJAVA-2242 if (variable.is(Tree.Kind.IDENTIFIER)) { ProgramState.Pop unstack = programState.unstackValue(2); ProgramState.SymbolicValueSymbol assignedTo = unstack.valuesAndSymbols.get(1); ProgramState.SymbolicValueSymbol value = unstack.valuesAndSymbols.get(0); programState = unstack.state; SymbolicValue symbolicValue = constraintManager.createBinarySymbolicValue(tree, ImmutableList.of(assignedTo, value)); Symbol symbol = ((IdentifierTree) variable).symbol(); programState = programState.stackValue(symbolicValue, symbol); programState = programState.put(symbol, symbolicValue); } }
ProgramState resetFieldValues(ConstraintManager constraintManager, boolean resetOnlyStaticFields) { List<Symbol> fields = new ArrayList<>(); values.forEach((symbol, symbolicValue) -> { if (isField(symbol) && !symbol.isFinal() && (symbol.isStatic() || !resetOnlyStaticFields) ) { fields.add(symbol); } }); ProgramState newProgramState = this; for (Symbol field : fields) { newProgramState = newProgramState.put(field, constraintManager.createDefaultSymbolicValue()); } return newProgramState; }
@VisibleForTesting Iterable<ProgramState> startingStates(String signature, ProgramState currentState, boolean isStaticMethod) { // TODO : deal with parameter annotations, equals methods etc. int parameterIdx = 0; ProgramState state = currentState; if(!isStaticMethod) { // Add a sv for "this" SymbolicValue thisSV = constraintManager.createSymbolicValue((Instruction) null); state = currentState.addConstraint(thisSV, ObjectConstraint.NOT_NULL) .addConstraint(thisSV, new TypedConstraint(signature.substring(0, signature.indexOf('#')))).put(0, thisSV); parameterIdx = 1; } org.objectweb.asm.Type[] argumentTypes = org.objectweb.asm.Type.getArgumentTypes(signature.substring(signature.indexOf('('))); for (org.objectweb.asm.Type argumentType: argumentTypes) { SymbolicValue sv = constraintManager.createSymbolicValue((Instruction) null); methodBehavior.addParameter(sv); state = state.put(parameterIdx, sv); state = setDoubleOrLong(state, sv, argumentType.getSize() == 2); parameterIdx += argumentType.getSize(); } return Collections.singletonList(state); }
ProgramState resetFieldValues(ConstraintManager constraintManager, boolean resetOnlyStaticFields) { List<Symbol> fields = new ArrayList<>(); values.forEach((symbol, symbolicValue) -> { if (isField(symbol) && !symbol.isFinal() && (symbol.isStatic() || !resetOnlyStaticFields) ) { fields.add(symbol); } }); ProgramState newProgramState = this; for (Symbol field : fields) { newProgramState = newProgramState.put(field, constraintManager.createDefaultSymbolicValue()); } return newProgramState; }
private void executeLogicalAssignment(AssignmentExpressionTree tree) { ExpressionTree variable = tree.variable(); // FIXME handle also assignments with this SONARJAVA-2242 if (variable.is(Tree.Kind.IDENTIFIER)) { ProgramState.Pop unstack = programState.unstackValue(2); ProgramState.SymbolicValueSymbol assignedTo = unstack.valuesAndSymbols.get(1); ProgramState.SymbolicValueSymbol value = unstack.valuesAndSymbols.get(0); programState = unstack.state; SymbolicValue symbolicValue = constraintManager.createBinarySymbolicValue(tree, ImmutableList.of(assignedTo, value)); Symbol symbol = ((IdentifierTree) variable).symbol(); programState = programState.stackValue(symbolicValue, symbol); programState = programState.put(symbol, symbolicValue); } }
private void executeLogicalAssignement(AssignmentExpressionTree tree) { ExpressionTree variable = tree.variable(); if (variable.is(Tree.Kind.IDENTIFIER)) { ProgramState.Pop unstack = programState.unstackValue(2); SymbolicValue assignedTo = unstack.values.get(0); SymbolicValue value = unstack.values.get(1); programState = unstack.state; SymbolicValue symbolicValue = constraintManager.createSymbolicValue(tree); symbolicValue.computedFrom(ImmutableList.of(assignedTo, value)); programState = programState.put(((IdentifierTree) variable).symbol(), symbolicValue); programState = programState.stackValue(symbolicValue); } }
private void executeIdentifier(IdentifierTree tree) { Symbol symbol = tree.symbol(); SymbolicValue value = programState.getValue(symbol); if (value == null) { value = constraintManager.createSymbolicValue(tree); programState = programState.put(symbol, value); } programState = programState.stackValue(value); }
private void executeAssignement(AssignmentExpressionTree tree) { ExpressionTree variable = tree.variable(); if (variable.is(Tree.Kind.IDENTIFIER)) { // FIXME restricted to identifiers for now. ProgramState.Pop unstack = programState.unstackValue(2); SymbolicValue value = tree.is(Tree.Kind.ASSIGNMENT) ? unstack.values.get(1) : constraintManager.createSymbolicValue(tree); programState = unstack.state; programState = programState.put(((IdentifierTree) variable).symbol(), value); programState = programState.stackValue(value); } }
private Iterable<ProgramState> startingStates(MethodTree tree, ProgramState currentState) { Stream<ProgramState> stateStream = Stream.of(currentState); boolean isEqualsMethod = EQUALS.matches(tree); boolean nonNullParameters = isGloballyAnnotatedParameterNonNull(methodTree.symbol()); boolean nullableParameters = isGloballyAnnotatedParameterNullable(methodTree.symbol()); boolean hasMethodBehavior = methodBehavior != null; for (final VariableTree variableTree : tree.parameters()) { // create final SymbolicValue sv = constraintManager.createSymbolicValue(variableTree); Symbol variableSymbol = variableTree.symbol(); if (hasMethodBehavior) { methodBehavior.addParameter(sv); } stateStream = stateStream.map(ps -> ps.put(variableSymbol, sv)); if (isEqualsMethod || parameterCanBeNull(variableSymbol, nullableParameters)) { stateStream = stateStream.flatMap((ProgramState ps) -> Stream.concat( sv.setConstraint(ps, ObjectConstraint.NULL).stream(), sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream() )); } else if (nonNullParameters || isAnnotatedNonNull(variableSymbol)) { stateStream = stateStream.flatMap(ps -> sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream()); } } return stateStream.collect(Collectors.toList()); }
private Iterable<ProgramState> startingStates(MethodTree tree, ProgramState currentState) { Stream<ProgramState> stateStream = Stream.of(currentState); boolean isEqualsMethod = EQUALS.matches(tree); boolean nonNullParameters = isGloballyAnnotatedParameterNonNull(methodTree.symbol()); boolean nullableParameters = isGloballyAnnotatedParameterNullable(methodTree.symbol()); boolean hasMethodBehavior = methodBehavior != null; for (final VariableTree variableTree : tree.parameters()) { // create final SymbolicValue sv = constraintManager.createSymbolicValue(variableTree); Symbol variableSymbol = variableTree.symbol(); if (hasMethodBehavior) { methodBehavior.addParameter(sv); } stateStream = stateStream.map(ps -> ps.put(variableSymbol, sv)); if (isEqualsMethod || parameterCanBeNull(variableSymbol, nullableParameters)) { stateStream = stateStream.flatMap((ProgramState ps) -> Stream.concat( sv.setConstraint(ps, ObjectConstraint.NULL).stream(), sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream() )); } else if (nonNullParameters || isAnnotatedNonNull(variableSymbol)) { stateStream = stateStream.flatMap(ps -> sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream()); } } return stateStream.collect(Collectors.toList()); }
private void executeUnaryExpression(Tree tree) { // consume one and produce one ProgramState.Pop unstackUnary = programState.unstackValue(1); programState = unstackUnary.state; SymbolicValue unarySymbolicValue = constraintManager.createSymbolicValue(tree); unarySymbolicValue.computedFrom(unstackUnary.valuesAndSymbols); ProgramState.SymbolicValueSymbol symbolicValueSymbol = unstackUnary.valuesAndSymbols.get(0); if (tree.is(Tree.Kind.POSTFIX_DECREMENT, Tree.Kind.POSTFIX_INCREMENT)) { programState = programState.stackValue(symbolicValueSymbol.sv, symbolicValueSymbol.symbol); } else { programState = programState.stackValue(unarySymbolicValue); } if (tree.is(Tree.Kind.POSTFIX_DECREMENT, Tree.Kind.POSTFIX_INCREMENT, Tree.Kind.PREFIX_DECREMENT, Tree.Kind.PREFIX_INCREMENT) && symbolicValueSymbol.symbol != null) { programState = programState.put(symbolicValueSymbol.symbol, unarySymbolicValue); } }
private void executeVariable(VariableTree variableTree, @Nullable Tree terminator) { ExpressionTree initializer = variableTree.initializer(); if (initializer == null) { SymbolicValue sv = null; if (terminator != null && terminator.is(Tree.Kind.FOR_EACH_STATEMENT)) { sv = constraintManager.createSymbolicValue(variableTree); } else if (variableTree.type().symbolType().is("boolean")) { sv = SymbolicValue.FALSE_LITERAL; } else if (!variableTree.type().symbolType().isPrimitive()) { sv = SymbolicValue.NULL_LITERAL; } if (sv != null) { programState = programState.put(variableTree.symbol(), sv); } } else { ProgramState.Pop unstack = programState.unstackValue(1); programState = unstack.state; programState = programState.put(variableTree.symbol(), unstack.values.get(0)); } }
private void executeIdentifier(IdentifierTree tree) { Symbol symbol = tree.symbol(); SymbolicValue value = programState.getValue(symbol); if (value == null) { value = constraintManager.createSymbolicValue(tree); programState = programState.stackValue(value, symbol); learnIdentifierConstraints(tree, value); } else { programState = programState.stackValue(value, symbol); } programState = programState.put(symbol, value); }
private void executeIdentifier(IdentifierTree tree) { Symbol symbol = tree.symbol(); SymbolicValue value = programState.getValue(symbol); if (value == null) { value = constraintManager.createSymbolicValue(tree); programState = programState.stackValue(value, symbol); learnIdentifierConstraints(tree, value); } else { programState = programState.stackValue(value, symbol); } programState = programState.put(symbol, value); }
private void executeUnaryExpression(Tree tree) { // consume one and produce one ProgramState.Pop unstackUnary = programState.unstackValue(1); programState = unstackUnary.state; SymbolicValue unarySymbolicValue = constraintManager.createSymbolicValue(tree); unarySymbolicValue.computedFrom(unstackUnary.valuesAndSymbols); ProgramState.SymbolicValueSymbol symbolicValueSymbol = unstackUnary.valuesAndSymbols.get(0); if (tree.is(Tree.Kind.POSTFIX_DECREMENT, Tree.Kind.POSTFIX_INCREMENT)) { programState = programState.stackValue(symbolicValueSymbol.sv, symbolicValueSymbol.symbol); } else { programState = programState.stackValue(unarySymbolicValue); } if (tree.is(Tree.Kind.POSTFIX_DECREMENT, Tree.Kind.POSTFIX_INCREMENT, Tree.Kind.PREFIX_DECREMENT, Tree.Kind.PREFIX_INCREMENT) && symbolicValueSymbol.symbol != null) { programState = programState.put(symbolicValueSymbol.symbol, unarySymbolicValue); } }
private void executeUnaryExpression(Tree tree) { // consume one and produce one ProgramState.Pop unstackUnary = programState.unstackValue(1); programState = unstackUnary.state; SymbolicValue unarySymbolicValue = constraintManager.createSymbolicValue(tree); unarySymbolicValue.computedFrom(unstackUnary.values); if (tree.is(Tree.Kind.POSTFIX_DECREMENT, Tree.Kind.POSTFIX_INCREMENT, Tree.Kind.PREFIX_DECREMENT, Tree.Kind.PREFIX_INCREMENT) && ((UnaryExpressionTree) tree).expression().is(Tree.Kind.IDENTIFIER)) { programState = programState.put(((IdentifierTree) ((UnaryExpressionTree) tree).expression()).symbol(), unarySymbolicValue); } if(tree.is(Tree.Kind.POSTFIX_DECREMENT, Tree.Kind.POSTFIX_INCREMENT)) { programState = programState.stackValue(unstackUnary.values.get(0)); } else { programState = programState.stackValue(unarySymbolicValue); } }
private void executeAssignment(AssignmentExpressionTree tree) { ProgramState.Pop unstack; SymbolicValue value; if (tree.is(Tree.Kind.ASSIGNMENT)) { unstack = ExpressionUtils.isSimpleAssignment(tree) ? programState.unstackValue(1) : programState.unstackValue(2); value = unstack.values.get(0); } else { unstack = programState.unstackValue(2); value = constraintManager.createSymbolicValue(tree); } programState = unstack.state; Symbol symbol = null; if (tree.variable().is(Tree.Kind.IDENTIFIER) || ExpressionUtils.isSelectOnThisOrSuper(tree)) { symbol = ExpressionUtils.extractIdentifier(tree).symbol(); programState = programState.put(symbol, value); } programState = programState.stackValue(value, symbol); }
private void executeAssignment(AssignmentExpressionTree tree) { ProgramState.Pop unstack; SymbolicValue value; if (tree.is(Tree.Kind.ASSIGNMENT)) { unstack = ExpressionUtils.isSimpleAssignment(tree) ? programState.unstackValue(1) : programState.unstackValue(2); value = unstack.values.get(0); } else { unstack = programState.unstackValue(2); value = constraintManager.createSymbolicValue(tree); } programState = unstack.state; Symbol symbol = null; if (tree.variable().is(Tree.Kind.IDENTIFIER) || ExpressionUtils.isSelectOnThisOrSuper(tree)) { symbol = ExpressionUtils.extractIdentifier(tree).symbol(); programState = programState.put(symbol, value); } programState = programState.stackValue(value, symbol); }