11package it .unive .golisa .cfg .runtime .fmt ;
22
3+ import java .util .Set ;
4+
35import it .unive .golisa .cfg .VarArgsParameter ;
46import it .unive .golisa .cfg .type .GoStringType ;
57import it .unive .golisa .cfg .type .composite .GoSliceType ;
68import it .unive .lisa .analysis .AbstractState ;
79import it .unive .lisa .analysis .AnalysisState ;
810import it .unive .lisa .analysis .SemanticException ;
911import it .unive .lisa .analysis .StatementStore ;
12+ import it .unive .lisa .analysis .lattices .ExpressionSet ;
1013import it .unive .lisa .interprocedural .InterproceduralAnalysis ;
1114import it .unive .lisa .program .CodeUnit ;
1215import it .unive .lisa .program .cfg .CFG ;
1316import it .unive .lisa .program .cfg .CodeLocation ;
1417import it .unive .lisa .program .cfg .CodeMemberDescriptor ;
1518import it .unive .lisa .program .cfg .NativeCFG ;
1619import it .unive .lisa .program .cfg .Parameter ;
17- import it .unive .lisa .program .cfg .statement .BinaryExpression ;
1820import it .unive .lisa .program .cfg .statement .Expression ;
21+ import it .unive .lisa .program .cfg .statement .NaryExpression ;
1922import it .unive .lisa .program .cfg .statement .PluggableStatement ;
2023import it .unive .lisa .program .cfg .statement .Statement ;
2124import it .unive .lisa .symbolic .SymbolicExpression ;
2225import it .unive .lisa .symbolic .value .operator .binary .BinaryOperator ;
26+ import it .unive .lisa .symbolic .value .operator .unary .UnaryOperator ;
2327import it .unive .lisa .type .Type ;
2428import it .unive .lisa .type .TypeSystem ;
2529import it .unive .lisa .type .Untyped ;
26- import java .util .Set ;
2730
2831/**
2932 * func Sprintf(format string, a ...any) string.
@@ -50,7 +53,7 @@ public Sprintf(CodeLocation location, CodeUnit fmtUnit) {
5053 *
5154 * @author <a href="mailto:[email protected] ">Vincenzo Arceri</a> 5255 */
53- public static class SprintfImpl extends BinaryExpression implements PluggableStatement {
56+ public static class SprintfImpl extends NaryExpression implements PluggableStatement {
5457
5558 private Statement original ;
5659
@@ -75,7 +78,7 @@ protected int compareSameClassAndParams(Statement o) {
7578 * @return the pluggable statement
7679 */
7780 public static SprintfImpl build (CFG cfg , CodeLocation location , Expression ... params ) {
78- return new SprintfImpl (cfg , location , params [ 0 ], params [ 1 ] );
81+ return new SprintfImpl (cfg , location , params );
7982 }
8083
8184 /**
@@ -87,20 +90,35 @@ public static SprintfImpl build(CFG cfg, CodeLocation location, Expression... pa
8790 * @param left the left expression
8891 * @param right the right expression
8992 */
90- public SprintfImpl (CFG cfg , CodeLocation location , Expression left , Expression right ) {
91- super (cfg , location , "Sprintf" , GoStringType .INSTANCE , left , right );
93+ public SprintfImpl (CFG cfg , CodeLocation location , Expression [] exprs ) {
94+ super (cfg , location , "Sprintf" , GoStringType .INSTANCE , exprs );
9295 }
9396
97+
9498 @ Override
95- public <A extends AbstractState <A >> AnalysisState <A > fwdBinarySemantics (
96- InterproceduralAnalysis <A > interprocedural ,
97- AnalysisState <A > state ,
98- SymbolicExpression left ,
99- SymbolicExpression right ,
99+ public <A extends AbstractState <A >> AnalysisState <A > forwardSemanticsAux (
100+ InterproceduralAnalysis <A > interprocedural , AnalysisState <A > state , ExpressionSet [] params ,
100101 StatementStore <A > expressions ) throws SemanticException {
101-
102- return state .smallStepSemantics (new it .unive .lisa .symbolic .value .BinaryExpression (getStaticType (), left ,
103- right , SprintfOperator .INSTANCE , getLocation ()), original );
102+
103+ ExpressionSet p1 = params [0 ];
104+ AnalysisState <A > res = state .bottom ();
105+
106+ if (params .length > 1 ) {
107+ for (SymbolicExpression e1 : p1 ) {
108+ for (int i = 1 ; i < params .length ; i ++)
109+ for (SymbolicExpression e2 : params [i ])
110+ res = res .lub (state .smallStepSemantics (new it .unive .lisa .symbolic .value .BinaryExpression (getStaticType (), e1 ,
111+ e2 , SprintfOperator .INSTANCE , getLocation ()), original ));
112+ }
113+ } else {
114+ for (SymbolicExpression e1 : p1 ) {
115+ res = res .lub (state .smallStepSemantics (new it .unive .lisa .symbolic .value .UnaryExpression (getStaticType (),
116+ e1 , (UnaryOperator ) SprintfOperatorUnary .INSTANCE , getLocation ()), original ));
117+ }
118+ }
119+
120+ return res ;
121+
104122 }
105123 }
106124
@@ -129,4 +147,30 @@ public Set<Type> typeInference(TypeSystem types, Set<Type> left, Set<Type> right
129147 return Set .of (types .getStringType ());
130148 }
131149 }
132- }
150+
151+ /**
152+ * The Sprintf operator.
153+ *
154+ * @author <a href="mailto:[email protected] ">Vincenzo Arceri</a> 155+ */
156+ public static class SprintfOperatorUnary implements UnaryOperator {
157+
158+ /**
159+ * The singleton instance of this class.
160+ */
161+ public static final SprintfOperator INSTANCE = new SprintfOperator ();
162+
163+ private SprintfOperatorUnary () {
164+ }
165+
166+ @ Override
167+ public String toString () {
168+ return "SprintfOperatorUnary" ;
169+ }
170+
171+ @ Override
172+ public Set <Type > typeInference (TypeSystem types , Set <Type > argument ) {
173+ return Set .of (types .getStringType ());
174+ }
175+ }
176+ }
0 commit comments