From 9bb3171bc68c205bc07dda11517c34783baf221a Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Tue, 19 Mar 2024 14:59:47 +0100 Subject: [PATCH 01/34] substring domain --- lisa/.DS_Store | Bin 0 -> 8196 bytes .../lisa/analysis/string/SubstringDomain.java | 354 ++++++++++++++++++ lisa/lisa-imp/.DS_Store | Bin 0 -> 6148 bytes lisa/lisa-imp/src/.DS_Store | Bin 0 -> 6148 bytes lisa/lisa-imp/src/main/.DS_Store | Bin 0 -> 6148 bytes 5 files changed, 354 insertions(+) create mode 100644 lisa/.DS_Store create mode 100644 lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java create mode 100644 lisa/lisa-imp/.DS_Store create mode 100644 lisa/lisa-imp/src/.DS_Store create mode 100644 lisa/lisa-imp/src/main/.DS_Store diff --git a/lisa/.DS_Store b/lisa/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..181d650d381c209c4bbeb48d607f1d814a7e35dc GIT binary patch literal 8196 zcmeHML2uJA6n^f?nyMSL64Q1;io~@Wn;1~UrIc~tN)a3Ym1GHRXc|{dx-wOjas~ba ze}N;v1pW&r_-uzZP1fFENZ6JAoaBAa?)RSKK9`7CYwR2m?GcfIDrB{S=7J)gi<&Ei z6l2A{ub%2wGoTsxFBuT;2NPAu zW+G!H<*NgYOaUN^xGf9%$O9zCOk^{Wv62!Bn<{%?36v!%22*f6H-$Q6Gm){93QkPH zi6tYmBtv0xbl^;>POPb)@&SAl&eOz-2=q)UEaUSrV2IOZfeaTp=NsJ@W3rmZ$gxp-%jf{oO z`ME=0_ftl|vbTitOWo?XTRJcukW za7Pm0IWAOQz3>8uPg;B&IHAP0)dQn!lsnbk>GY^^uWmN(%1_NZ$F}!qv5PQ3Va?2rwZIwiY65}>cDG|p-TkaD!M`} zw0=fkgjia?hJYL+P?S4+aB6@sS`!K~?9vvlNw-Hbqy;uyix%ORM(;v@h-DFB1_&N} z_OYZnmdF4>wXk~e0>`U@T}_3hpf1J;kcxc0{|h#B(F|N30~>1SJ(2%EUVZ+5c@xwl zYX&p}f1CkUJZYb_FpS!o^W%wJ+eCeXDvHpHm6Q-PG98DM={V&44@2}#s0vIok+G7v RgQ9;3NE&pb8ThLV`~q2-G?4%R literal 0 HcmV?d00001 diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java new file mode 100644 index 000000000..df2f97e51 --- /dev/null +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -0,0 +1,354 @@ +package it.unive.lisa.analysis.string; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import it.unive.lisa.analysis.ScopeToken; +import it.unive.lisa.analysis.SemanticException; +import it.unive.lisa.analysis.SemanticOracle; +import it.unive.lisa.analysis.lattices.ExpressionInverseSet; +import it.unive.lisa.analysis.lattices.FunctionalLattice; +import it.unive.lisa.analysis.lattices.Satisfiability; +import it.unive.lisa.analysis.value.ValueDomain; +import it.unive.lisa.program.cfg.ProgramPoint; +import it.unive.lisa.symbolic.SymbolicExpression; +import it.unive.lisa.symbolic.value.BinaryExpression; +import it.unive.lisa.symbolic.value.Identifier; +import it.unive.lisa.symbolic.value.ValueExpression; +import it.unive.lisa.symbolic.value.operator.binary.BinaryOperator; +import it.unive.lisa.symbolic.value.operator.binary.LogicalAnd; +import it.unive.lisa.symbolic.value.operator.binary.LogicalOr; +import it.unive.lisa.symbolic.value.operator.binary.StringConcat; +import it.unive.lisa.symbolic.value.operator.binary.StringContains; +import it.unive.lisa.symbolic.value.operator.binary.StringEquals; + +public class SubstringDomain extends FunctionalLattice implements ValueDomain { + + public SubstringDomain(ExpressionInverseSet lattice, Map function) { + super(lattice, function); + } + + public SubstringDomain(ExpressionInverseSet lattice) { + super(lattice); + } + + @Override + public SubstringDomain top() { + return isTop() ? this : new SubstringDomain(lattice.top()); + } + + @Override + public SubstringDomain bottom() { + return isBottom() ? this : new SubstringDomain(lattice.bottom()); + } + + @Override + public ExpressionInverseSet stateOfUnknown(Identifier key) { + return new ExpressionInverseSet(); + } + + @Override + public SubstringDomain mk(ExpressionInverseSet lattice, Map function) { + return new SubstringDomain(lattice, function); + } + + @Override + public SubstringDomain assign(Identifier id, ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) + throws SemanticException { + if (isBottom()) + return this; + + Set identifiers = extrPlus(expression); + + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); + + result.remove(identifiers, id); + + result.add(identifiers, id); + + result.interasg(id); + + result.closure(id); + + return result; + } + + @Override + public SubstringDomain smallStepSemantics(ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) + throws SemanticException { + return this; + } + + @Override + public SubstringDomain assume(ValueExpression expression, ProgramPoint src, ProgramPoint dest, + SemanticOracle oracle) throws SemanticException { + if (isBottom()) + return this; + + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); + + if (expression instanceof BinaryExpression) { + + BinaryExpression binaryExpression = (BinaryExpression) expression; + BinaryOperator binaryOperator = binaryExpression.getOperator(); + + SymbolicExpression left = binaryExpression.getLeft(); + SymbolicExpression right = binaryExpression.getRight(); + + if (binaryOperator instanceof StringContains) { + + if (!(left instanceof Identifier)) + return this; + + if (!(right instanceof ValueExpression)) + throw new SemanticException("instanceof right"); + + + Set add = extrPlus((ValueExpression) right); + + result.add(add, (Identifier) left); + + result.closure((Identifier) left); + + } else if (binaryOperator instanceof StringEquals){ + //both are identifiers + if ((left instanceof Identifier) && (right instanceof Identifier)) { + result.add(extrPlus((ValueExpression) left), (Identifier) right); + result.add(extrPlus((ValueExpression) right), (Identifier)left); + + result.closure((Identifier) left); + result.closure((Identifier) right); + } //one is identifier + else if((left instanceof Identifier) || (right instanceof Identifier)) { + + if (right instanceof Identifier) { //left instance of Identifier, right SymbolicExpression + SymbolicExpression temp = left; + left = right; + right = temp; + } + + if (!(right instanceof ValueExpression)) + throw new SemanticException("instanceof right != ValueExpression.class"); + + Set add = extrPlus((ValueExpression) right); + + result.add(add, (Identifier) left); + + result.closure((Identifier) left); + } + } else if(binaryOperator instanceof LogicalOr || binaryOperator instanceof LogicalAnd){ + + if (!(left instanceof ValueExpression) || !(right instanceof ValueExpression)) + throw new SemanticException("!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); + + ValueExpression rightValueExpression = (ValueExpression) right; + ValueExpression leftValueExpression = (ValueExpression) left; + + SubstringDomain leftDomain = assume(leftValueExpression, src, dest, oracle); + SubstringDomain rightDomain = assume(rightValueExpression, src, dest, oracle); + + if (binaryOperator instanceof LogicalOr) { + result = glb(leftDomain.glb(rightDomain)); + } else { + result = glb(leftDomain.lub(rightDomain)); + } + } + + } + + return result; + } + + @Override + public boolean knowsIdentifier(Identifier id) { + if (id == null || function == null || isBottom() || isTop()) + return false; + + if (function.containsKey(id)) + return true; + + return false; + } + + @Override + public SubstringDomain forgetIdentifier(Identifier id) throws SemanticException { + if (!knowsIdentifier(id)) + return this; + + Map newFunction = mkNewFunction(function, false); //function != null + + newFunction.remove(id); + + return new SubstringDomain(lattice, newFunction); + } + + @Override + public SubstringDomain forgetIdentifiersIf(Predicate test) throws SemanticException { + if (function == null || isTop() || isBottom() || function.keySet().isEmpty()) + return this; + + Map newFunction = mkNewFunction(function, false); //function != null + + Set keys = newFunction.keySet().stream().filter(test::test).collect(Collectors.toSet()); + + keys.forEach(newFunction::remove); + + return new SubstringDomain(lattice, newFunction); + } + + @Override + public Satisfiability satisfies(ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) + throws SemanticException { + if (isBottom()) + return Satisfiability.BOTTOM; + + if (expression instanceof BinaryExpression) { + BinaryExpression binaryExpression = (BinaryExpression) expression; + BinaryOperator binaryOperator = binaryExpression.getOperator(); + + SymbolicExpression left = binaryExpression.getLeft(); + SymbolicExpression right = binaryExpression.getRight(); + + if (binaryOperator instanceof StringContains) { + if (!(left instanceof Identifier)) + return Satisfiability.UNKNOWN; + + return function.get((Identifier) left).contains(right) ? Satisfiability.SATISFIED : Satisfiability.UNKNOWN; + } else if (binaryOperator instanceof StringEquals) { + if (!(left instanceof Identifier) || !(right instanceof Identifier)) + return Satisfiability.UNKNOWN; + + return (function.get((Identifier) left).contains(right)) && (function.get((Identifier) right).contains(left)) + ? Satisfiability.SATISFIED + : Satisfiability.UNKNOWN; + } + } + + return Satisfiability.UNKNOWN; + } + + @Override + public SubstringDomain pushScope(ScopeToken token) throws SemanticException { + return new SubstringDomain(lattice.pushScope(token), mkNewFunction(function, true)); + } + + @Override + public SubstringDomain popScope(ScopeToken token) throws SemanticException { + return new SubstringDomain(lattice.popScope(token), mkNewFunction(function, true)); + } + + private Set extr(ValueExpression expression) throws SemanticException{ + if (isBottom()) + return null; + + Set result = Collections.emptySet(); + if (expression instanceof BinaryExpression) { + BinaryExpression binaryExpression = (BinaryExpression) expression; + BinaryOperator binaryOperator = binaryExpression.getOperator(); + if (!(binaryOperator instanceof StringConcat)) + throw new SemanticException(); + + ValueExpression left = (ValueExpression) binaryExpression.getLeft(); + ValueExpression right = (ValueExpression) binaryExpression.getRight(); + + result.addAll(extr(left)); + result.addAll(extr(right)); + } else if(expression instanceof Identifier) { + Identifier identifier = (Identifier) expression; + + result.add(identifier); + } else { + throw new SemanticException("typeof expression"); + } + + return result; + } + + private Set extrPlus(ValueExpression expression) throws SemanticException{ + if (isBottom()) + return null; + + Set result = extr(expression); + + return result; + } + + + private void add(Set symbolicExpressions, Identifier id) throws SemanticException{ + if (isBottom()) + return; + + ExpressionInverseSet newSet = function.get(id).glb(new ExpressionInverseSet(symbolicExpressions)); + + function.put(id, newSet); + } + + private void remove(Set expresionsToRemove, Identifier id) { + if(isBottom()) + return; + + if(!expresionsToRemove.contains(id)) { // x = x + ..... --> keep relations for x + function.remove(id); + } + + for (Map.Entry entry : function.entrySet()) { + for(SymbolicExpression se : expresionsToRemove) { + Set set = entry.getValue().elements(); + + set.remove(se); + } + } + } + + private void interasg(Identifier id) { + if (isBottom()) + return; + + Set keys = getKeys(); + keys.remove(id); + + ExpressionInverseSet eiv = function.get(id); + Set iterate = eiv.mk(function.get(id).elements()).elements(); + + + for (Identifier key : keys) { + boolean contained = true; + for (SymbolicExpression symbolicExpression : iterate) { + if (!function.get(key).contains(symbolicExpression)) { + contained = false; + break; + } + } + + if (contained) { + ExpressionInverseSet set = function.get(key); + set.elements.add(id); + } + + } + } + + private void closure(Identifier id) { + if (isBottom()) + return; + + ExpressionInverseSet toModify = function.get(id); + Set setToModify = toModify.elements(); + Set iterate = toModify.mk(setToModify).elements(); + + do { + for (SymbolicExpression se : iterate) { + if (se instanceof Identifier) { + Identifier variable = (Identifier) se; + + setToModify.addAll(function.get(variable).elements()); + } + } + } while(iterate.equals(setToModify)); + + } + +} diff --git a/lisa/lisa-imp/.DS_Store b/lisa/lisa-imp/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1df778ff6746409186585b8b9a73d97cb06d5d53 GIT binary patch literal 6148 zcmeHK!H&}~6nt*GG^MQQ0R$JMNLInq#LBFQm?>2 z@CzLI68INRFwb^HlU+C=gpi+P&$B%f$5X|wiAap+(H_x&h#VBg&UsX41dnq$6)n@# z2MT_MoQA0k(c;J1unt%U{&ffV+ig=w31yGc+V^`OBRk(!s6}jnH3u)HsKNZyU|#si zq#Zh)mC^YaO z-@NyD@+Ljb}R~psUfl6HgfE{$JK(7A$16}R_dInb-(Ss0L3e-|zt{B4H9fX!++%x=@ zMlC0yX2x^O%);DIgt>YMSJ6p$8f|SIunyE6XzS*H&;N(NzW>)nwq+f#4*XXRh|ZyZ zIL4C9*?MYmeAc=suTVIcx6-I2sLXM!5*cCZ$7FDJ%R8BY(p0 zz@2R>C@_Km-AU(XpYQDWIkJ5KAR2>q6`%wFHY#DRh{Y#D{iGixXDk+?pfL_2c^O19 zz%~uY^7|Q}y|bVTK7DMW@Za^!Jf0v zy=yu2Qa>Fe4ZnX%ts^O;;I-}t$6;sKDlP2EIQ7H0(^mmuyMr!gCt=){!-gEh?L@_T zy2CEo#a3x)G^*CO%1(V_Ty{p=wOZNPtgny9MSF2&ZRfCc6Ln*Gr&KCduh2&R7NpRD1kx!w9js3suk$8OUTM$*9E}=rY>o#EfC@ui6bp~ z7E6QJgC-0W(NKlGVhBUWc4_lGi={zB2VpNC!j3HL4MphD@%d7xgYXP;$qKLn>k3p& zwMFOu+rQuc*GXJs1z3RxrGTjQgT9ZSWY5-(kE63zqF Date: Wed, 20 Mar 2024 10:49:07 +0100 Subject: [PATCH 02/34] Removed .DS_Store files --- lisa/.DS_Store | Bin 8196 -> 0 bytes lisa/lisa-imp/.DS_Store | Bin 6148 -> 0 bytes lisa/lisa-imp/src/.DS_Store | Bin 6148 -> 0 bytes lisa/lisa-imp/src/main/.DS_Store | Bin 6148 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 lisa/.DS_Store delete mode 100644 lisa/lisa-imp/.DS_Store delete mode 100644 lisa/lisa-imp/src/.DS_Store delete mode 100644 lisa/lisa-imp/src/main/.DS_Store diff --git a/lisa/.DS_Store b/lisa/.DS_Store deleted file mode 100644 index 181d650d381c209c4bbeb48d607f1d814a7e35dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHML2uJA6n^f?nyMSL64Q1;io~@Wn;1~UrIc~tN)a3Ym1GHRXc|{dx-wOjas~ba ze}N;v1pW&r_-uzZP1fFENZ6JAoaBAa?)RSKK9`7CYwR2m?GcfIDrB{S=7J)gi<&Ei z6l2A{ub%2wGoTsxFBuT;2NPAu zW+G!H<*NgYOaUN^xGf9%$O9zCOk^{Wv62!Bn<{%?36v!%22*f6H-$Q6Gm){93QkPH zi6tYmBtv0xbl^;>POPb)@&SAl&eOz-2=q)UEaUSrV2IOZfeaTp=NsJ@W3rmZ$gxp-%jf{oO z`ME=0_ftl|vbTitOWo?XTRJcukW za7Pm0IWAOQz3>8uPg;B&IHAP0)dQn!lsnbk>GY^^uWmN(%1_NZ$F}!qv5PQ3Va?2rwZIwiY65}>cDG|p-TkaD!M`} zw0=fkgjia?hJYL+P?S4+aB6@sS`!K~?9vvlNw-Hbqy;uyix%ORM(;v@h-DFB1_&N} z_OYZnmdF4>wXk~e0>`U@T}_3hpf1J;kcxc0{|h#B(F|N30~>1SJ(2%EUVZ+5c@xwl zYX&p}f1CkUJZYb_FpS!o^W%wJ+eCeXDvHpHm6Q-PG98DM={V&44@2}#s0vIok+G7v RgQ9;3NE&pb8ThLV`~q2-G?4%R diff --git a/lisa/lisa-imp/.DS_Store b/lisa/lisa-imp/.DS_Store deleted file mode 100644 index 1df778ff6746409186585b8b9a73d97cb06d5d53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!H&}~6nt*GG^MQQ0R$JMNLInq#LBFQm?>2 z@CzLI68INRFwb^HlU+C=gpi+P&$B%f$5X|wiAap+(H_x&h#VBg&UsX41dnq$6)n@# z2MT_MoQA0k(c;J1unt%U{&ffV+ig=w31yGc+V^`OBRk(!s6}jnH3u)HsKNZyU|#si zq#Zh)mC^YaO z-@NyD@+Ljb}R~psUfl6HgfE{$JK(7A$16}R_dInb-(Ss0L3e-|zt{B4H9fX!++%x=@ zMlC0yX2x^O%);DIgt>YMSJ6p$8f|SIunyE6XzS*H&;N(NzW>)nwq+f#4*XXRh|ZyZ zIL4C9*?MYmeAc=suTVIcx6-I2sLXM!5*cCZ$7FDJ%R8BY(p0 zz@2R>C@_Km-AU(XpYQDWIkJ5KAR2>q6`%wFHY#DRh{Y#D{iGixXDk+?pfL_2c^O19 zz%~uY^7|Q}y|bVTK7DMW@Za^!Jf0v zy=yu2Qa>Fe4ZnX%ts^O;;I-}t$6;sKDlP2EIQ7H0(^mmuyMr!gCt=){!-gEh?L@_T zy2CEo#a3x)G^*CO%1(V_Ty{p=wOZNPtgny9MSF2&ZRfCc6Ln*Gr&KCduh2&R7NpRD1kx!w9js3suk$8OUTM$*9E}=rY>o#EfC@ui6bp~ z7E6QJgC-0W(NKlGVhBUWc4_lGi={zB2VpNC!j3HL4MphD@%d7xgYXP;$qKLn>k3p& zwMFOu+rQuc*GXJs1z3RxrGTjQgT9ZSWY5-(kE63zqF Date: Wed, 27 Mar 2024 15:03:52 +0100 Subject: [PATCH 03/34] tests --- .gitignore | 3 + .../imp-testcases/string/strings.imp | 30 +- .../lisa/analysis/string/SubstringDomain.java | 367 +++++++--- .../analysis/string/SubstringDomainTest.java | 643 ++++++++++++++++++ .../unive/lisa/cron/StringAnalysesTest.java | 19 + .../lattices/ExpressionInverseSet.java | 37 +- 6 files changed, 992 insertions(+), 107 deletions(-) create mode 100644 .gitignore create mode 100644 lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ee2afad00 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.metadata/ +/.metadata/ +.DS_Store diff --git a/lisa/lisa-analyses/imp-testcases/string/strings.imp b/lisa/lisa-analyses/imp-testcases/string/strings.imp index c5ef46d87..060c99e32 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings.imp @@ -1,5 +1,24 @@ class strings { + closure() { + def y = "a"; + def z = y; + } + + closure2(x) { + def j = "j"; + def w = j; + def y = x; + x = w; + + } + + assign() { + def j = "string"; + def x = "a" + j; + def y = "a"; + } + constants() { def a = "abc"; def b = "def"; @@ -13,8 +32,17 @@ class strings { a = "world"; } + assume(x) { + def b = "abc"; + if (strcon(x, b)) + b = "hello"; + else + b = b + "hello"; + + } + loops(x) { - def str = "a"; + def str = "b"; while (x < 100) { str = str + "a"; } diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index df2f97e51..69f6041e1 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -1,6 +1,6 @@ package it.unive.lisa.analysis.string; -import java.util.Collections; +import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.function.Predicate; @@ -16,14 +16,18 @@ import it.unive.lisa.program.cfg.ProgramPoint; import it.unive.lisa.symbolic.SymbolicExpression; import it.unive.lisa.symbolic.value.BinaryExpression; +import it.unive.lisa.symbolic.value.Constant; import it.unive.lisa.symbolic.value.Identifier; import it.unive.lisa.symbolic.value.ValueExpression; +import it.unive.lisa.symbolic.value.Variable; import it.unive.lisa.symbolic.value.operator.binary.BinaryOperator; import it.unive.lisa.symbolic.value.operator.binary.LogicalAnd; import it.unive.lisa.symbolic.value.operator.binary.LogicalOr; import it.unive.lisa.symbolic.value.operator.binary.StringConcat; import it.unive.lisa.symbolic.value.operator.binary.StringContains; +import it.unive.lisa.symbolic.value.operator.binary.StringEndsWith; import it.unive.lisa.symbolic.value.operator.binary.StringEquals; +import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; public class SubstringDomain extends FunctionalLattice implements ValueDomain { @@ -34,6 +38,74 @@ public SubstringDomain(ExpressionInverseSet lattice, Map newFunction = mkNewFunction(null, false); + + for(Map.Entry entry : other) { + ExpressionInverseSet newSet = getState(entry.getKey()); + newFunction.put(entry.getKey(), newSet.lub(entry.getValue())); + } + + SubstringDomain result = mk(lattice, newFunction); + + return result.clear(); + } + + @Override + public SubstringDomain glb(SubstringDomain other) throws SemanticException{ + if (other == null) + throw new SemanticException("other == null"); + + if (this == other || this.equals(other)) + return this; + + if (isTop() || this.isBottom()) + return other; + + if (other.isTop() || other.isBottom()) + return this; + + return glbAux(other); + } + + @Override + public SubstringDomain glbAux(SubstringDomain other) throws SemanticException { + Map newFunction = mkNewFunction(this.function, false); + + for(Map.Entry entry : other) { + ExpressionInverseSet newSet = getState(entry.getKey()).glb(entry.getValue()); + newFunction.put(entry.getKey(), newSet); + } + + SubstringDomain result = mk(lattice, newFunction); + + return result.closure(); + + } @Override public SubstringDomain top() { @@ -58,22 +130,19 @@ public SubstringDomain mk(ExpressionInverseSet lattice, Map identifiers = extrPlus(expression); SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - result.remove(identifiers, id); + result = result.remove(identifiers, id); - result.add(identifiers, id); + result = result.add(identifiers, id); - result.interasg(id); + result = result.interasg(id); - result.closure(id); + result = result.closure(id); - return result; + return result.clear(); } @Override @@ -85,8 +154,6 @@ public SubstringDomain smallStepSemantics(ValueExpression expression, ProgramPoi @Override public SubstringDomain assume(ValueExpression expression, ProgramPoint src, ProgramPoint dest, SemanticOracle oracle) throws SemanticException { - if (isBottom()) - return this; SubstringDomain result = mk(lattice, mkNewFunction(function, false)); @@ -98,29 +165,31 @@ public SubstringDomain assume(ValueExpression expression, ProgramPoint src, Prog SymbolicExpression left = binaryExpression.getLeft(); SymbolicExpression right = binaryExpression.getRight(); - if (binaryOperator instanceof StringContains) { + if (binaryOperator instanceof StringContains + || binaryOperator instanceof StringStartsWith + || binaryOperator instanceof StringEndsWith) { if (!(left instanceof Identifier)) return this; if (!(right instanceof ValueExpression)) throw new SemanticException("instanceof right"); - - Set add = extrPlus((ValueExpression) right); + Set extracted = extrPlus((ValueExpression) right); - result.add(add, (Identifier) left); + result = result.add(extracted, (Identifier) left); - result.closure((Identifier) left); + //result = result.closure((Identifier) left); + result = result.closure(); } else if (binaryOperator instanceof StringEquals){ //both are identifiers if ((left instanceof Identifier) && (right instanceof Identifier)) { - result.add(extrPlus((ValueExpression) left), (Identifier) right); - result.add(extrPlus((ValueExpression) right), (Identifier)left); + result = result.add(extrPlus((ValueExpression) left), (Identifier) right); + result = result.add(extrPlus((ValueExpression) right), (Identifier)left); - result.closure((Identifier) left); - result.closure((Identifier) right); + result = result.closure((Identifier) left); + result = result.closure((Identifier) right); } //one is identifier else if((left instanceof Identifier) || (right instanceof Identifier)) { @@ -135,9 +204,11 @@ else if((left instanceof Identifier) || (right instanceof Identifier)) { Set add = extrPlus((ValueExpression) right); - result.add(add, (Identifier) left); + result = result.add(add, (Identifier) left); - result.closure((Identifier) left); + //result = result.closure((Identifier) left); + result = result.closure(); + } } else if(binaryOperator instanceof LogicalOr || binaryOperator instanceof LogicalAnd){ @@ -151,15 +222,15 @@ else if((left instanceof Identifier) || (right instanceof Identifier)) { SubstringDomain rightDomain = assume(rightValueExpression, src, dest, oracle); if (binaryOperator instanceof LogicalOr) { - result = glb(leftDomain.glb(rightDomain)); + result = leftDomain.glb(rightDomain); } else { - result = glb(leftDomain.lub(rightDomain)); + result = leftDomain.lub(rightDomain); } - } + } } - return result; + return result.clear(); } @Override @@ -202,32 +273,53 @@ public SubstringDomain forgetIdentifiersIf(Predicate test) throws Se @Override public Satisfiability satisfies(ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) throws SemanticException { - if (isBottom()) - return Satisfiability.BOTTOM; + if (isBottom() || !(expression instanceof BinaryExpression)) + return Satisfiability.UNKNOWN; - if (expression instanceof BinaryExpression) { - BinaryExpression binaryExpression = (BinaryExpression) expression; - BinaryOperator binaryOperator = binaryExpression.getOperator(); + + BinaryExpression binaryExpression = (BinaryExpression) expression; + BinaryOperator binaryOperator = binaryExpression.getOperator(); + + SymbolicExpression left = binaryExpression.getLeft(); + SymbolicExpression right = binaryExpression.getRight(); + + if (binaryOperator instanceof StringContains) { + if (!(left instanceof Variable)) + return Satisfiability.UNKNOWN; - SymbolicExpression left = binaryExpression.getLeft(); - SymbolicExpression right = binaryExpression.getRight(); + return getState((Identifier) left).contains(right) ? Satisfiability.SATISFIED : Satisfiability.UNKNOWN; + } else if (binaryOperator instanceof StringEquals || binaryOperator instanceof StringEndsWith || binaryOperator instanceof StringStartsWith) { + if (!(left instanceof Variable) || !(right instanceof Variable)) + return Satisfiability.UNKNOWN; - if (binaryOperator instanceof StringContains) { - if (!(left instanceof Identifier)) - return Satisfiability.UNKNOWN; - - return function.get((Identifier) left).contains(right) ? Satisfiability.SATISFIED : Satisfiability.UNKNOWN; - } else if (binaryOperator instanceof StringEquals) { - if (!(left instanceof Identifier) || !(right instanceof Identifier)) - return Satisfiability.UNKNOWN; - - return (function.get((Identifier) left).contains(right)) && (function.get((Identifier) right).contains(left)) - ? Satisfiability.SATISFIED - : Satisfiability.UNKNOWN; - } + return (getState((Identifier) left).contains(right)) && (getState((Identifier) right).contains(left)) + ? Satisfiability.SATISFIED + : Satisfiability.UNKNOWN; + } else if (binaryOperator instanceof LogicalOr) { + if (!(left instanceof ValueExpression) || !(right instanceof ValueExpression)) + throw new SemanticException("!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); + Satisfiability leftSatisfiability = satisfies((ValueExpression) left, pp, oracle); + + if (leftSatisfiability == Satisfiability.SATISFIED) + return Satisfiability.SATISFIED; + + Satisfiability rightSatisfiability = satisfies((ValueExpression) right, pp, oracle); + + return rightSatisfiability; + + } else if (binaryOperator instanceof LogicalAnd) { + if (!(left instanceof ValueExpression) || !(right instanceof ValueExpression)) + throw new SemanticException("!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); + Satisfiability leftSatisfiability = satisfies((ValueExpression) left, pp, oracle); + Satisfiability rightSatisfiability = satisfies((ValueExpression) right, pp, oracle); + + if (leftSatisfiability == Satisfiability.SATISFIED && rightSatisfiability == Satisfiability.SATISFIED) + return Satisfiability.SATISFIED; + else + return Satisfiability.UNKNOWN; } - return Satisfiability.UNKNOWN; + throw new SemanticException("Invalid expression"); } @Override @@ -240,11 +332,9 @@ public SubstringDomain popScope(ScopeToken token) throws SemanticException { return new SubstringDomain(lattice.popScope(token), mkNewFunction(function, true)); } - private Set extr(ValueExpression expression) throws SemanticException{ - if (isBottom()) - return null; + private static Set extr(ValueExpression expression) throws SemanticException{ - Set result = Collections.emptySet(); + Set result = new HashSet<>(); if (expression instanceof BinaryExpression) { BinaryExpression binaryExpression = (BinaryExpression) expression; BinaryOperator binaryOperator = binaryExpression.getOperator(); @@ -256,99 +346,166 @@ private Set extr(ValueExpression expression) throws Semantic result.addAll(extr(left)); result.addAll(extr(right)); - } else if(expression instanceof Identifier) { - Identifier identifier = (Identifier) expression; - - result.add(identifier); - } else { - throw new SemanticException("typeof expression"); - } + } else if(expression instanceof Variable || expression instanceof Constant) { + result.add(expression); + } return result; } - private Set extrPlus(ValueExpression expression) throws SemanticException{ - if (isBottom()) - return null; - + private static Set extrPlus(ValueExpression expression) throws SemanticException{ Set result = extr(expression); return result; } - private void add(Set symbolicExpressions, Identifier id) throws SemanticException{ - if (isBottom()) - return; + private SubstringDomain add(Set symbolicExpressions, Identifier id) throws SemanticException{ + + Map newFunction = mkNewFunction(function, false); - ExpressionInverseSet newSet = function.get(id).glb(new ExpressionInverseSet(symbolicExpressions)); + symbolicExpressions.remove(id); - function.put(id, newSet); + ExpressionInverseSet newSet = new ExpressionInverseSet(symbolicExpressions); + + if (!(newFunction.get(id) == null)) + newSet = newSet.glb(newFunction.get(id)); + + newFunction.put(id, newSet); + + return mk(lattice, newFunction); } - private void remove(Set expresionsToRemove, Identifier id) { - if(isBottom()) - return; + private SubstringDomain remove(Set extracted, Identifier id) throws SemanticException { + + Map newFunction = mkNewFunction(function, false); - if(!expresionsToRemove.contains(id)) { // x = x + ..... --> keep relations for x - function.remove(id); + if(!extracted.contains(id)) { // x = x + ..... --> keep relations for x + newFunction.remove(id); } - for (Map.Entry entry : function.entrySet()) { - for(SymbolicExpression se : expresionsToRemove) { + Set expressionsToRemove = new HashSet<>(); + for (SymbolicExpression expression : extracted) { + if (appears(id, expression)) + expressionsToRemove.add(expression); + } + + expressionsToRemove.add(id); + + for (Map.Entry entry : newFunction.entrySet()) { + for(SymbolicExpression se : expressionsToRemove) { Set set = entry.getValue().elements(); set.remove(se); } } + + return mk(lattice, newFunction); } - private void interasg(Identifier id) { - if (isBottom()) - return; + private SubstringDomain interasg(Identifier id) throws SemanticException { + Map newFunction = mkNewFunction(function, false); - Set keys = getKeys(); - keys.remove(id); + ExpressionInverseSet compare = function.get(id); + + for (Map.Entry entry : function.entrySet()) { + if (entry.getKey().equals(id)) + continue; + + if ((entry.getValue().lub(compare)).equals(compare)) { + Set newRelation = new HashSet<>(); + newRelation.add(id); + + ExpressionInverseSet newSet = newFunction.get(entry.getKey()).glb(new ExpressionInverseSet(newRelation)); + newFunction.put(entry.getKey(), newSet); + } + + } + + return mk(lattice, newFunction); + } + + private SubstringDomain closure(Identifier id) throws SemanticException { + + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - ExpressionInverseSet eiv = function.get(id); - Set iterate = eiv.mk(function.get(id).elements()).elements(); + ExpressionInverseSet toModify; + ExpressionInverseSet iterate; + do { + toModify = result.getState(id); + iterate = toModify.mk(toModify.elements); - for (Identifier key : keys) { - boolean contained = true; - for (SymbolicExpression symbolicExpression : iterate) { - if (!function.get(key).contains(symbolicExpression)) { - contained = false; - break; + for (SymbolicExpression se : toModify) { + if (se instanceof Variable) { + Variable variable = (Variable) se; + + if (result.knowsIdentifier(variable)) { + Set add = new HashSet<>(result.getState(variable).elements); + result = result.add(add , id); + } } } + } while(!iterate.equals(toModify)); + + return result; + } + + private SubstringDomain closure() throws SemanticException { + + SubstringDomain prev; + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); + + + do { + prev = mk(lattice, mkNewFunction(result.function, false)); + Set set = prev.function.keySet(); - if (contained) { - ExpressionInverseSet set = function.get(key); - set.elements.add(id); + for(Identifier id : set) { + result = result.closure(id); } + result = result.clear(); + }while(!prev.equals(result)); + + + return result; + + } + + private SubstringDomain clear() throws SemanticException { + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); + + Map iterate = mkNewFunction(result.function, false); + for (Map.Entry entry : iterate.entrySet() ) { + if (entry.getValue().isBottom()) { + result = result.forgetIdentifier(entry.getKey()); + } + } + + return result; } - private void closure(Identifier id) { - if (isBottom()) - return; + private static boolean appears(Identifier id, SymbolicExpression expr) throws SemanticException { + if (expr instanceof Identifier) + return id.equals(expr); - ExpressionInverseSet toModify = function.get(id); - Set setToModify = toModify.elements(); - Set iterate = toModify.mk(setToModify).elements(); + if (expr instanceof Constant) + return false; - do { - for (SymbolicExpression se : iterate) { - if (se instanceof Identifier) { - Identifier variable = (Identifier) se; - - setToModify.addAll(function.get(variable).elements()); - } - } - } while(iterate.equals(setToModify)); + if (expr instanceof BinaryExpression) { + BinaryExpression expression = (BinaryExpression) expr; + SymbolicExpression left = expression.getLeft(); + SymbolicExpression right = expression.getRight(); + return appears(id, left) || appears(id, right); + } + + throw new SemanticException("Invalid expression"); + + + } } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java new file mode 100644 index 000000000..53ef10d01 --- /dev/null +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -0,0 +1,643 @@ +package it.unive.lisa.analysis.string; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; + +import it.unive.lisa.analysis.SemanticException; +import it.unive.lisa.analysis.lattices.ExpressionInverseSet; +import it.unive.lisa.analysis.lattices.Satisfiability; +import it.unive.lisa.program.SyntheticLocation; +import it.unive.lisa.program.type.BoolType; +import it.unive.lisa.program.type.StringType; +import it.unive.lisa.symbolic.SymbolicExpression; +import it.unive.lisa.symbolic.value.BinaryExpression; +import it.unive.lisa.symbolic.value.Constant; +import it.unive.lisa.symbolic.value.Identifier; +import it.unive.lisa.symbolic.value.ValueExpression; +import it.unive.lisa.symbolic.value.Variable; +import it.unive.lisa.symbolic.value.operator.binary.LogicalAnd; +import it.unive.lisa.symbolic.value.operator.binary.LogicalOr; +import it.unive.lisa.symbolic.value.operator.binary.StringConcat; +import it.unive.lisa.symbolic.value.operator.binary.StringContains; +import it.unive.lisa.symbolic.value.operator.binary.StringEndsWith; +import it.unive.lisa.symbolic.value.operator.binary.StringEquals; +import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; + +public class SubstringDomainTest { + + Identifier y = new Variable(StringType.INSTANCE, "y", SyntheticLocation.INSTANCE); + Identifier x = new Variable(StringType.INSTANCE, "x", SyntheticLocation.INSTANCE); + Identifier z = new Variable(StringType.INSTANCE, "z", SyntheticLocation.INSTANCE); + Identifier w = new Variable(StringType.INSTANCE, "w", SyntheticLocation.INSTANCE); + + ValueExpression c = new Constant(StringType.INSTANCE, "c", SyntheticLocation.INSTANCE); + + SubstringDomain domainA; + SubstringDomain domainB; + + SubstringDomain domainC; + SubstringDomain domainD; + + SubstringDomain domainE; + + SubstringDomain domainF; + + SubstringDomain TOP; + SubstringDomain BOTTOM; + + ValueExpression XEqualsY = new BinaryExpression(BoolType.INSTANCE, x, y, StringEquals.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XEqualsW = new BinaryExpression(BoolType.INSTANCE, x, w, StringEquals.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression YSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, y, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression WSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, w, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XStartsWithY = new BinaryExpression(BoolType.INSTANCE, x, y, StringStartsWith.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XStartsWithW = new BinaryExpression(BoolType.INSTANCE, x, w, StringStartsWith.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XEndsWithY = new BinaryExpression(BoolType.INSTANCE, x, y, StringEndsWith.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XEndsWithW = new BinaryExpression(BoolType.INSTANCE, x, w, StringEndsWith.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression invalid = new BinaryExpression(StringType.INSTANCE, x, XEqualsY, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression XConcatY = new BinaryExpression(StringType.INSTANCE, x, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression ZConcatX = new BinaryExpression(StringType.INSTANCE, z, x, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression ZConcatXConcatY = new BinaryExpression(StringType.INSTANCE, z, XConcatY, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression CSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, c, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XSubstringOfC = new BinaryExpression(BoolType.INSTANCE, c, x, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + + + public SubstringDomainTest() { + Map mapA = new HashMap<>(); + Set setA = new HashSet<>(); + setA.add(y); + setA.add(w); + mapA.put(x, new ExpressionInverseSet(setA)); + + Map mapB = new HashMap<>(); + Set setB = new HashSet<>(); + Set setB2 = new HashSet<>(); + setB.add(z); + setB2.add(w); + mapB.put(y, new ExpressionInverseSet(setB)); + mapB.put(x, new ExpressionInverseSet(setB2)); + + Map mapC = new HashMap<>(); + Set setC = new HashSet<>(); + setC.add(z); + mapC.put(x, new ExpressionInverseSet(setC)); + + Map mapD = new HashMap<>(); + Set setD = new HashSet<>(); + setD.add(w); + mapD.put(y, new ExpressionInverseSet(setD)); + + Map mapE = new HashMap<>(); + Set setE1 = new HashSet<>(); + Set setE2 = new HashSet<>(); + setE1.add(y); + setE2.add(x); + mapE.put(x, new ExpressionInverseSet(setE1)); + mapE.put(y, new ExpressionInverseSet(setE2)); + + Map mapF = new HashMap<>(); + Set setF1 = new HashSet<>(); + Set setF2 = new HashSet<>(); + setF1.add(y); + setF1.add(c); + setF2.add(z); + mapF.put(x, new ExpressionInverseSet(setF1)); + mapF.put(w, new ExpressionInverseSet(setF2)); + + domainA = new SubstringDomain(new ExpressionInverseSet(), mapA); + domainB = new SubstringDomain(new ExpressionInverseSet(), mapB); + domainC = new SubstringDomain(new ExpressionInverseSet(), mapC); + domainD = new SubstringDomain(new ExpressionInverseSet(), mapD); + domainE = new SubstringDomain(new ExpressionInverseSet(), mapE); + domainF = new SubstringDomain(new ExpressionInverseSet(), mapF); + + TOP = new SubstringDomain().top(); + BOTTOM = new SubstringDomain().bottom();; + } + + @Test + public void testAssumeEmpty() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assumed = empty.assume(XEqualsY, null, null, null); + assertTrue(assumed.getState(x).contains(y)); + assertTrue(assumed.getState(y).contains(x)); + assertFalse(assumed.getState(y).contains(y)); + assertFalse(assumed.getState(x).contains(x)); + } + + @Test + public void testAssumeEmpty2() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assumed = empty.assume(XEndsWithY, null, null, null); + assertTrue(assumed.getState(x).contains(y)); + assertFalse(assumed.getState(y).contains(x)); + assertFalse(assumed.getState(y).contains(y)); + assertFalse(assumed.getState(x).contains(x)); + } + + @Test + public void testAssumeEmpty3() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assumed = empty.assume(XStartsWithY, null, null, null); + assertTrue(assumed.getState(x).contains(y)); + assertFalse(assumed.getState(y).contains(x)); + assertFalse(assumed.getState(y).contains(y)); + assertFalse(assumed.getState(x).contains(x)); + } + + @Test + public void testAssumeEmpty4() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assumed = empty.assume(YSubstringOfX, null, null, null); + assertTrue(assumed.getState(x).contains(y)); + assertFalse(assumed.getState(y).contains(x)); + assertFalse(assumed.getState(y).contains(y)); + assertFalse(assumed.getState(x).contains(x)); + } + + @Test + public void testAssumeEmpty5() throws SemanticException { + ValueExpression orOperation = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, + LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assumed = empty.assume(orOperation, null, null, null); + //assertTrue(assumed.getState(x).contains(y)); + //assertFalse(assumed.getState(y).contains(x)); + //assertFalse(assumed.getState(y).contains(y)); + //assertFalse(assumed.getState(x).contains(x)); + } + + @Test + public void testAssumeEmpty6() throws SemanticException { + ValueExpression andOperation = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, + LogicalAnd.INSTANCE, SyntheticLocation.INSTANCE); + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assumed = empty.assume(andOperation, null, null, null); + //assertTrue(assumed.getState(x).contains(y)); + //assertFalse(assumed.getState(y).contains(x)); + //assertFalse(assumed.getState(y).contains(y)); + //assertFalse(assumed.getState(x).contains(x)); + } + + @Test + public void testAssume1() throws SemanticException { + SubstringDomain assume1 = domainB.assume(YSubstringOfX, null, null, null); + SubstringDomain assume2 = domainB.assume(XEndsWithY, null, null, null); + SubstringDomain assume3 = domainB.assume(XStartsWithY, null, null, null); + + assertEquals(assume1, assume2); + assertEquals(assume1, assume3); + assertTrue(assume1.getState(x).contains(y)); + assertTrue(assume1.getState(x).contains(w)); + assertTrue(assume1.getState(x).contains(z)); + assertTrue(assume1.getState(y).contains(z)); + } + + @Test + public void testAssume2() throws SemanticException { + SubstringDomain assume = domainB.assume(XEqualsY, null, null, null); + + assertTrue(assume.getState(x).contains(y)); + assertTrue(assume.getState(x).contains(w)); + assertTrue(assume.getState(x).contains(z)); + assertTrue(assume.getState(y).contains(w)); + assertTrue(assume.getState(y).contains(x)); + assertTrue(assume.getState(y).contains(z)); + } + + @Test + public void testAssume3() throws SemanticException { + Identifier j = new Variable(StringType.INSTANCE, "j", SyntheticLocation.INSTANCE); + ValueExpression JSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, j, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression andOperation = new BinaryExpression(BoolType.INSTANCE, JSubstringOfY, YSubstringOfX, + LogicalAnd.INSTANCE, SyntheticLocation.INSTANCE); + SubstringDomain assume = domainB.assume(andOperation, null, null, null); + + //assertTrue(assume.getState(x).contains(w)); + //assertTrue(assume.getState(x).contains(y)); + //assertTrue(assume.getState(x).contains(z)); + //assertTrue(assume.getState(x).contains(j)); + //assertTrue(assume.getState(y).contains(j)); + //assertTrue(assume.getState(y).contains(z)); + //assertFalse(assume.getState(x).contains(x)); + //assertFalse(assume.getState(y).contains(y)); + + } + + @Test + public void testAssume4() throws SemanticException { + Identifier j = new Variable(StringType.INSTANCE, "j", SyntheticLocation.INSTANCE); + ValueExpression JSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, j, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression orOperation = new BinaryExpression(BoolType.INSTANCE, JSubstringOfY, YSubstringOfX, + LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); + SubstringDomain assume = domainB.assume(orOperation, null, null, null); + + //assertTrue(assume.getState(x).contains(w)); + //assertFalse(assume.getState(x).contains(y)); + //assertFalse(assume.getState(x).contains(z)); + //assertFalse(assume.getState(x).contains(j)); + //assertFalse(assume.getState(y).contains(j)); + //assertTrue(assume.getState(y).contains(z)); + //assertFalse(assume.getState(x).contains(x)); + //assertFalse(assume.getState(y).contains(y)); + + } + + @Test + public void testAssume5() throws SemanticException { + SubstringDomain assume = domainB.assume(CSubstringOfX, null, null, null); + + assertTrue(assume.getState(x).contains(c)); + assertTrue(assume.getState(x).contains(w)); + assertTrue(assume.getState(y).contains(z)); + } + + @Test + public void testAssume6() throws SemanticException { + SubstringDomain assume = domainF.assume(XSubstringOfC, null, null, null); + + assertTrue(assume.equals(domainF)); + } + + @Test + public void testSatisfies() throws SemanticException { + assertEquals(Satisfiability.SATISFIED, domainA.satisfies(YSubstringOfX, null, null)); + + assertEquals(Satisfiability.SATISFIED, domainE.satisfies(XEqualsY, null, null)); + assertEquals(Satisfiability.SATISFIED, domainE.satisfies(YSubstringOfX, null, null)); + assertEquals(Satisfiability.UNKNOWN, domainE.satisfies(XEqualsW, null, null)); + + assertEquals(Satisfiability.SATISFIED, domainE.satisfies(XStartsWithY, null, null)); + assertEquals(Satisfiability.UNKNOWN, domainA.satisfies(XStartsWithY, null, null)); + assertEquals(Satisfiability.SATISFIED, domainE.satisfies(XEndsWithY, null, null)); + assertEquals(Satisfiability.UNKNOWN, domainA.satisfies(XEndsWithY, null, null)); + + ValueExpression andOperation = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, LogicalAnd.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression orOperation1 = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression orOperation2 = new BinaryExpression(BoolType.INSTANCE, YSubstringOfX, WSubstringOfX, LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); + + + assertEquals(Satisfiability.SATISFIED, domainA.satisfies(andOperation, null, null)); + assertEquals(Satisfiability.SATISFIED, domainE.satisfies(orOperation1, null, null)); + assertEquals(Satisfiability.SATISFIED, domainA.satisfies(orOperation1, null, null)); + assertEquals(Satisfiability.UNKNOWN, domainE.satisfies(andOperation, null, null)); + assertEquals(Satisfiability.UNKNOWN, domainD.satisfies(orOperation1, null, null)); + + assertEquals(domainE.satisfies(orOperation2, null, null), domainE.satisfies(orOperation1, null, null)); + + assertEquals(Satisfiability.SATISFIED, domainF.satisfies(CSubstringOfX, null, null)); + assertEquals(Satisfiability.UNKNOWN, domainF.satisfies(XSubstringOfC, null, null)); + } + + @Test(expected = SemanticException.class) + public void testAssumeException1() throws SemanticException{ + domainA.assume(invalid, null, null, null); + } + + @Test(expected = SemanticException.class) + public void testAssumeException2() throws SemanticException{ + domainA.assume(XConcatY, null, null, null); + } + + @Test(expected = SemanticException.class) + public void testSatisfiesException1() throws SemanticException{ + domainA.satisfies(invalid, null, null); + } + + @Test(expected = SemanticException.class) + public void testSatisfiesException2() throws SemanticException{ + domainA.satisfies(XConcatY, null, null); + } + + @Test(expected = SemanticException.class) + public void testAssignException() throws SemanticException { + new SubstringDomain().assign(x, invalid, null, null); + } + + @Test(expected = SemanticException.class) + public void testAssignException2() throws SemanticException { + new SubstringDomain().assign(x, YSubstringOfX, null, null); + } + + @Test + public void testAssignEmptyDomain1() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, y, null, null); + assertTrue(assigned.getState(x).contains(y)); + } + + @Test + public void testAssignEmptyDomain2() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, XConcatY, null, null); + assertTrue(assigned.getState(x).contains(y)); + assertFalse(assigned.getState(x).contains(x)); + } + + @Test + public void testAssignEmptyDomain3() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, ZConcatXConcatY, null, null); + assertTrue(assigned.getState(x).contains(y)); + assertFalse(assigned.getState(x).contains(x)); + assertTrue(assigned.getState(x).contains(z)); + } + + @Test + public void testAssignEmptyDomain4() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, c, null, null); + assertTrue(assigned.getState(x).contains(c)); + } + + @Test + public void testAssignEmptyDomain5() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + Identifier j = new Variable(StringType.INSTANCE, "j", SyntheticLocation.INSTANCE); + + + SubstringDomain assigned = empty.assign(j, c, null, null) + .assign(w, j, null, null) + .assign(y, x, null, null); + + assigned = assigned.assume(WSubstringOfX, null, null, null); + + assertTrue(assigned.getState(y).contains(c)); + } + + @Test + public void testAssignEmptyDomain6() throws SemanticException{ + SubstringDomain empty = new SubstringDomain(); + + ValueExpression a = new Constant(StringType.INSTANCE, "a", SyntheticLocation.INSTANCE); + ValueExpression b = new Constant(StringType.INSTANCE, "b", SyntheticLocation.INSTANCE); + ValueExpression AConcatB = new BinaryExpression(StringType.INSTANCE, a, b, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain assigned = empty.assign(x, AConcatB, null, null); + assigned = assigned.assign(y, a, null, null); + assigned = assigned.assign(x, c, null, null); + + assertTrue(assigned.getState(y).contains(a)); + assertFalse(assigned.getState(x).contains(a)); + assertTrue(assigned.getState(x).contains(c)); + } + + @Test + public void testAssignEmptyDomain7() throws SemanticException{ + SubstringDomain empty = new SubstringDomain(); + + ValueExpression a = new Constant(StringType.INSTANCE, "a", SyntheticLocation.INSTANCE); + ValueExpression b = new Constant(StringType.INSTANCE, "b", SyntheticLocation.INSTANCE); + ValueExpression AConcatB = new BinaryExpression(StringType.INSTANCE, a, b, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain assigned = empty.assign(x, AConcatB, null, null); + assigned = assigned.assign(y, x, null, null); + assigned = assigned.assign(x, c, null, null); + + assertTrue(assigned.getState(y).contains(a)); + assertTrue(assigned.getState(y).contains(b)); + assertFalse(assigned.getState(x).contains(a)); + assertTrue(assigned.getState(x).contains(c)); + } + + @Test + public void testAssignEmptyDomain8() throws SemanticException{ + SubstringDomain empty = new SubstringDomain(); + + ValueExpression a = new Constant(StringType.INSTANCE, "a", SyntheticLocation.INSTANCE); + ValueExpression b = new Constant(StringType.INSTANCE, "b", SyntheticLocation.INSTANCE); + ValueExpression AConcatB = new BinaryExpression(StringType.INSTANCE, a, b, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XConcatC = new BinaryExpression(StringType.INSTANCE, x, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + + SubstringDomain assigned = empty.assign(x, AConcatB, null, null); + assigned = assigned.assign(y, x, null, null); + assigned = assigned.assign(x, XConcatC, null, null); + + assertTrue(assigned.getState(y).contains(a)); + assertTrue(assigned.getState(y).contains(b)); + assertTrue(assigned.getState(x).contains(a)); + assertTrue(assigned.getState(x).contains(c)); + } + + @Test + public void testAssign1() throws SemanticException { + SubstringDomain assigned = domainA.assign(x, z, null, null); + assertTrue(assigned.getState(x).contains(z)); + assertFalse(assigned.getState(x).contains(y)); + } + + @Test + public void testAssign2() throws SemanticException { + SubstringDomain assigned = domainA.assign(x, XConcatY, null, null); + assertTrue(assigned.getState(x).contains(y)); + assertFalse(assigned.getState(x).contains(x)); + assertTrue(assigned.getState(x).contains(w)); + } + + @Test + public void testAssign3() throws SemanticException { + SubstringDomain assigned = domainA.assign(x, y, null, null); + assertTrue(assigned.getState(x).contains(y)); + assertFalse(assigned.getState(x).contains(w)); + } + + @Test + public void testAssign4() throws SemanticException { + SubstringDomain assigned = domainD.assign(x, XConcatY, null, null); + assertTrue(assigned.getState(x).contains(y)); + assertTrue(assigned.getState(x).contains(w)); + assertTrue(assigned.getState(y).contains(w)); + } + + @Test + public void testAssign5() throws SemanticException { + ValueExpression WConcatY = new BinaryExpression(StringType.INSTANCE, w, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + SubstringDomain assigned = domainA.assign(z, WConcatY, null, null); + assertTrue(assigned.getState(x).contains(y)); + assertTrue(assigned.getState(x).contains(w)); + assertTrue(assigned.getState(z).contains(w)); + assertTrue(assigned.getState(z).contains(y)); + assertTrue(assigned.getState(x).contains(z)); + } + + @Test + public void testAssign6() throws SemanticException { + SubstringDomain assigned = domainE.assign(y, z, null, null); + assertFalse(assigned.getState(x).contains(y)); + assertFalse(assigned.getState(y).contains(x)); + assertTrue(assigned.getState(y).contains(z)); + + } + + @Test + public void testAssign7() throws SemanticException { + ValueExpression XConcatZ = new BinaryExpression(StringType.INSTANCE, x, z, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + SubstringDomain assigned = domainA.assign(x, XConcatZ, null, null); + assigned = assigned.assign(w, x, null, null); + assertFalse(assigned.getState(x).contains(w)); + assertTrue(assigned.getState(x).contains(y)); + assertTrue(assigned.getState(x).contains(z)); + assertTrue(assigned.getState(w).contains(x)); + assertTrue(assigned.getState(w).contains(y)); + assertTrue(assigned.getState(w).contains(z)); + } + + @Test + public void testAssign8() throws SemanticException { + SubstringDomain assigned = new SubstringDomain().assign(x, w, null, null) + .assign(y, x, null, null) + .assign(x, ZConcatXConcatY, null, null); + assertTrue(assigned.getState(x).contains(y)); + assertTrue(assigned.getState(x).contains(z)); + assertTrue(assigned.getState(x).contains(w)); + assertFalse(assigned.getState(y).contains(x)); + assertTrue(assigned.getState(y).contains(w)); + } + + @Test + public void testAssign9() throws SemanticException { + Identifier j = new Variable(StringType.INSTANCE, "j", SyntheticLocation.INSTANCE); + ValueExpression XSubstringOfJ = new BinaryExpression(BoolType.INSTANCE, j, x, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain assigned = domainF.assign(j, x, null, null); + + assertTrue(assigned.getState(x).contains(c)); + assertTrue(assigned.getState(x).contains(y)); + assertTrue(assigned.getState(w).contains(z)); + assertTrue(assigned.getState(j).contains(x)); + assertTrue(assigned.getState(j).contains(c)); + assertTrue(assigned.getState(j).contains(y)); + } + + @Test + public void testAssign10() throws SemanticException { + SubstringDomain assigned = new SubstringDomain().assign(y, c, null, null).assign(x, y, null, null); + + assertTrue(assigned.getState(x).contains(y)); + assertTrue(assigned.getState(x).contains(c)); + assertTrue(assigned.getState(y).contains(c)); + } + + @Test + public void testAssign11() throws SemanticException { + SubstringDomain assigned = new SubstringDomain().assign(y, c, null, null).assign(x, c, null, null); + + assertTrue(assigned.getState(y).contains(x)); + } + + @Test + public void testConstructor() { + SubstringDomain first = new SubstringDomain(); + + SubstringDomain second = new SubstringDomain(new ExpressionInverseSet().bottom()); + + Map f = new HashMap<>(); + + Set set = new HashSet<>(); + + set.add(y); + ExpressionInverseSet eis = new ExpressionInverseSet(set); + + f.put(x, eis); + + SubstringDomain third = new SubstringDomain(new ExpressionInverseSet(), f); + + assertTrue(first.isBottom()); + assertTrue(second.isBottom()); + assertTrue(third.getState(x).contains(y)); + } + + @Test + public void testForgetIdentifier() throws SemanticException { + Map f = new HashMap<>(); + + Set set = new HashSet<>(); + Identifier y = new Variable(StringType.INSTANCE, "y", SyntheticLocation.INSTANCE); + Identifier x = new Variable(StringType.INSTANCE, "x", SyntheticLocation.INSTANCE); + + set.add(y); + ExpressionInverseSet eis = new ExpressionInverseSet(set); + + f.put(x, eis); + + SubstringDomain domain = new SubstringDomain(new ExpressionInverseSet(), f); + + assertFalse(domain.forgetIdentifier(x).knowsIdentifier(x)); + } + + @Test + public void testLub1() throws SemanticException { + SubstringDomain lub = domainA.lub(domainB); + + assertFalse(lub.getState(x).contains(y)); + assertFalse(lub.getState(y).contains(z)); + assertTrue(lub.getState(x).contains(w)); + + } + + @Test + public void testLub2() throws SemanticException { + SubstringDomain lub = domainA.lub(TOP); + + assertTrue(lub.isTop()); + } + + @Test + public void testLub3() throws SemanticException { + SubstringDomain lub = BOTTOM.lub(domainA); + + assertTrue(lub.isBottom()); + } + + @Test + public void testLub4() throws SemanticException { + SubstringDomain lub = domainC.lub(domainD); + + assertTrue(lub.isBottom()); + } + + @Test + public void testGlb1() throws SemanticException { + SubstringDomain glb = domainA.glb(domainB); + + assertTrue(glb.getState(x).contains(y)); + assertTrue(glb.getState(y).contains(z)); + assertTrue(glb.getState(x).contains(w)); + assertTrue(glb.getState(x).contains(z)); + } + + @Test + public void testGlb2() throws SemanticException { + SubstringDomain glb = TOP.glb(domainA); + + assertTrue(glb.equals(domainA)); + } + + @Test + public void testGlb3() throws SemanticException { + SubstringDomain glb = BOTTOM.glb(domainA); + + assertTrue(glb.equals(domainA)); + } + + @Test + public void testGlb4() throws SemanticException { + SubstringDomain glb = domainC.glb(domainD); + + assertTrue(glb.getState(x).contains(z)); + assertTrue(glb.getState(y).contains(w)); + } +} diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 5dd403b93..425096f60 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -6,10 +6,13 @@ import it.unive.lisa.analysis.nonrelational.value.ValueEnvironment; import it.unive.lisa.analysis.string.CharInclusion; import it.unive.lisa.analysis.string.Prefix; +import it.unive.lisa.analysis.string.SubstringDomain; import it.unive.lisa.analysis.string.Suffix; import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; +import it.unive.lisa.conf.LiSAConfiguration.GraphType; + import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { @@ -106,4 +109,20 @@ public void testTarsis() { conf.programFile = "strings.imp"; perform(conf); } + + @Test + public void testSubstringDomain() { + CronConfiguration conf = new CronConfiguration(); + conf.serializeResults = true; // dump results + conf.abstractState = DefaultConfiguration.simpleState( + DefaultConfiguration.defaultHeapDomain(), + new SubstringDomain(), + DefaultConfiguration.defaultTypeDomain()); + conf.testDir = "string"; + conf.testSubDir = "subs-domain"; + conf.programFile = "strings.imp"; + conf.analysisGraphs = GraphType.DOT; + perform(conf); + + } } diff --git a/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java b/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java index 435a9bfb6..49e06e425 100644 --- a/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java +++ b/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java @@ -97,7 +97,42 @@ public boolean equals( ExpressionInverseSet other = (ExpressionInverseSet) obj; if (isTop != other.isTop) return false; - return true; + return elements.equals(other.elements); + } + + @Override + public ExpressionInverseSet glb(ExpressionInverseSet other) throws SemanticException{ + if (other == null) + throw new SemanticException("other == null"); + + if (this == other || this.equals(other)) + return this; + + if (isTop() || this.isBottom()) + return other; + + if (other.isTop() || other.isBottom()) + return this; + + return glbAux(other); + } + + @Override + public ExpressionInverseSet lub(ExpressionInverseSet other) throws SemanticException{ + if (other == null) + throw new SemanticException("other == null"); + + if (this == other || this.equals(other)) + return this; + + if (other.isTop() || this.isTop()) + return top(); + + if (isBottom() || other.isBottom()) + return bottom(); + + return lubAux(other); + } @Override From ded61cd7625afb070e464a501ee3164d3904a904 Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Wed, 27 Mar 2024 15:29:06 +0100 Subject: [PATCH 04/34] Restore ExpressionInverseSet implementation --- .../lattices/ExpressionInverseSet.java | 37 +------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java b/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java index 49e06e425..435a9bfb6 100644 --- a/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java +++ b/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java @@ -97,42 +97,7 @@ public boolean equals( ExpressionInverseSet other = (ExpressionInverseSet) obj; if (isTop != other.isTop) return false; - return elements.equals(other.elements); - } - - @Override - public ExpressionInverseSet glb(ExpressionInverseSet other) throws SemanticException{ - if (other == null) - throw new SemanticException("other == null"); - - if (this == other || this.equals(other)) - return this; - - if (isTop() || this.isBottom()) - return other; - - if (other.isTop() || other.isBottom()) - return this; - - return glbAux(other); - } - - @Override - public ExpressionInverseSet lub(ExpressionInverseSet other) throws SemanticException{ - if (other == null) - throw new SemanticException("other == null"); - - if (this == other || this.equals(other)) - return this; - - if (other.isTop() || this.isTop()) - return top(); - - if (isBottom() || other.isBottom()) - return bottom(); - - return lubAux(other); - + return true; } @Override From c27ccc157d730df22db1f00e01e73ca3ebf8a5e5 Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Wed, 27 Mar 2024 16:41:43 +0100 Subject: [PATCH 05/34] Refactor string tests, minor changes --- .../imp-testcases/string/strings-subs.imp | 50 +++++++++++++++++++ .../imp-testcases/string/strings.imp | 30 +---------- .../string/subs-domain/report.json | 38 ++++++++++++++ .../analysis/string/SubstringDomainTest.java | 12 ++--- .../unive/lisa/cron/StringAnalysesTest.java | 6 +-- 5 files changed, 98 insertions(+), 38 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/strings-subs.imp create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp new file mode 100644 index 000000000..885e345e8 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp @@ -0,0 +1,50 @@ +class strings { + + closure() { + def y = "a"; + def z = y; + } + + closure2(x) { + def j = "j"; + def w = j; + def y = x; + x = w; + + } + + assign() { + def j = "string"; + def x = "a" + j; + def y = "a"; + } + + constants() { + def a = "abc"; + def b = "def"; + } + + branching(x) { + def a = "abc"; + if (x == 2) + a = "hello"; + else + a = "world"; + } + + assume(x) { + def b = "abc"; + if (strcon(x, b)) + b = "hello"; + else + b = b + "hello"; + + } + + loops(x) { + def str = "b"; + while (x < 100) { + str = str + "a"; + } + } +} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/strings.imp b/lisa/lisa-analyses/imp-testcases/string/strings.imp index 060c99e32..c5ef46d87 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings.imp @@ -1,24 +1,5 @@ class strings { - closure() { - def y = "a"; - def z = y; - } - - closure2(x) { - def j = "j"; - def w = j; - def y = x; - x = w; - - } - - assign() { - def j = "string"; - def x = "a" + j; - def y = "a"; - } - constants() { def a = "abc"; def b = "def"; @@ -32,17 +13,8 @@ class strings { a = "world"; } - assume(x) { - def b = "abc"; - if (strcon(x, b)) - b = "hello"; - else - b = b + "hello"; - - } - loops(x) { - def str = "b"; + def str = "a"; while (x < 100) { str = str + "a"; } diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json new file mode 100644 index 000000000..dad788f09 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json @@ -0,0 +1,38 @@ +{ + "warnings" : [ ], + "files" : [ "report.json", "untyped_strings.closure(strings__this).json" ], + "info" : { + "cfgs" : "1", + "duration" : "24ms", + "end" : "2024-03-27T16:24:12.709+01:00", + "expressions" : "4", + "files" : "1", + "globals" : "0", + "members" : "1", + "programs" : "1", + "start" : "2024-03-27T16:24:12.685+01:00", + "statements" : "3", + "units" : "1", + "version" : "0.1b9", + "warnings" : "0" + }, + "configuration" : { + "analysisGraphs" : "NONE", + "descendingPhaseType" : "NONE", + "dumpForcesUnwinding" : "false", + "fixpointWorkingSet" : "DuplicateFreeFIFOWorkingSet", + "glbThreshold" : "5", + "hotspots" : "unset", + "jsonOutput" : "true", + "openCallPolicy" : "WorstCasePolicy", + "optimize" : "false", + "recursionWideningThreshold" : "5", + "semanticChecks" : "", + "serializeInputs" : "false", + "serializeResults" : "true", + "syntacticChecks" : "", + "useWideningPoints" : "true", + "wideningThreshold" : "5", + "workdir" : "test-outputs/string/subs-domain" + } +} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 53ef10d01..56037ca17 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -1,5 +1,9 @@ package it.unive.lisa.analysis.string; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -7,10 +11,6 @@ import org.junit.Test; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertEquals; - import it.unive.lisa.analysis.SemanticException; import it.unive.lisa.analysis.lattices.ExpressionInverseSet; import it.unive.lisa.analysis.lattices.Satisfiability; @@ -599,7 +599,7 @@ public void testLub2() throws SemanticException { public void testLub3() throws SemanticException { SubstringDomain lub = BOTTOM.lub(domainA); - assertTrue(lub.isBottom()); + assertEquals(lub, domainA); } @Test @@ -630,7 +630,7 @@ public void testGlb2() throws SemanticException { public void testGlb3() throws SemanticException { SubstringDomain glb = BOTTOM.glb(domainA); - assertTrue(glb.equals(domainA)); + assertEquals(glb, BOTTOM); } @Test diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 425096f60..59b64ca4f 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -1,5 +1,7 @@ package it.unive.lisa.cron; +import org.junit.Test; + import it.unive.lisa.AnalysisTestExecutor; import it.unive.lisa.CronConfiguration; import it.unive.lisa.DefaultConfiguration; @@ -13,8 +15,6 @@ import it.unive.lisa.analysis.string.tarsis.Tarsis; import it.unive.lisa.conf.LiSAConfiguration.GraphType; -import org.junit.Test; - public class StringAnalysesTest extends AnalysisTestExecutor { @Test @@ -120,7 +120,7 @@ public void testSubstringDomain() { DefaultConfiguration.defaultTypeDomain()); conf.testDir = "string"; conf.testSubDir = "subs-domain"; - conf.programFile = "strings.imp"; + conf.programFile = "strings-subs.imp"; conf.analysisGraphs = GraphType.DOT; perform(conf); From 0f25d5df126f6af0629fd4633a7d1cc3c6106ade Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Wed, 27 Mar 2024 16:41:58 +0100 Subject: [PATCH 06/34] Refactor lub and glb methods for substring relational domain --- ...ntyped_strings.closure(strings__this).json | 224 ++++++++++++++++++ .../lisa/analysis/string/SubstringDomain.java | 59 +---- 2 files changed, 227 insertions(+), 56 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure(strings__this).json diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure(strings__this).json new file mode 100644 index 000000000..267e889bc --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure(strings__this).json @@ -0,0 +1,224 @@ +{ + "name": "untyped strings::closure(strings* this)", + "description": null, + "nodes": [ + { + "id": 0, + "subNodes": [ + 1, + 2 + ], + "text": "y = \"a\"" + }, + { + "id": 1, + "text": "y" + }, + { + "id": 2, + "text": "\"a\"" + }, + { + "id": 3, + "subNodes": [ + 4, + 5 + ], + "text": "z = y" + }, + { + "id": 4, + "text": "z" + }, + { + "id": 5, + "text": "y" + }, + { + "id": 6, + "text": "ret" + } + ], + "edges": [ + { + "sourceId": 0, + "destId": 3, + "kind": "SequentialEdge" + }, + { + "sourceId": 3, + "destId": 6, + "kind": "SequentialEdge" + } + ], + "descriptions": [ + { + "nodeId": 0, + "description": { + "expressions": [ + "y" + ], + "state": { + "heap": "monolith", + "type": { + "this": [ + "strings*" + ], + "y": [ + "string" + ] + }, + "value": { + "y": [ + "\"a\"" + ] + } + } + } + }, + { + "nodeId": 1, + "description": { + "expressions": [ + "y" + ], + "state": { + "heap": "monolith", + "type": { + "this": [ + "strings*" + ] + }, + "value": "#TOP#" + } + } + }, + { + "nodeId": 2, + "description": { + "expressions": [ + "\"a\"" + ], + "state": { + "heap": "monolith", + "type": { + "this": [ + "strings*" + ] + }, + "value": "#TOP#" + } + } + }, + { + "nodeId": 3, + "description": { + "expressions": [ + "z" + ], + "state": { + "heap": "monolith", + "type": { + "this": [ + "strings*" + ], + "y": [ + "string" + ], + "z": [ + "string" + ] + }, + "value": { + "y": [ + "\"a\"" + ], + "z": [ + "\"a\"", + "y" + ] + } + } + } + }, + { + "nodeId": 4, + "description": { + "expressions": [ + "z" + ], + "state": { + "heap": "monolith", + "type": { + "this": [ + "strings*" + ], + "y": [ + "string" + ] + }, + "value": { + "y": [ + "\"a\"" + ] + } + } + } + }, + { + "nodeId": 5, + "description": { + "expressions": [ + "y" + ], + "state": { + "heap": "monolith", + "type": { + "this": [ + "strings*" + ], + "y": [ + "string" + ] + }, + "value": { + "y": [ + "\"a\"" + ] + } + } + } + }, + { + "nodeId": 6, + "description": { + "expressions": [ + "skip" + ], + "state": { + "heap": "monolith", + "type": { + "this": [ + "strings*" + ], + "y": [ + "string" + ], + "z": [ + "string" + ] + }, + "value": { + "y": [ + "\"a\"" + ], + "z": [ + "\"a\"", + "y" + ] + } + } + } + } + ] +} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index 69f6041e1..232c4909d 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -43,68 +43,15 @@ public SubstringDomain() { this(new ExpressionInverseSet()); } - @Override - public SubstringDomain lub(SubstringDomain other) throws SemanticException{ - if (other == null) - throw new SemanticException("other == null"); - - if (this == other || this.equals(other)) - return this; - - if (other.isTop() || this.isTop()) - return top(); - - if (isBottom() || other.isBottom()) - return bottom(); - - return lubAux(other); - - } - @Override public SubstringDomain lubAux(SubstringDomain other) throws SemanticException { - Map newFunction = mkNewFunction(null, false); - - for(Map.Entry entry : other) { - ExpressionInverseSet newSet = getState(entry.getKey()); - newFunction.put(entry.getKey(), newSet.lub(entry.getValue())); - } - - SubstringDomain result = mk(lattice, newFunction); - - return result.clear(); - } - - @Override - public SubstringDomain glb(SubstringDomain other) throws SemanticException{ - if (other == null) - throw new SemanticException("other == null"); - - if (this == other || this.equals(other)) - return this; - - if (isTop() || this.isBottom()) - return other; - - if (other.isTop() || other.isBottom()) - return this; - - return glbAux(other); + return functionalLift(other, lattice.top(), this::lubKeys, (o1, o2) -> o1.lub(o2)); } @Override public SubstringDomain glbAux(SubstringDomain other) throws SemanticException { - Map newFunction = mkNewFunction(this.function, false); - - for(Map.Entry entry : other) { - ExpressionInverseSet newSet = getState(entry.getKey()).glb(entry.getValue()); - newFunction.put(entry.getKey(), newSet); - } - - SubstringDomain result = mk(lattice, newFunction); - - return result.closure(); - + // FIXME: lattice.top should be changed + return functionalLift(other, lattice.top(), this::glbKeys, (o1, o2) -> o1.glb(o2)).closure(); } @Override From 58d32fe01c124b9641edef3b9bc144be33d9a659 Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Mon, 1 Apr 2024 20:26:43 +0200 Subject: [PATCH 07/34] Substring domain bug fix + test --- .../imp-testcases/string/strings-subs.imp | 56 ++++- .../string/subs-domain/report.json | 18 +- ...ings.assume(strings__this,_untyped_x).json | 1 + ...s.branching(strings__this,_untyped_x).json | 1 + ...ntyped_strings.closure(strings__this).json | 225 +----------------- ...gs.closure2(strings__this,_untyped_x).json | 1 + ...typed_strings.closure3(strings__this).json | 1 + ...typed_strings.closure4(strings__this).json | 1 + ...yped_strings.constants(strings__this).json | 1 + ...ntyped_strings.iftest1(strings__this).json | 1 + ...ntyped_strings.iftest2(strings__this).json | 1 + ...yped_strings.iftestand(strings__this).json | 1 + ...typed_strings.iftestor(strings__this).json | 1 + ...ed_strings.interassign(strings__this).json | 1 + ...rings.loops(strings__this,_untyped_x).json | 1 + .../lisa/analysis/string/SubstringDomain.java | 69 +++--- .../analysis/string/SubstringDomainTest.java | 201 ++++++++-------- .../unive/lisa/cron/StringAnalysesTest.java | 2 +- .../lattices/ExpressionInverseSet.java | 5 +- 19 files changed, 220 insertions(+), 368 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this,_untyped_x).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this,_untyped_x).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure3(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure4(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.constants(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest2(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestor(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.interassign(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.loops(strings__this,_untyped_x).json diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp index 885e345e8..5061d5063 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp @@ -1,5 +1,37 @@ class strings { + iftest1() { + def str = "a"; + if (strstarts(str, "a")) + str = str + " true"; + else + str = "false"; + } + + iftest2() { + def str = "hello"; + if (strends(str, "o")) + str = "true"; + else + str = "false"; + } + + iftestand(){ + def str = "string"; + if ((strends(str, "ng")) && (streq(str, "ong"))) + def x = "ong"; + else + def y = "no"; + } + + iftestor(){ + def str = "string"; + if (strends(str, "n") || streq(str, "no")) + def x = "n"; + else + def y = "no"; + } + closure() { def y = "a"; def z = y; @@ -10,13 +42,31 @@ class strings { def w = j; def y = x; x = w; - } - assign() { + closure3() { + def j = "j"; + def w = j; + def x = "x"; + def y = x; + x = w; + } + + closure4() { + def w = "w"; + def z = "z" + w; + def y = "y"; + def x = "x" + y; + if (strcon(y, z)) + w = "hello"; + else + w = "world"; + } + + interassign() { def j = "string"; def x = "a" + j; - def y = "a"; + def y = "string"; } constants() { diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json index dad788f09..9c8064a95 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json @@ -1,17 +1,17 @@ { "warnings" : [ ], - "files" : [ "report.json", "untyped_strings.closure(strings__this).json" ], + "files" : [ "report.json", "untyped_strings.assume(strings__this,_untyped_x).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this,_untyped_x).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.closure4(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json" ], "info" : { - "cfgs" : "1", - "duration" : "24ms", - "end" : "2024-03-27T16:24:12.709+01:00", - "expressions" : "4", - "files" : "1", + "cfgs" : "13", + "duration" : "41ms", + "end" : "2024-03-30T19:30:59.858+01:00", + "expressions" : "120", + "files" : "13", "globals" : "0", - "members" : "1", + "members" : "13", "programs" : "1", - "start" : "2024-03-27T16:24:12.685+01:00", - "statements" : "3", + "start" : "2024-03-30T19:30:59.817+01:00", + "statements" : "63", "units" : "1", "version" : "0.1b9", "warnings" : "0" diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this,_untyped_x).json new file mode 100644 index 000000000..e59ee1578 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this,_untyped_x).json @@ -0,0 +1 @@ +{"name":"untyped strings::assume(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"b = \"abc\""},{"id":1,"text":"b"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"contains(x, b)"},{"id":4,"text":"x"},{"id":5,"text":"b"},{"id":6,"subNodes":[7,8],"text":"b = \"hello\""},{"id":7,"text":"b"},{"id":8,"text":"\"hello\""},{"id":9,"subNodes":[10,11],"text":"b = +(b, \"hello\")"},{"id":10,"text":"b"},{"id":11,"subNodes":[12,13],"text":"+(b, \"hello\")"},{"id":12,"text":"b"},{"id":13,"text":"\"hello\""},{"id":14,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":14,"kind":"SequentialEdge"},{"sourceId":9,"destId":14,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":1,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x strcontains b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":5,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":6,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"hello\""],"x":["\"abc\""]}}}},{"nodeId":7,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""],"x":["\"abc\"","b"]}}}},{"nodeId":8,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""],"x":["\"abc\"","b"]}}}},{"nodeId":9,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\"","\"hello\""]}}}},{"nodeId":10,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":11,"description":{"expressions":["b strcat \"hello\""],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":12,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":13,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":14,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"hello\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json new file mode 100644 index 000000000..f80c5d02b --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json @@ -0,0 +1 @@ +{"name":"untyped strings::branching(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = \"abc\""},{"id":1,"text":"a"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"==(x, 2)"},{"id":4,"text":"x"},{"id":5,"text":"2"},{"id":6,"subNodes":[7,8],"text":"a = \"hello\""},{"id":7,"text":"a"},{"id":8,"text":"\"hello\""},{"id":9,"subNodes":[10,11],"text":"a = \"world\""},{"id":10,"text":"a"},{"id":11,"text":"\"world\""},{"id":12,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":1,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x == 2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":5,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":6,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"hello\""]}}}},{"nodeId":7,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":8,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":9,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"world\""]}}}},{"nodeId":10,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":11,"description":{"expressions":["\"world\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":12,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure(strings__this).json index 267e889bc..fbee6724e 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure(strings__this).json @@ -1,224 +1 @@ -{ - "name": "untyped strings::closure(strings* this)", - "description": null, - "nodes": [ - { - "id": 0, - "subNodes": [ - 1, - 2 - ], - "text": "y = \"a\"" - }, - { - "id": 1, - "text": "y" - }, - { - "id": 2, - "text": "\"a\"" - }, - { - "id": 3, - "subNodes": [ - 4, - 5 - ], - "text": "z = y" - }, - { - "id": 4, - "text": "z" - }, - { - "id": 5, - "text": "y" - }, - { - "id": 6, - "text": "ret" - } - ], - "edges": [ - { - "sourceId": 0, - "destId": 3, - "kind": "SequentialEdge" - }, - { - "sourceId": 3, - "destId": 6, - "kind": "SequentialEdge" - } - ], - "descriptions": [ - { - "nodeId": 0, - "description": { - "expressions": [ - "y" - ], - "state": { - "heap": "monolith", - "type": { - "this": [ - "strings*" - ], - "y": [ - "string" - ] - }, - "value": { - "y": [ - "\"a\"" - ] - } - } - } - }, - { - "nodeId": 1, - "description": { - "expressions": [ - "y" - ], - "state": { - "heap": "monolith", - "type": { - "this": [ - "strings*" - ] - }, - "value": "#TOP#" - } - } - }, - { - "nodeId": 2, - "description": { - "expressions": [ - "\"a\"" - ], - "state": { - "heap": "monolith", - "type": { - "this": [ - "strings*" - ] - }, - "value": "#TOP#" - } - } - }, - { - "nodeId": 3, - "description": { - "expressions": [ - "z" - ], - "state": { - "heap": "monolith", - "type": { - "this": [ - "strings*" - ], - "y": [ - "string" - ], - "z": [ - "string" - ] - }, - "value": { - "y": [ - "\"a\"" - ], - "z": [ - "\"a\"", - "y" - ] - } - } - } - }, - { - "nodeId": 4, - "description": { - "expressions": [ - "z" - ], - "state": { - "heap": "monolith", - "type": { - "this": [ - "strings*" - ], - "y": [ - "string" - ] - }, - "value": { - "y": [ - "\"a\"" - ] - } - } - } - }, - { - "nodeId": 5, - "description": { - "expressions": [ - "y" - ], - "state": { - "heap": "monolith", - "type": { - "this": [ - "strings*" - ], - "y": [ - "string" - ] - }, - "value": { - "y": [ - "\"a\"" - ] - } - } - } - }, - { - "nodeId": 6, - "description": { - "expressions": [ - "skip" - ], - "state": { - "heap": "monolith", - "type": { - "this": [ - "strings*" - ], - "y": [ - "string" - ], - "z": [ - "string" - ] - }, - "value": { - "y": [ - "\"a\"" - ], - "z": [ - "\"a\"", - "y" - ] - } - } - } - } - ] -} \ No newline at end of file +{"name":"untyped strings::closure(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"y = \"a\""},{"id":1,"text":"y"},{"id":2,"text":"\"a\""},{"id":3,"subNodes":[4,5],"text":"z = y"},{"id":4,"text":"z"},{"id":5,"text":"y"},{"id":6,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"a\""]}}}},{"nodeId":1,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":{"y":["\"a\""],"z":["\"a\"","y"]}}}},{"nodeId":4,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"a\""]}}}},{"nodeId":5,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"a\""]}}}},{"nodeId":6,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":{"y":["\"a\""],"z":["\"a\"","y"]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this,_untyped_x).json new file mode 100644 index 000000000..bfa088168 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this,_untyped_x).json @@ -0,0 +1 @@ +{"name":"untyped strings::closure2(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"j = \"j\""},{"id":1,"text":"j"},{"id":2,"text":"\"j\""},{"id":3,"subNodes":[4,5],"text":"w = j"},{"id":4,"text":"w"},{"id":5,"text":"j"},{"id":6,"subNodes":[7,8],"text":"y = x"},{"id":7,"text":"y"},{"id":8,"text":"x"},{"id":9,"subNodes":[10,11],"text":"x = w"},{"id":10,"text":"x"},{"id":11,"text":"w"},{"id":12,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"j":["\"j\""]}}}},{"nodeId":1,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"j\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":4,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"j":["\"j\""]}}}},{"nodeId":5,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"j":["\"j\""]}}}},{"nodeId":6,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#","y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"y":["x"]}}}},{"nodeId":7,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":8,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":9,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#","y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"y":["x"]}}}},{"nodeId":11,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#","y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"y":["x"]}}}},{"nodeId":12,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure3(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure3(strings__this).json new file mode 100644 index 000000000..ea260a957 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure3(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::closure3(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"j = \"j\""},{"id":1,"text":"j"},{"id":2,"text":"\"j\""},{"id":3,"subNodes":[4,5],"text":"w = j"},{"id":4,"text":"w"},{"id":5,"text":"j"},{"id":6,"subNodes":[7,8],"text":"x = \"x\""},{"id":7,"text":"x"},{"id":8,"text":"\"x\""},{"id":9,"subNodes":[10,11],"text":"y = x"},{"id":10,"text":"y"},{"id":11,"text":"x"},{"id":12,"subNodes":[13,14],"text":"x = w"},{"id":13,"text":"x"},{"id":14,"text":"w"},{"id":15,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":15,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"j\""]}}}},{"nodeId":1,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"j\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":4,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"j\""]}}}},{"nodeId":5,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"j\""]}}}},{"nodeId":6,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""]}}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":8,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""],"y":["\"x\"","x"]}}}},{"nodeId":10,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"],"y":["\"x\""]}}}},{"nodeId":13,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""],"y":["\"x\"","x"]}}}},{"nodeId":14,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""],"y":["\"x\"","x"]}}}},{"nodeId":15,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"],"y":["\"x\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure4(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure4(strings__this).json new file mode 100644 index 000000000..a3d282b56 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure4(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::closure4(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"w = \"w\""},{"id":1,"text":"w"},{"id":2,"text":"\"w\""},{"id":3,"subNodes":[4,5],"text":"z = +(\"z\", w)"},{"id":4,"text":"z"},{"id":5,"subNodes":[6,7],"text":"+(\"z\", w)"},{"id":6,"text":"\"z\""},{"id":7,"text":"w"},{"id":8,"subNodes":[9,10],"text":"y = \"y\""},{"id":9,"text":"y"},{"id":10,"text":"\"y\""},{"id":11,"subNodes":[12,13],"text":"x = +(\"x\", y)"},{"id":12,"text":"x"},{"id":13,"subNodes":[14,15],"text":"+(\"x\", y)"},{"id":14,"text":"\"x\""},{"id":15,"text":"y"},{"id":16,"subNodes":[17,18],"text":"contains(y, z)"},{"id":17,"text":"y"},{"id":18,"text":"z"},{"id":19,"subNodes":[20,21],"text":"w = \"hello\""},{"id":20,"text":"w"},{"id":21,"text":"\"hello\""},{"id":22,"subNodes":[23,24],"text":"w = \"world\""},{"id":23,"text":"w"},{"id":24,"text":"\"world\""},{"id":25,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":8,"kind":"SequentialEdge"},{"sourceId":8,"destId":11,"kind":"SequentialEdge"},{"sourceId":11,"destId":16,"kind":"SequentialEdge"},{"sourceId":16,"destId":19,"kind":"TrueEdge"},{"sourceId":16,"destId":22,"kind":"FalseEdge"},{"sourceId":19,"destId":25,"kind":"SequentialEdge"},{"sourceId":22,"destId":25,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":1,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"w\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"z":["string"]},"value":{"w":["\"w\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":4,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":5,"description":{"expressions":["\"z\" strcat w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":6,"description":{"expressions":["\"z\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":7,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"z":["string"]},"value":{"w":["\"w\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":10,"description":{"expressions":["\"y\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"z":["string"]},"value":{"w":["\"w\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":13,"description":{"expressions":["\"x\" strcat y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":14,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":15,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":16,"description":{"expressions":["y strcontains z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":18,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":19,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"hello\""],"x":["\"w\"","\"x\"","\"y\"","\"z\"","y","z"],"y":["\"w\"","\"y\"","\"z\"","z"],"z":["\"w\"","\"z\""]}}}},{"nodeId":20,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"w\"","\"x\"","\"y\"","\"z\"","w","y","z"],"y":["\"w\"","\"y\"","\"z\"","w","z"],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":21,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"w\"","\"x\"","\"y\"","\"z\"","w","y","z"],"y":["\"w\"","\"y\"","\"z\"","w","z"],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":22,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"world\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\""]}}}},{"nodeId":23,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":24,"description":{"expressions":["\"world\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":25,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.constants(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.constants(strings__this).json new file mode 100644 index 000000000..5456d152a --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.constants(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::constants(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = \"abc\""},{"id":1,"text":"a"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"b = \"def\""},{"id":4,"text":"b"},{"id":5,"text":"\"def\""},{"id":6,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"]},"value":{"a":["\"abc\""]}}}},{"nodeId":1,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"]},"value":{"a":["\"abc\""],"b":["\"def\""]}}}},{"nodeId":4,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"]},"value":{"a":["\"abc\""]}}}},{"nodeId":5,"description":{"expressions":["\"def\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"]},"value":{"a":["\"abc\""]}}}},{"nodeId":6,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"]},"value":{"a":["\"abc\""],"b":["\"def\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json new file mode 100644 index 000000000..e2fb42548 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::iftest1(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"a\""},{"id":1,"text":"str"},{"id":2,"text":"\"a\""},{"id":3,"subNodes":[4,5],"text":"startsWith(str, \"a\")"},{"id":4,"text":"str"},{"id":5,"text":"\"a\""},{"id":6,"subNodes":[7,8],"text":"str = +(str, \" true\")"},{"id":7,"text":"str"},{"id":8,"subNodes":[9,10],"text":"+(str, \" true\")"},{"id":9,"text":"str"},{"id":10,"text":"\" true\""},{"id":11,"subNodes":[12,13],"text":"str = \"false\""},{"id":12,"text":"str"},{"id":13,"text":"\"false\""},{"id":14,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":11,"kind":"FalseEdge"},{"sourceId":6,"destId":14,"kind":"SequentialEdge"},{"sourceId":11,"destId":14,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strstarts \"a\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":4,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":5,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":6,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\" true\"","\"a\""]}}}},{"nodeId":7,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":8,"description":{"expressions":["str strcat \" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":9,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":10,"description":{"expressions":["\" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":11,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"false\""]}}}},{"nodeId":12,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":13,"description":{"expressions":["\"false\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":14,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":"#TOP#"}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest2(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest2(strings__this).json new file mode 100644 index 000000000..d2d084a36 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest2(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::iftest2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"hello\""},{"id":1,"text":"str"},{"id":2,"text":"\"hello\""},{"id":3,"subNodes":[4,5],"text":"endsWith(str, \"o\")"},{"id":4,"text":"str"},{"id":5,"text":"\"o\""},{"id":6,"subNodes":[7,8],"text":"str = \"true\""},{"id":7,"text":"str"},{"id":8,"text":"\"true\""},{"id":9,"subNodes":[10,11],"text":"str = \"false\""},{"id":10,"text":"str"},{"id":11,"text":"\"false\""},{"id":12,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":4,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":5,"description":{"expressions":["\"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":6,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"true\""]}}}},{"nodeId":7,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\"","\"o\""]}}}},{"nodeId":8,"description":{"expressions":["\"true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\"","\"o\""]}}}},{"nodeId":9,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"false\""]}}}},{"nodeId":10,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":11,"description":{"expressions":["\"false\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":12,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":"#TOP#"}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json new file mode 100644 index 000000000..1237799b2 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::iftestand(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"string\""},{"id":1,"text":"str"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,7],"text":"&&(endsWith(str, \"ng\"), equals(str, \"ong\"))"},{"id":4,"subNodes":[5,6],"text":"endsWith(str, \"ng\")"},{"id":5,"text":"str"},{"id":6,"text":"\"ng\""},{"id":7,"subNodes":[8,9],"text":"equals(str, \"ong\")"},{"id":8,"text":"str"},{"id":9,"text":"\"ong\""},{"id":10,"subNodes":[11,12],"text":"x = \"ong\""},{"id":11,"text":"x"},{"id":12,"text":"\"ong\""},{"id":13,"subNodes":[14,15],"text":"y = \"no\""},{"id":14,"text":"y"},{"id":15,"text":"\"no\""},{"id":16,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":10,"kind":"TrueEdge"},{"sourceId":3,"destId":13,"kind":"FalseEdge"},{"sourceId":10,"destId":16,"kind":"SequentialEdge"},{"sourceId":13,"destId":16,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"ng\" && str strcmp \"ong\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":4,"description":{"expressions":["str strends \"ng\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":5,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":6,"description":{"expressions":["\"ng\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":7,"description":{"expressions":["str strcmp \"ong\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":8,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":9,"description":{"expressions":["\"ong\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"]},"value":{"str":["\"ng\"","\"ong\"","\"string\"","x"],"x":["\"ong\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"ng\"","\"ong\"","\"string\""]}}}},{"nodeId":12,"description":{"expressions":["\"ong\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"ng\"","\"ong\"","\"string\""]}}}},{"nodeId":13,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"y":["string"]},"value":{"str":["\"string\""],"y":["\"no\""]}}}},{"nodeId":14,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":15,"description":{"expressions":["\"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":16,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"str":["\"string\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestor(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestor(strings__this).json new file mode 100644 index 000000000..73430fc16 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestor(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::iftestor(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"string\""},{"id":1,"text":"str"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,7],"text":"||(endsWith(str, \"n\"), equals(str, \"no\"))"},{"id":4,"subNodes":[5,6],"text":"endsWith(str, \"n\")"},{"id":5,"text":"str"},{"id":6,"text":"\"n\""},{"id":7,"subNodes":[8,9],"text":"equals(str, \"no\")"},{"id":8,"text":"str"},{"id":9,"text":"\"no\""},{"id":10,"subNodes":[11,12],"text":"x = \"n\""},{"id":11,"text":"x"},{"id":12,"text":"\"n\""},{"id":13,"subNodes":[14,15],"text":"y = \"no\""},{"id":14,"text":"y"},{"id":15,"text":"\"no\""},{"id":16,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":10,"kind":"TrueEdge"},{"sourceId":3,"destId":13,"kind":"FalseEdge"},{"sourceId":10,"destId":16,"kind":"SequentialEdge"},{"sourceId":13,"destId":16,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"n\" || str strcmp \"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":4,"description":{"expressions":["str strends \"n\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":5,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":6,"description":{"expressions":["\"n\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":7,"description":{"expressions":["str strcmp \"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":8,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":9,"description":{"expressions":["\"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"]},"value":{"str":["\"string\""],"x":["\"n\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":12,"description":{"expressions":["\"n\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":13,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"y":["string"]},"value":{"str":["\"string\""],"y":["\"no\""]}}}},{"nodeId":14,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":15,"description":{"expressions":["\"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":16,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"str":["\"string\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.interassign(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.interassign(strings__this).json new file mode 100644 index 000000000..ad6dcfd40 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.interassign(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::interassign(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"j = \"string\""},{"id":1,"text":"j"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,5],"text":"x = +(\"a\", j)"},{"id":4,"text":"x"},{"id":5,"subNodes":[6,7],"text":"+(\"a\", j)"},{"id":6,"text":"\"a\""},{"id":7,"text":"j"},{"id":8,"subNodes":[9,10],"text":"y = \"string\""},{"id":9,"text":"y"},{"id":10,"text":"\"string\""},{"id":11,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":8,"kind":"SequentialEdge"},{"sourceId":8,"destId":11,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":1,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"]},"value":{"j":["\"string\""],"x":["\"a\"","\"string\"","j"]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":5,"description":{"expressions":["\"a\" strcat j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":6,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":7,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"j":["\"string\"","y"],"x":["\"a\"","\"string\"","j","y"],"y":["\"string\""]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"]},"value":{"j":["\"string\""],"x":["\"a\"","\"string\"","j"]}}}},{"nodeId":10,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"]},"value":{"j":["\"string\""],"x":["\"a\"","\"string\"","j"]}}}},{"nodeId":11,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"j":["\"string\"","y"],"x":["\"a\"","\"string\"","j","y"],"y":["\"string\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.loops(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.loops(strings__this,_untyped_x).json new file mode 100644 index 000000000..06ce81d26 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.loops(strings__this,_untyped_x).json @@ -0,0 +1 @@ +{"name":"untyped strings::loops(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"b\""},{"id":1,"text":"str"},{"id":2,"text":"\"b\""},{"id":3,"subNodes":[4,5],"text":"<(x, 100)"},{"id":4,"text":"x"},{"id":5,"text":"100"},{"id":6,"subNodes":[7,8],"text":"str = +(str, \"a\")"},{"id":7,"text":"str"},{"id":8,"subNodes":[9,10],"text":"+(str, \"a\")"},{"id":9,"text":"str"},{"id":10,"text":"\"a\""},{"id":11,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":11,"kind":"FalseEdge"},{"sourceId":6,"destId":3,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"b\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x < 100"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"b\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"b\""]}}}},{"nodeId":5,"description":{"expressions":["100"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"b\""]}}}},{"nodeId":6,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"a\"","\"b\""]}}}},{"nodeId":7,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"b\""]}}}},{"nodeId":8,"description":{"expressions":["str strcat \"a\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"b\""]}}}},{"nodeId":9,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"b\""]}}}},{"nodeId":10,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"b\""]}}}},{"nodeId":11,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"str":["\"b\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index 232c4909d..0550114a4 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -1,5 +1,6 @@ package it.unive.lisa.analysis.string; +import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -45,13 +46,12 @@ public SubstringDomain() { @Override public SubstringDomain lubAux(SubstringDomain other) throws SemanticException { - return functionalLift(other, lattice.top(), this::lubKeys, (o1, o2) -> o1.lub(o2)); + return functionalLift(other, lattice.top(), this::glbKeys, (o1, o2) -> o1.lub(o2)).clear(); } @Override public SubstringDomain glbAux(SubstringDomain other) throws SemanticException { - // FIXME: lattice.top should be changed - return functionalLift(other, lattice.top(), this::glbKeys, (o1, o2) -> o1.glb(o2)).closure(); + return functionalLift(other, lattice.top(), this::lubKeys, (o1, o2) -> o1.glb(o2)).closure(); } @Override @@ -66,12 +66,12 @@ public SubstringDomain bottom() { @Override public ExpressionInverseSet stateOfUnknown(Identifier key) { - return new ExpressionInverseSet(); + return lattice.top(); } @Override public SubstringDomain mk(ExpressionInverseSet lattice, Map function) { - return new SubstringDomain(lattice, function); + return new SubstringDomain(lattice.isBottom() ? lattice.bottom() : lattice.top(), function); } @Override @@ -126,21 +126,19 @@ public SubstringDomain assume(ValueExpression expression, ProgramPoint src, Prog result = result.add(extracted, (Identifier) left); - //result = result.closure((Identifier) left); result = result.closure(); } else if (binaryOperator instanceof StringEquals){ - //both are identifiers + // both are identifiers if ((left instanceof Identifier) && (right instanceof Identifier)) { result = result.add(extrPlus((ValueExpression) left), (Identifier) right); result = result.add(extrPlus((ValueExpression) right), (Identifier)left); - result = result.closure((Identifier) left); - result = result.closure((Identifier) right); - } //one is identifier + result = result.closure(); + } // one is identifier else if((left instanceof Identifier) || (right instanceof Identifier)) { - if (right instanceof Identifier) { //left instance of Identifier, right SymbolicExpression + if (right instanceof Identifier) { // left instance of Identifier, right SymbolicExpression SymbolicExpression temp = left; left = right; right = temp; @@ -153,7 +151,6 @@ else if((left instanceof Identifier) || (right instanceof Identifier)) { result = result.add(add, (Identifier) left); - //result = result.closure((Identifier) left); result = result.closure(); } @@ -169,9 +166,9 @@ else if((left instanceof Identifier) || (right instanceof Identifier)) { SubstringDomain rightDomain = assume(rightValueExpression, src, dest, oracle); if (binaryOperator instanceof LogicalOr) { - result = leftDomain.glb(rightDomain); - } else { result = leftDomain.lub(rightDomain); + } else { + result = leftDomain.glb(rightDomain); } } @@ -182,7 +179,7 @@ else if((left instanceof Identifier) || (right instanceof Identifier)) { @Override public boolean knowsIdentifier(Identifier id) { - if (id == null || function == null || isBottom() || isTop()) + if (id == null || function == null) return false; if (function.containsKey(id)) @@ -200,12 +197,12 @@ public SubstringDomain forgetIdentifier(Identifier id) throws SemanticException newFunction.remove(id); - return new SubstringDomain(lattice, newFunction); + return mk(lattice, newFunction); } @Override public SubstringDomain forgetIdentifiersIf(Predicate test) throws SemanticException { - if (function == null || isTop() || isBottom() || function.keySet().isEmpty()) + if (function == null || function.keySet().isEmpty()) return this; Map newFunction = mkNewFunction(function, false); //function != null @@ -214,7 +211,7 @@ public SubstringDomain forgetIdentifiersIf(Predicate test) throws Se keys.forEach(newFunction::remove); - return new SubstringDomain(lattice, newFunction); + return mk(lattice, newFunction); } @Override @@ -247,7 +244,7 @@ public Satisfiability satisfies(ValueExpression expression, ProgramPoint pp, Sem throw new SemanticException("!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); Satisfiability leftSatisfiability = satisfies((ValueExpression) left, pp, oracle); - if (leftSatisfiability == Satisfiability.SATISFIED) + if (leftSatisfiability.equals(Satisfiability.SATISFIED)) return Satisfiability.SATISFIED; Satisfiability rightSatisfiability = satisfies((ValueExpression) right, pp, oracle); @@ -260,13 +257,14 @@ public Satisfiability satisfies(ValueExpression expression, ProgramPoint pp, Sem Satisfiability leftSatisfiability = satisfies((ValueExpression) left, pp, oracle); Satisfiability rightSatisfiability = satisfies((ValueExpression) right, pp, oracle); - if (leftSatisfiability == Satisfiability.SATISFIED && rightSatisfiability == Satisfiability.SATISFIED) + if (leftSatisfiability.equals(Satisfiability.SATISFIED) && rightSatisfiability.equals(Satisfiability.SATISFIED)) return Satisfiability.SATISFIED; else return Satisfiability.UNKNOWN; } - throw new SemanticException("Invalid expression"); + return Satisfiability.UNKNOWN; + } @Override @@ -286,7 +284,7 @@ private static Set extr(ValueExpression expression) throws S BinaryExpression binaryExpression = (BinaryExpression) expression; BinaryOperator binaryOperator = binaryExpression.getOperator(); if (!(binaryOperator instanceof StringConcat)) - throw new SemanticException(); + throw new SemanticException("!(binaryOperator instanceof StringConcat)"); ValueExpression left = (ValueExpression) binaryExpression.getLeft(); ValueExpression right = (ValueExpression) binaryExpression.getRight(); @@ -312,7 +310,9 @@ private SubstringDomain add(Set symbolicExpressions, Identif Map newFunction = mkNewFunction(function, false); symbolicExpressions.remove(id); - + if (symbolicExpressions.isEmpty()) + return this; + ExpressionInverseSet newSet = new ExpressionInverseSet(symbolicExpressions); if (!(newFunction.get(id) == null)) @@ -323,8 +323,7 @@ private SubstringDomain add(Set symbolicExpressions, Identif return mk(lattice, newFunction); } - private SubstringDomain remove(Set extracted, Identifier id) throws SemanticException { - + private SubstringDomain remove(Set extracted, Identifier id) throws SemanticException { Map newFunction = mkNewFunction(function, false); if(!extracted.contains(id)) { // x = x + ..... --> keep relations for x @@ -340,11 +339,14 @@ private SubstringDomain remove(Set extracted, Identifier id) expressionsToRemove.add(id); for (Map.Entry entry : newFunction.entrySet()) { - for(SymbolicExpression se : expressionsToRemove) { - Set set = entry.getValue().elements(); - - set.remove(se); - } + Set newSet = entry.getValue().elements.stream() + .filter(element -> !expressionsToRemove.contains(element)) + .collect(Collectors.toSet()); + + ExpressionInverseSet value = newSet.isEmpty() ? new ExpressionInverseSet().top() : new ExpressionInverseSet(newSet); + + entry.setValue(value); + } return mk(lattice, newFunction); @@ -353,6 +355,9 @@ private SubstringDomain remove(Set extracted, Identifier id) private SubstringDomain interasg(Identifier id) throws SemanticException { Map newFunction = mkNewFunction(function, false); + if (!knowsIdentifier(id)) + return this; + ExpressionInverseSet compare = function.get(id); for (Map.Entry entry : function.entrySet()) { @@ -381,7 +386,7 @@ private SubstringDomain closure(Identifier id) throws SemanticException { do { toModify = result.getState(id); - iterate = toModify.mk(toModify.elements); + iterate = result.getState(id); for (SymbolicExpression se : toModify) { if (se instanceof Variable) { @@ -425,7 +430,7 @@ private SubstringDomain clear() throws SemanticException { Map iterate = mkNewFunction(result.function, false); for (Map.Entry entry : iterate.entrySet() ) { - if (entry.getValue().isBottom()) { + if (entry.getValue().isTop()) { result = result.forgetIdentifier(entry.getKey()); } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 56037ca17..3e4c2e8eb 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -171,10 +171,12 @@ public void testAssumeEmpty5() throws SemanticException { LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain empty = new SubstringDomain(); SubstringDomain assumed = empty.assume(orOperation, null, null, null); - //assertTrue(assumed.getState(x).contains(y)); - //assertFalse(assumed.getState(y).contains(x)); - //assertFalse(assumed.getState(y).contains(y)); - //assertFalse(assumed.getState(x).contains(x)); + assertFalse(assumed.getState(x).contains(y)); + assertFalse(assumed.getState(y).contains(x)); + assertFalse(assumed.getState(y).contains(y)); + assertFalse(assumed.getState(x).contains(x)); + + assertEquals(assumed, BOTTOM); } @Test @@ -183,10 +185,10 @@ public void testAssumeEmpty6() throws SemanticException { LogicalAnd.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain empty = new SubstringDomain(); SubstringDomain assumed = empty.assume(andOperation, null, null, null); - //assertTrue(assumed.getState(x).contains(y)); - //assertFalse(assumed.getState(y).contains(x)); - //assertFalse(assumed.getState(y).contains(y)); - //assertFalse(assumed.getState(x).contains(x)); + assertTrue(assumed.getState(x).contains(y)); + assertFalse(assumed.getState(y).contains(x)); + assertFalse(assumed.getState(y).contains(w)); + assertTrue(assumed.getState(x).contains(w)); } @Test @@ -224,14 +226,14 @@ public void testAssume3() throws SemanticException { LogicalAnd.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain assume = domainB.assume(andOperation, null, null, null); - //assertTrue(assume.getState(x).contains(w)); - //assertTrue(assume.getState(x).contains(y)); - //assertTrue(assume.getState(x).contains(z)); - //assertTrue(assume.getState(x).contains(j)); - //assertTrue(assume.getState(y).contains(j)); - //assertTrue(assume.getState(y).contains(z)); - //assertFalse(assume.getState(x).contains(x)); - //assertFalse(assume.getState(y).contains(y)); + assertTrue(assume.getState(x).contains(w)); + assertTrue(assume.getState(x).contains(y)); + assertTrue(assume.getState(x).contains(z)); + assertTrue(assume.getState(x).contains(j)); + assertTrue(assume.getState(y).contains(j)); + assertTrue(assume.getState(y).contains(z)); + assertFalse(assume.getState(x).contains(x)); + assertFalse(assume.getState(y).contains(y)); } @@ -244,14 +246,14 @@ public void testAssume4() throws SemanticException { LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain assume = domainB.assume(orOperation, null, null, null); - //assertTrue(assume.getState(x).contains(w)); - //assertFalse(assume.getState(x).contains(y)); - //assertFalse(assume.getState(x).contains(z)); - //assertFalse(assume.getState(x).contains(j)); - //assertFalse(assume.getState(y).contains(j)); - //assertTrue(assume.getState(y).contains(z)); - //assertFalse(assume.getState(x).contains(x)); - //assertFalse(assume.getState(y).contains(y)); + assertTrue(assume.getState(x).contains(w)); + assertFalse(assume.getState(x).contains(y)); + assertFalse(assume.getState(x).contains(z)); + assertFalse(assume.getState(x).contains(j)); + assertFalse(assume.getState(y).contains(j)); + assertTrue(assume.getState(y).contains(z)); + assertFalse(assume.getState(x).contains(x)); + assertFalse(assume.getState(y).contains(y)); } @@ -268,7 +270,7 @@ public void testAssume5() throws SemanticException { public void testAssume6() throws SemanticException { SubstringDomain assume = domainF.assume(XSubstringOfC, null, null, null); - assertTrue(assume.equals(domainF)); + assertEquals(assume, domainF); } @Test @@ -301,36 +303,6 @@ public void testSatisfies() throws SemanticException { assertEquals(Satisfiability.UNKNOWN, domainF.satisfies(XSubstringOfC, null, null)); } - @Test(expected = SemanticException.class) - public void testAssumeException1() throws SemanticException{ - domainA.assume(invalid, null, null, null); - } - - @Test(expected = SemanticException.class) - public void testAssumeException2() throws SemanticException{ - domainA.assume(XConcatY, null, null, null); - } - - @Test(expected = SemanticException.class) - public void testSatisfiesException1() throws SemanticException{ - domainA.satisfies(invalid, null, null); - } - - @Test(expected = SemanticException.class) - public void testSatisfiesException2() throws SemanticException{ - domainA.satisfies(XConcatY, null, null); - } - - @Test(expected = SemanticException.class) - public void testAssignException() throws SemanticException { - new SubstringDomain().assign(x, invalid, null, null); - } - - @Test(expected = SemanticException.class) - public void testAssignException2() throws SemanticException { - new SubstringDomain().assign(x, YSubstringOfX, null, null); - } - @Test public void testAssignEmptyDomain1() throws SemanticException { SubstringDomain empty = new SubstringDomain(); @@ -374,7 +346,16 @@ public void testAssignEmptyDomain5() throws SemanticException { assigned = assigned.assume(WSubstringOfX, null, null, null); + assertTrue(assigned.getState(j).contains(c)); + assertTrue(assigned.getState(w).contains(c)); + assertTrue(assigned.getState(w).contains(j)); + assertTrue(assigned.getState(x).contains(w)); + assertTrue(assigned.getState(x).contains(c)); + assertTrue(assigned.getState(x).contains(j)); + assertTrue(assigned.getState(y).contains(x)); + assertTrue(assigned.getState(y).contains(w)); assertTrue(assigned.getState(y).contains(c)); + assertTrue(assigned.getState(y).contains(j)); } @Test @@ -387,6 +368,9 @@ public void testAssignEmptyDomain6() throws SemanticException{ SubstringDomain assigned = empty.assign(x, AConcatB, null, null); assigned = assigned.assign(y, a, null, null); + + assertTrue(assigned.getState(x).contains(y)); + assigned = assigned.assign(x, c, null, null); assertTrue(assigned.getState(y).contains(a)); @@ -410,6 +394,7 @@ public void testAssignEmptyDomain7() throws SemanticException{ assertTrue(assigned.getState(y).contains(b)); assertFalse(assigned.getState(x).contains(a)); assertTrue(assigned.getState(x).contains(c)); + assertFalse(assigned.getState(y).contains(x)); } @Test @@ -430,6 +415,7 @@ public void testAssignEmptyDomain8() throws SemanticException{ assertTrue(assigned.getState(y).contains(b)); assertTrue(assigned.getState(x).contains(a)); assertTrue(assigned.getState(x).contains(c)); + assertFalse(assigned.getState(y).contains(c)); } @Test @@ -449,13 +435,24 @@ public void testAssign2() throws SemanticException { @Test public void testAssign3() throws SemanticException { + ValueExpression XConcatZ = new BinaryExpression(StringType.INSTANCE, x, z, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain assigned = domainA.assign(x, XConcatZ, null, null); + assertTrue(assigned.getState(x).contains(y)); + assertFalse(assigned.getState(x).contains(x)); + assertTrue(assigned.getState(x).contains(w)); + assertTrue(assigned.getState(x).contains(z)); + } + + @Test + public void testAssign4() throws SemanticException { SubstringDomain assigned = domainA.assign(x, y, null, null); assertTrue(assigned.getState(x).contains(y)); assertFalse(assigned.getState(x).contains(w)); } @Test - public void testAssign4() throws SemanticException { + public void testAssign5() throws SemanticException { SubstringDomain assigned = domainD.assign(x, XConcatY, null, null); assertTrue(assigned.getState(x).contains(y)); assertTrue(assigned.getState(x).contains(w)); @@ -463,7 +460,7 @@ public void testAssign4() throws SemanticException { } @Test - public void testAssign5() throws SemanticException { + public void testAssign6() throws SemanticException { ValueExpression WConcatY = new BinaryExpression(StringType.INSTANCE, w, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain assigned = domainA.assign(z, WConcatY, null, null); assertTrue(assigned.getState(x).contains(y)); @@ -474,7 +471,7 @@ public void testAssign5() throws SemanticException { } @Test - public void testAssign6() throws SemanticException { + public void testAssign7() throws SemanticException { SubstringDomain assigned = domainE.assign(y, z, null, null); assertFalse(assigned.getState(x).contains(y)); assertFalse(assigned.getState(y).contains(x)); @@ -483,7 +480,7 @@ public void testAssign6() throws SemanticException { } @Test - public void testAssign7() throws SemanticException { + public void testAssign8() throws SemanticException { ValueExpression XConcatZ = new BinaryExpression(StringType.INSTANCE, x, z, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain assigned = domainA.assign(x, XConcatZ, null, null); assigned = assigned.assign(w, x, null, null); @@ -496,7 +493,7 @@ public void testAssign7() throws SemanticException { } @Test - public void testAssign8() throws SemanticException { + public void testAssign9() throws SemanticException { SubstringDomain assigned = new SubstringDomain().assign(x, w, null, null) .assign(y, x, null, null) .assign(x, ZConcatXConcatY, null, null); @@ -508,9 +505,8 @@ public void testAssign8() throws SemanticException { } @Test - public void testAssign9() throws SemanticException { + public void testAssign10() throws SemanticException { Identifier j = new Variable(StringType.INSTANCE, "j", SyntheticLocation.INSTANCE); - ValueExpression XSubstringOfJ = new BinaryExpression(BoolType.INSTANCE, j, x, StringContains.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain assigned = domainF.assign(j, x, null, null); @@ -523,7 +519,7 @@ public void testAssign9() throws SemanticException { } @Test - public void testAssign10() throws SemanticException { + public void testAssign11() throws SemanticException { SubstringDomain assigned = new SubstringDomain().assign(y, c, null, null).assign(x, y, null, null); assertTrue(assigned.getState(x).contains(y)); @@ -532,7 +528,7 @@ public void testAssign10() throws SemanticException { } @Test - public void testAssign11() throws SemanticException { + public void testAssign12() throws SemanticException { SubstringDomain assigned = new SubstringDomain().assign(y, c, null, null).assign(x, c, null, null); assertTrue(assigned.getState(y).contains(x)); @@ -542,7 +538,6 @@ public void testAssign11() throws SemanticException { public void testConstructor() { SubstringDomain first = new SubstringDomain(); - SubstringDomain second = new SubstringDomain(new ExpressionInverseSet().bottom()); Map f = new HashMap<>(); @@ -553,11 +548,13 @@ public void testConstructor() { f.put(x, eis); - SubstringDomain third = new SubstringDomain(new ExpressionInverseSet(), f); + SubstringDomain second = new SubstringDomain(new ExpressionInverseSet(), f); assertTrue(first.isBottom()); - assertTrue(second.isBottom()); - assertTrue(third.getState(x).contains(y)); + assertTrue(second.getState(x).contains(y)); + + assertTrue(new SubstringDomain().top().isTop()); + assertTrue(new SubstringDomain().bottom().isBottom()); } @Test @@ -579,65 +576,73 @@ public void testForgetIdentifier() throws SemanticException { } @Test - public void testLub1() throws SemanticException { - SubstringDomain lub = domainA.lub(domainB); + public void testGlb1() throws SemanticException { + SubstringDomain glb = domainA.glb(domainB); - assertFalse(lub.getState(x).contains(y)); - assertFalse(lub.getState(y).contains(z)); - assertTrue(lub.getState(x).contains(w)); + assertTrue(glb.getState(x).contains(y)); + assertTrue(glb.getState(y).contains(z)); + assertTrue(glb.getState(x).contains(w)); + assertTrue(glb.getState(x).contains(z)); } @Test - public void testLub2() throws SemanticException { - SubstringDomain lub = domainA.lub(TOP); + public void testGlb2() throws SemanticException { + SubstringDomain glb = domainA.glb(TOP); - assertTrue(lub.isTop()); + assertEquals(glb, domainA); } @Test - public void testLub3() throws SemanticException { - SubstringDomain lub = BOTTOM.lub(domainA); + public void testGlb3() throws SemanticException { + SubstringDomain glb = BOTTOM.glb(domainA); - assertEquals(lub, domainA); + assertEquals(glb, BOTTOM); } @Test - public void testLub4() throws SemanticException { - SubstringDomain lub = domainC.lub(domainD); + public void testGlb4() throws SemanticException { + SubstringDomain glb = domainC.glb(domainD); - assertTrue(lub.isBottom()); + assertTrue(glb.getState(x).contains(z)); + assertTrue(glb.getState(y).contains(w)); } @Test - public void testGlb1() throws SemanticException { - SubstringDomain glb = domainA.glb(domainB); + public void testLub1() throws SemanticException { + SubstringDomain lub = domainA.lub(domainB); - assertTrue(glb.getState(x).contains(y)); - assertTrue(glb.getState(y).contains(z)); - assertTrue(glb.getState(x).contains(w)); - assertTrue(glb.getState(x).contains(z)); + assertFalse(lub.getState(x).contains(y)); + assertFalse(lub.getState(y).contains(z)); + assertEquals(lub.getState(y), lub.stateOfUnknown(y)); + assertTrue(lub.getState(x).contains(w)); } @Test - public void testGlb2() throws SemanticException { - SubstringDomain glb = TOP.glb(domainA); + public void testLub2() throws SemanticException { + SubstringDomain lub = TOP.lub(domainA); - assertTrue(glb.equals(domainA)); + assertEquals(lub, TOP); } @Test - public void testGlb3() throws SemanticException { - SubstringDomain glb = BOTTOM.glb(domainA); + public void testLub3() throws SemanticException { + SubstringDomain lub = BOTTOM.lub(domainA); - assertEquals(glb, BOTTOM); + assertEquals(lub, domainA); } @Test - public void testGlb4() throws SemanticException { - SubstringDomain glb = domainC.glb(domainD); + public void testLub4() throws SemanticException { + SubstringDomain lub = domainC.lub(domainD); - assertTrue(glb.getState(x).contains(z)); - assertTrue(glb.getState(y).contains(w)); + assertEquals(lub, BOTTOM); } + + @Test + public void testLub5() throws SemanticException { + SubstringDomain lub = domainA.lub(domainC); + + assertEquals(lub, BOTTOM); + } } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 59b64ca4f..efbdc81db 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -121,7 +121,7 @@ public void testSubstringDomain() { conf.testDir = "string"; conf.testSubDir = "subs-domain"; conf.programFile = "strings-subs.imp"; - conf.analysisGraphs = GraphType.DOT; + //conf.analysisGraphs = GraphType.DOT; perform(conf); } diff --git a/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java b/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java index 435a9bfb6..696606e76 100644 --- a/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java +++ b/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java @@ -47,7 +47,7 @@ public ExpressionInverseSet( */ public ExpressionInverseSet( Set set) { - this(set, false); + this(Collections.unmodifiableSet(set), false); } private ExpressionInverseSet( @@ -113,6 +113,9 @@ public ExpressionInverseSet lubAux( id2) -> id1.getName().equals(id2.getName()), ExpressionInverseSet::wrapper); idlub.forEach(lub::add); + + if (lub.isEmpty()) + return top(); return new ExpressionInverseSet(lub); } From 79a633091ea4ccfd543769a9f43b44dbddac4551 Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Fri, 5 Apr 2024 13:08:52 +0200 Subject: [PATCH 08/34] Bug fix for simple substring domain. Finished simple substring domain. --- .../imp-testcases/string/strings-subs.imp | 10 +++++---- .../string/subs-domain/report.json | 10 ++++----- ...s.branching(strings__this,_untyped_x).json | 2 +- ...ntyped_strings.iftest1(strings__this).json | 2 +- ...yped_strings.iftestand(strings__this).json | 2 +- .../lisa/analysis/string/SubstringDomain.java | 21 ++++++++++--------- .../analysis/string/SubstringDomainTest.java | 12 ++++++++++- 7 files changed, 36 insertions(+), 23 deletions(-) diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp index 5061d5063..05da21ad5 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp @@ -2,7 +2,7 @@ class strings { iftest1() { def str = "a"; - if (strstarts(str, "a")) + if (strstarts(str, "c")) str = str + " true"; else str = "false"; @@ -18,10 +18,10 @@ class strings { iftestand(){ def str = "string"; - if ((strends(str, "ng")) && (streq(str, "ong"))) - def x = "ong"; + if ((strends(str, "o")) && (streq(str, "ing"))) + def x = "x"; else - def y = "no"; + def y = "y"; } iftestor(){ @@ -80,6 +80,8 @@ class strings { a = "hello"; else a = "world"; + + def b = a; } assume(x) { diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json index 9c8064a95..4373b4f83 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json @@ -3,15 +3,15 @@ "files" : [ "report.json", "untyped_strings.assume(strings__this,_untyped_x).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this,_untyped_x).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.closure4(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json" ], "info" : { "cfgs" : "13", - "duration" : "41ms", - "end" : "2024-03-30T19:30:59.858+01:00", - "expressions" : "120", + "duration" : "34ms", + "end" : "2024-04-05T13:00:03.612+02:00", + "expressions" : "122", "files" : "13", "globals" : "0", "members" : "13", "programs" : "1", - "start" : "2024-03-30T19:30:59.817+01:00", - "statements" : "63", + "start" : "2024-04-05T13:00:03.578+02:00", + "statements" : "64", "units" : "1", "version" : "0.1b9", "warnings" : "0" diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json index f80c5d02b..5d91e9303 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json @@ -1 +1 @@ -{"name":"untyped strings::branching(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = \"abc\""},{"id":1,"text":"a"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"==(x, 2)"},{"id":4,"text":"x"},{"id":5,"text":"2"},{"id":6,"subNodes":[7,8],"text":"a = \"hello\""},{"id":7,"text":"a"},{"id":8,"text":"\"hello\""},{"id":9,"subNodes":[10,11],"text":"a = \"world\""},{"id":10,"text":"a"},{"id":11,"text":"\"world\""},{"id":12,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":1,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x == 2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":5,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":6,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"hello\""]}}}},{"nodeId":7,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":8,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":9,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"world\""]}}}},{"nodeId":10,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":11,"description":{"expressions":["\"world\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":12,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}}]} \ No newline at end of file +{"name":"untyped strings::branching(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = \"abc\""},{"id":1,"text":"a"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"==(x, 2)"},{"id":4,"text":"x"},{"id":5,"text":"2"},{"id":6,"subNodes":[7,8],"text":"a = \"hello\""},{"id":7,"text":"a"},{"id":8,"text":"\"hello\""},{"id":9,"subNodes":[10,11],"text":"a = \"world\""},{"id":10,"text":"a"},{"id":11,"text":"\"world\""},{"id":12,"subNodes":[13,14],"text":"b = a"},{"id":13,"text":"b"},{"id":14,"text":"a"},{"id":15,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":15,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":1,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x == 2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":5,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":6,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"hello\""]}}}},{"nodeId":7,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":8,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":9,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"world\""]}}}},{"nodeId":10,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":11,"description":{"expressions":["\"world\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":12,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["a"]}}}},{"nodeId":13,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":14,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":15,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["a"]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json index e2fb42548..eb0ef1536 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::iftest1(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"a\""},{"id":1,"text":"str"},{"id":2,"text":"\"a\""},{"id":3,"subNodes":[4,5],"text":"startsWith(str, \"a\")"},{"id":4,"text":"str"},{"id":5,"text":"\"a\""},{"id":6,"subNodes":[7,8],"text":"str = +(str, \" true\")"},{"id":7,"text":"str"},{"id":8,"subNodes":[9,10],"text":"+(str, \" true\")"},{"id":9,"text":"str"},{"id":10,"text":"\" true\""},{"id":11,"subNodes":[12,13],"text":"str = \"false\""},{"id":12,"text":"str"},{"id":13,"text":"\"false\""},{"id":14,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":11,"kind":"FalseEdge"},{"sourceId":6,"destId":14,"kind":"SequentialEdge"},{"sourceId":11,"destId":14,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strstarts \"a\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":4,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":5,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":6,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\" true\"","\"a\""]}}}},{"nodeId":7,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":8,"description":{"expressions":["str strcat \" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":9,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":10,"description":{"expressions":["\" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":11,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"false\""]}}}},{"nodeId":12,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":13,"description":{"expressions":["\"false\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":14,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":"#TOP#"}}}]} \ No newline at end of file +{"name":"untyped strings::iftest1(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"a\""},{"id":1,"text":"str"},{"id":2,"text":"\"a\""},{"id":3,"subNodes":[4,5],"text":"startsWith(str, \"c\")"},{"id":4,"text":"str"},{"id":5,"text":"\"c\""},{"id":6,"subNodes":[7,8],"text":"str = +(str, \" true\")"},{"id":7,"text":"str"},{"id":8,"subNodes":[9,10],"text":"+(str, \" true\")"},{"id":9,"text":"str"},{"id":10,"text":"\" true\""},{"id":11,"subNodes":[12,13],"text":"str = \"false\""},{"id":12,"text":"str"},{"id":13,"text":"\"false\""},{"id":14,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":11,"kind":"FalseEdge"},{"sourceId":6,"destId":14,"kind":"SequentialEdge"},{"sourceId":11,"destId":14,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strstarts \"c\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":4,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":5,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":6,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\" true\"","\"a\"","\"c\""]}}}},{"nodeId":7,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":8,"description":{"expressions":["str strcat \" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":9,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":10,"description":{"expressions":["\" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":11,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"false\""]}}}},{"nodeId":12,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":13,"description":{"expressions":["\"false\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":14,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":"#TOP#"}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json index 1237799b2..cd6d4b99e 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::iftestand(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"string\""},{"id":1,"text":"str"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,7],"text":"&&(endsWith(str, \"ng\"), equals(str, \"ong\"))"},{"id":4,"subNodes":[5,6],"text":"endsWith(str, \"ng\")"},{"id":5,"text":"str"},{"id":6,"text":"\"ng\""},{"id":7,"subNodes":[8,9],"text":"equals(str, \"ong\")"},{"id":8,"text":"str"},{"id":9,"text":"\"ong\""},{"id":10,"subNodes":[11,12],"text":"x = \"ong\""},{"id":11,"text":"x"},{"id":12,"text":"\"ong\""},{"id":13,"subNodes":[14,15],"text":"y = \"no\""},{"id":14,"text":"y"},{"id":15,"text":"\"no\""},{"id":16,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":10,"kind":"TrueEdge"},{"sourceId":3,"destId":13,"kind":"FalseEdge"},{"sourceId":10,"destId":16,"kind":"SequentialEdge"},{"sourceId":13,"destId":16,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"ng\" && str strcmp \"ong\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":4,"description":{"expressions":["str strends \"ng\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":5,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":6,"description":{"expressions":["\"ng\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":7,"description":{"expressions":["str strcmp \"ong\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":8,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":9,"description":{"expressions":["\"ong\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"]},"value":{"str":["\"ng\"","\"ong\"","\"string\"","x"],"x":["\"ong\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"ng\"","\"ong\"","\"string\""]}}}},{"nodeId":12,"description":{"expressions":["\"ong\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"ng\"","\"ong\"","\"string\""]}}}},{"nodeId":13,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"y":["string"]},"value":{"str":["\"string\""],"y":["\"no\""]}}}},{"nodeId":14,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":15,"description":{"expressions":["\"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":16,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"str":["\"string\""]}}}}]} \ No newline at end of file +{"name":"untyped strings::iftestand(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"string\""},{"id":1,"text":"str"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,7],"text":"&&(endsWith(str, \"o\"), equals(str, \"ing\"))"},{"id":4,"subNodes":[5,6],"text":"endsWith(str, \"o\")"},{"id":5,"text":"str"},{"id":6,"text":"\"o\""},{"id":7,"subNodes":[8,9],"text":"equals(str, \"ing\")"},{"id":8,"text":"str"},{"id":9,"text":"\"ing\""},{"id":10,"subNodes":[11,12],"text":"x = \"x\""},{"id":11,"text":"x"},{"id":12,"text":"\"x\""},{"id":13,"subNodes":[14,15],"text":"y = \"y\""},{"id":14,"text":"y"},{"id":15,"text":"\"y\""},{"id":16,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":10,"kind":"TrueEdge"},{"sourceId":3,"destId":13,"kind":"FalseEdge"},{"sourceId":10,"destId":16,"kind":"SequentialEdge"},{"sourceId":13,"destId":16,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"o\" && str strcmp \"ing\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":4,"description":{"expressions":["str strends \"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":5,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":6,"description":{"expressions":["\"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":7,"description":{"expressions":["str strcmp \"ing\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":8,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":9,"description":{"expressions":["\"ing\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"]},"value":{"str":["\"ing\"","\"o\"","\"string\""],"x":["\"x\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"ing\"","\"o\"","\"string\""]}}}},{"nodeId":12,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"ing\"","\"o\"","\"string\""]}}}},{"nodeId":13,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"y":["string"]},"value":{"str":["\"string\""],"y":["\"y\""]}}}},{"nodeId":14,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":15,"description":{"expressions":["\"y\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":16,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"str":["\"string\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index 0550114a4..684b64863 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -1,6 +1,5 @@ package it.unive.lisa.analysis.string; -import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -85,9 +84,9 @@ public SubstringDomain assign(Identifier id, ValueExpression expression, Program result = result.add(identifiers, id); - result = result.interasg(id); + result = result.interasg(id, expression); - result = result.closure(id); + result = result.closure(); return result.clear(); } @@ -352,21 +351,19 @@ private SubstringDomain remove(Set extracted, Identifier id) return mk(lattice, newFunction); } - private SubstringDomain interasg(Identifier id) throws SemanticException { + private SubstringDomain interasg(Identifier assignedId, SymbolicExpression assignedExpression) throws SemanticException { Map newFunction = mkNewFunction(function, false); - if (!knowsIdentifier(id)) + if (!knowsIdentifier(assignedId)) return this; - ExpressionInverseSet compare = function.get(id); - for (Map.Entry entry : function.entrySet()) { - if (entry.getKey().equals(id)) + if (entry.getKey().equals(assignedId)) continue; - if ((entry.getValue().lub(compare)).equals(compare)) { + if (entry.getValue().contains(assignedExpression)) { Set newRelation = new HashSet<>(); - newRelation.add(id); + newRelation.add(assignedId); ExpressionInverseSet newSet = newFunction.get(entry.getKey()).glb(new ExpressionInverseSet(newRelation)); newFunction.put(entry.getKey(), newSet); @@ -378,6 +375,8 @@ private SubstringDomain interasg(Identifier id) throws SemanticException { } private SubstringDomain closure(Identifier id) throws SemanticException { + if (isTop() || isBottom()) + return this; SubstringDomain result = mk(lattice, mkNewFunction(function, false)); @@ -404,6 +403,8 @@ private SubstringDomain closure(Identifier id) throws SemanticException { } private SubstringDomain closure() throws SemanticException { + if (isTop() || isBottom()) + return this; SubstringDomain prev; SubstringDomain result = mk(lattice, mkNewFunction(function, false)); diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 3e4c2e8eb..2aaa236ed 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -417,6 +417,16 @@ public void testAssignEmptyDomain8() throws SemanticException{ assertTrue(assigned.getState(x).contains(c)); assertFalse(assigned.getState(y).contains(c)); } + + @Test + public void testAssignEmptyDomain9() throws SemanticException{ + SubstringDomain empty = new SubstringDomain(); + + SubstringDomain assigned = empty.assign(x, c, null, null); + assigned = assigned.assign(y, x, null, null); + + + } @Test public void testAssign1() throws SemanticException { @@ -467,7 +477,7 @@ public void testAssign6() throws SemanticException { assertTrue(assigned.getState(x).contains(w)); assertTrue(assigned.getState(z).contains(w)); assertTrue(assigned.getState(z).contains(y)); - assertTrue(assigned.getState(x).contains(z)); + assertFalse(assigned.getState(x).contains(z)); } @Test From 5f63c6e11bcf2bfb2a5515bd6fcd677e071b4c47 Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Tue, 9 Apr 2024 00:07:13 +0200 Subject: [PATCH 09/34] Extended domain to string expressions + tests for extended domain --- .../imp-testcases/string/strings-subs.imp | 55 ++++- .../lisa/analysis/string/SubstringDomain.java | 184 +++++++++++++++-- .../analysis/string/SubstringDomainTest.java | 190 ++++++++++++++++++ .../unive/lisa/cron/StringAnalysesTest.java | 2 +- 4 files changed, 399 insertions(+), 32 deletions(-) diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp index 05da21ad5..38d1a33c4 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp @@ -1,5 +1,9 @@ class strings { + stringconcat(){ + def str = "a" + "b" + "c"; + } + iftest1() { def str = "a"; if (strstarts(str, "c")) @@ -37,14 +41,7 @@ class strings { def z = y; } - closure2(x) { - def j = "j"; - def w = j; - def y = x; - x = w; - } - - closure3() { + closure2() { def j = "j"; def w = j; def x = "x"; @@ -52,7 +49,7 @@ class strings { x = w; } - closure4() { + closure3() { def w = "w"; def z = "z" + w; def y = "y"; @@ -84,7 +81,8 @@ class strings { def b = a; } - assume(x) { + assume() { + def x = ""; def b = "abc"; if (strcon(x, b)) b = "hello"; @@ -99,4 +97,41 @@ class strings { str = str + "a"; } } + + paper1(){ + def x = "ab"; + def y = "a"; + def z = "b"; + def w = y + z; + } + + paper2(){ + def x = ""; + def y = ""; + if (streq(x, y)) + x = x + "c"; + else + x = y + "c"; + } + + + paper3(x){ + def v = ""; + if (x % 2) + v = "abc"; + else + v = "def"; + + def r = "Elem: \n" + v + "\n"; + for (def i = 0; i < 20; i = i + 1){ + if (x % 2) + v = "abc"; + else + v = "def"; + + r = r + v + "\n"; + } + } + + } \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index 684b64863..e6a0533fb 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -1,6 +1,9 @@ package it.unive.lisa.analysis.string; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Predicate; @@ -13,6 +16,7 @@ import it.unive.lisa.analysis.lattices.FunctionalLattice; import it.unive.lisa.analysis.lattices.Satisfiability; import it.unive.lisa.analysis.value.ValueDomain; +import it.unive.lisa.program.SyntheticLocation; import it.unive.lisa.program.cfg.ProgramPoint; import it.unive.lisa.symbolic.SymbolicExpression; import it.unive.lisa.symbolic.value.BinaryExpression; @@ -28,6 +32,9 @@ import it.unive.lisa.symbolic.value.operator.binary.StringEndsWith; import it.unive.lisa.symbolic.value.operator.binary.StringEquals; import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; +import it.unive.lisa.type.StringType; +import it.unive.lisa.type.Type; + public class SubstringDomain extends FunctionalLattice implements ValueDomain { @@ -76,6 +83,7 @@ public SubstringDomain mk(ExpressionInverseSet lattice, Map identifiers = extrPlus(expression); SubstringDomain result = mk(lattice, mkNewFunction(function, false)); @@ -100,6 +108,7 @@ public SubstringDomain smallStepSemantics(ValueExpression expression, ProgramPoi @Override public SubstringDomain assume(ValueExpression expression, ProgramPoint src, ProgramPoint dest, SemanticOracle oracle) throws SemanticException { + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); @@ -216,6 +225,7 @@ public SubstringDomain forgetIdentifiersIf(Predicate test) throws Se @Override public Satisfiability satisfies(ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) throws SemanticException { + if (isBottom() || !(expression instanceof BinaryExpression)) return Satisfiability.UNKNOWN; @@ -232,12 +242,14 @@ public Satisfiability satisfies(ValueExpression expression, ProgramPoint pp, Sem return getState((Identifier) left).contains(right) ? Satisfiability.SATISFIED : Satisfiability.UNKNOWN; } else if (binaryOperator instanceof StringEquals || binaryOperator instanceof StringEndsWith || binaryOperator instanceof StringStartsWith) { + //******* if (!(left instanceof Variable) || !(right instanceof Variable)) return Satisfiability.UNKNOWN; return (getState((Identifier) left).contains(right)) && (getState((Identifier) right).contains(left)) ? Satisfiability.SATISFIED : Satisfiability.UNKNOWN; + //****** } else if (binaryOperator instanceof LogicalOr) { if (!(left instanceof ValueExpression) || !(right instanceof ValueExpression)) throw new SemanticException("!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); @@ -276,14 +288,14 @@ public SubstringDomain popScope(ScopeToken token) throws SemanticException { return new SubstringDomain(lattice.popScope(token), mkNewFunction(function, true)); } - private static Set extr(ValueExpression expression) throws SemanticException{ + private static List extr(ValueExpression expression) throws SemanticException{ - Set result = new HashSet<>(); + List result = new ArrayList<>(); if (expression instanceof BinaryExpression) { BinaryExpression binaryExpression = (BinaryExpression) expression; BinaryOperator binaryOperator = binaryExpression.getOperator(); if (!(binaryOperator instanceof StringConcat)) - throw new SemanticException("!(binaryOperator instanceof StringConcat)"); + return Collections.emptyList(); ValueExpression left = (ValueExpression) binaryExpression.getLeft(); ValueExpression right = (ValueExpression) binaryExpression.getRight(); @@ -298,21 +310,161 @@ private static Set extr(ValueExpression expression) throws S } private static Set extrPlus(ValueExpression expression) throws SemanticException{ - Set result = extr(expression); + List extracted = extr(expression); + + extracted = mergeStringLiterals(extracted); + + Set result = new HashSet<>(); + + for (int l = 1; l <= extracted.size(); l++) { + for (int i = 0; i <= (extracted.size() - l); i++) { + List subList = extracted.subList(i, i+l); + result.add(composeExpression(subList)); + + if (subList.size() == 1 && subList.get(0) instanceof Constant) { + Set substrings = getSubstrings((Constant) subList.get(0)); + + for (SymbolicExpression substring : substrings) { + List newList = new ArrayList<>(); + newList.add(substring); + + result.add(composeExpression(newList)); + + } + } else if (subList.get(0) instanceof Constant) { + Set suffixes = getSuffix((Constant) subList.get(0)); + + for (SymbolicExpression suffix : suffixes) { + List newList = new ArrayList<>(subList); + newList.set(0, suffix); + + + if (subList.get(subList.size() - 1) instanceof Constant) { + Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); + + for (SymbolicExpression prefix : prefixes) { + newList.set(newList.size() - 1, prefix); + + result.add(composeExpression(newList)); + } + } else + result.add(composeExpression(newList)); + + + } + } else if (subList.get(subList.size() - 1) instanceof Constant) { + Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); + + for (SymbolicExpression prefix : prefixes) { + List newList = new ArrayList<>(subList); + newList.set(newList.size() - 1, prefix); + + result.add(composeExpression(newList)); + } + } + + + } + } + + return new HashSet<>(result); + } + + private static List mergeStringLiterals(List extracted){ + List result = new ArrayList<>(); + StringBuilder recent = new StringBuilder(); + Type stringType = null; + + for (SymbolicExpression expr : extracted) { + if (expr instanceof Constant) { + Constant c = (Constant) expr; + stringType = expr.getStaticType(); + recent.append(c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString()); + + + } else { + if (!recent.isEmpty()) { + result.add(new Constant(stringType, recent.toString(), SyntheticLocation.INSTANCE)); + recent.delete(0, recent.length()); + } + result.add(expr); + } + } + + + if (!recent.isEmpty()) + result.add(new Constant(stringType, recent.toString(), SyntheticLocation.INSTANCE)); + + return result; + } + + private static Set getSubstrings(Constant c){ + Set result = new HashSet<>(); + + String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); + for (int l = 1; l < str.length(); l++) { + for (int i=0; i <= str.length() - l; i++) { + ValueExpression substring = new Constant(c.getStaticType(), str.substring(i, i+l), SyntheticLocation.INSTANCE); + + result.add(substring); + } + } return result; } + private static Set getPrefix(Constant c){ + Set result = new HashSet<>(); + + String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); + for (int i = 1; i <= str.length(); i++) { + ValueExpression prefix = new Constant(c.getStaticType(), str.substring(0, i), SyntheticLocation.INSTANCE); + + result.add(prefix); + } + + return result; + } + + private static Set getSuffix(Constant c){ + Set result = new HashSet<>(); + + String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); + int length = str.length(); + for (int i = 1; i <= length; i++) { + ValueExpression suffix = new Constant(c.getStaticType(), str.substring(length - i, length), SyntheticLocation.INSTANCE); + + result.add(suffix); + } + + return result; + } + + private static SymbolicExpression composeExpression(List expressions) { + if (expressions.size() == 1) + return expressions.get(0); + + return new BinaryExpression(expressions.get(0).getStaticType(), expressions.get(0), composeExpression(expressions.subList(1, expressions.size())), StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + } + + private SubstringDomain add(Set symbolicExpressions, Identifier id) throws SemanticException{ Map newFunction = mkNewFunction(function, false); - symbolicExpressions.remove(id); - if (symbolicExpressions.isEmpty()) + Set expressionsToRemove = new HashSet<>(); + for (SymbolicExpression se : symbolicExpressions) { + if (!appears(id, se)) + expressionsToRemove.add(se); + } + //symbolicExpressions.remove(id); + + + if (expressionsToRemove.isEmpty()) return this; - ExpressionInverseSet newSet = new ExpressionInverseSet(symbolicExpressions); + ExpressionInverseSet newSet = new ExpressionInverseSet(expressionsToRemove); if (!(newFunction.get(id) == null)) newSet = newSet.glb(newFunction.get(id)); @@ -328,18 +480,10 @@ private SubstringDomain remove(Set extracted, Identifier id) if(!extracted.contains(id)) { // x = x + ..... --> keep relations for x newFunction.remove(id); } - - Set expressionsToRemove = new HashSet<>(); - for (SymbolicExpression expression : extracted) { - if (appears(id, expression)) - expressionsToRemove.add(expression); - } - - expressionsToRemove.add(id); - + for (Map.Entry entry : newFunction.entrySet()) { Set newSet = entry.getValue().elements.stream() - .filter(element -> !expressionsToRemove.contains(element)) + .filter(element -> !appears(id, element)) .collect(Collectors.toSet()); ExpressionInverseSet value = newSet.isEmpty() ? new ExpressionInverseSet().top() : new ExpressionInverseSet(newSet); @@ -440,7 +584,7 @@ private SubstringDomain clear() throws SemanticException { return result; } - private static boolean appears(Identifier id, SymbolicExpression expr) throws SemanticException { + private static boolean appears(Identifier id, SymbolicExpression expr) { if (expr instanceof Identifier) return id.equals(expr); @@ -455,10 +599,8 @@ private static boolean appears(Identifier id, SymbolicExpression expr) throws Se return appears(id, left) || appears(id, right); } - throw new SemanticException("Invalid expression"); + return false; - - } } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 2aaa236ed..103e799bc 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -38,7 +38,13 @@ public class SubstringDomainTest { Identifier z = new Variable(StringType.INSTANCE, "z", SyntheticLocation.INSTANCE); Identifier w = new Variable(StringType.INSTANCE, "w", SyntheticLocation.INSTANCE); + ValueExpression a = new Constant(StringType.INSTANCE, "a", SyntheticLocation.INSTANCE); + ValueExpression b = new Constant(StringType.INSTANCE, "b", SyntheticLocation.INSTANCE); ValueExpression c = new Constant(StringType.INSTANCE, "c", SyntheticLocation.INSTANCE); + ValueExpression ab = new Constant(StringType.INSTANCE, "ab", SyntheticLocation.INSTANCE); + ValueExpression bc = new Constant(StringType.INSTANCE, "bc", SyntheticLocation.INSTANCE); + ValueExpression abc = new Constant(StringType.INSTANCE, "abc", SyntheticLocation.INSTANCE); + SubstringDomain domainA; SubstringDomain domainB; @@ -68,6 +74,13 @@ public class SubstringDomainTest { ValueExpression ZConcatX = new BinaryExpression(StringType.INSTANCE, z, x, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); ValueExpression ZConcatXConcatY = new BinaryExpression(StringType.INSTANCE, z, XConcatY, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XConcatAB = new BinaryExpression(StringType.INSTANCE, x, ab, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XConcatA = new BinaryExpression(StringType.INSTANCE, x, a, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XConcatBC = new BinaryExpression(StringType.INSTANCE, x, bc, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XConcatABC = new BinaryExpression(StringType.INSTANCE, x, abc, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XConcatABCConcatY = new BinaryExpression(StringType.INSTANCE, XConcatABC, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression CSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, c, StringContains.INSTANCE, SyntheticLocation.INSTANCE); ValueExpression XSubstringOfC = new BinaryExpression(BoolType.INSTANCE, c, x, StringContains.INSTANCE, SyntheticLocation.INSTANCE); @@ -544,6 +557,183 @@ public void testAssign12() throws SemanticException { assertTrue(assigned.getState(y).contains(x)); } + @Test + public void testEmptyAssignComplex1() throws SemanticException { + ValueExpression ZConcatY = new BinaryExpression(StringType.INSTANCE, z, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(w, ZConcatXConcatY, null, null); + + assertTrue(assigned.getState(w).contains(ZConcatX)); + assertTrue(assigned.getState(w).contains(XConcatY)); + assertTrue(assigned.getState(w).contains(ZConcatXConcatY)); + assertTrue(assigned.getState(w).contains(x)); + assertTrue(assigned.getState(w).contains(z)); + assertTrue(assigned.getState(w).contains(y)); + assertFalse(assigned.getState(w).contains(ZConcatY)); + } + + @Test + public void testEmptyAssignComplex2() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(w, XConcatABC, null, null); + + assertTrue(assigned.getState(w).contains(XConcatABC)); + assertTrue(assigned.getState(w).contains(x)); + assertTrue(assigned.getState(w).contains(abc)); + assertTrue(assigned.getState(w).contains(ab)); + assertTrue(assigned.getState(w).contains(bc)); + assertTrue(assigned.getState(w).contains(a)); + assertTrue(assigned.getState(w).contains(b)); + assertTrue(assigned.getState(w).contains(XConcatA)); + assertTrue(assigned.getState(w).contains(XConcatAB)); + assertFalse(assigned.getState(w).contains(XConcatBC)); + + } + + @Test + public void testEmptyAssignComplex3() throws SemanticException{ + ValueExpression abcd = new Constant(StringType.INSTANCE, "abcd", SyntheticLocation.INSTANCE); + ValueExpression ab = new Constant(StringType.INSTANCE, "ab", SyntheticLocation.INSTANCE); + ValueExpression cd = new Constant(StringType.INSTANCE, "cd", SyntheticLocation.INSTANCE); + ValueExpression ABConcatCD = new BinaryExpression(StringType.INSTANCE, ab, cd, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned1 = empty.assign(x, abcd, null, null); + SubstringDomain assigned2 = empty.assign(x, ABConcatCD, null, null); + + assertEquals(assigned1, assigned2); + } + + @Test + public void testEmptyAssignComplex4() throws SemanticException{ + ValueExpression ab = new Constant(StringType.INSTANCE, "ab", SyntheticLocation.INSTANCE); + ValueExpression cd = new Constant(StringType.INSTANCE, "cd", SyntheticLocation.INSTANCE); + ValueExpression ABConcatY = new BinaryExpression(StringType.INSTANCE, ab, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression ABConcatYConcatCD = new BinaryExpression(StringType.INSTANCE, ABConcatY, cd, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, ABConcatYConcatCD, null, null); + + assertTrue(assigned.getState(x).size() == 15); + } + + @Test + public void testEmptyAssignComplex5() throws SemanticException{ + ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression YConcatWConcatAB = new BinaryExpression(StringType.INSTANCE, YConcatW, ab, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression WConcatA = new BinaryExpression(StringType.INSTANCE, w, a, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, YConcatWConcatAB, null, null); + + assertTrue(assigned.getState(x).contains(y)); + assertTrue(assigned.getState(x).contains(w)); + assertTrue(assigned.getState(x).contains(a)); + assertTrue(assigned.getState(x).contains(b)); + assertTrue(assigned.getState(x).contains(ab)); + assertTrue(assigned.getState(x).contains(YConcatW)); + assertTrue(assigned.getState(x).contains(WConcatA)); + } + + @Test + public void testEmptyAssignComplex6() throws SemanticException{ + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, c, null, null); + assigned = assigned.assign(x, ZConcatX, null, null); + + assertTrue(assigned.getState(x).contains(c)); + + assigned = assigned.assign(x, w, null, null); + + assertTrue(assigned.getState(x).contains(w) && assigned.getState(x).size() == 1); + } + + @Test + public void testEmptyAssignComplex7() throws SemanticException{ + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(y, ZConcatX, null, null); + assigned = assigned.assign(x, c, null, null); + + assertFalse(assigned.getState(y).contains(x)); + assertFalse(assigned.getState(y).contains(ZConcatX)); + + } + + @Test + public void testEmptyInterAssignComplex() throws SemanticException{ + ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression YConcatWConcatAB = new BinaryExpression(StringType.INSTANCE, YConcatW, ab, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression WConcatA = new BinaryExpression(StringType.INSTANCE, w, a, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, YConcatWConcatAB, null, null); + assigned = assigned.assign(y, WConcatA, null, null); + + assertTrue(assigned.getState(x).contains(y)); + } + + @Test + public void testEmptyInterAssignComplex2() throws SemanticException{ + SubstringDomain empty = new SubstringDomain(); + ValueExpression WConcatC = new BinaryExpression(StringType.INSTANCE, w, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain assigned = empty.assign(x, WConcatC, null, null); + assigned = assigned.assign(x, ZConcatX, null, null); + assigned = assigned.assign(y, ZConcatX, null, null); + + + assertTrue(assigned.getState(y).contains(x)); + assertTrue(assigned.getState(y).contains(c)); + assertTrue(assigned.getState(y).contains(WConcatC)); + } + + @Test + public void testAssumeComplex1() throws SemanticException{ + ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, x, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, YConcatW, null, null); + assigned = assigned.assume(XSubstringOfY, null, null, null); + + assertTrue(assigned.getState(y).contains(x)); + assertTrue(assigned.getState(y).contains(w)); + assertFalse(assigned.getState(y).contains(YConcatW)); + } + + @Test + public void testAssumeComplex2() throws SemanticException{ + ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression YConcatWSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, YConcatW, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(z, YConcatW, null, null); + assigned = assigned.assume(YConcatWSubstringOfX, null, null, null); + + assertEquals(assigned.getState(x), assigned.getState(z)); + assertFalse(assigned.getState(z).contains(x)); + } + + @Test + public void testAssumeComplex3() throws SemanticException{ + ValueExpression XSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, x, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assigned = empty.assign(x, abc, null, null); + assigned = assigned.assume(XSubstringOfY, null, null, null); + + assertTrue(assigned.getState(y).contains(abc)); + assertTrue(assigned.getState(y).contains(x)); + assertFalse(assigned.getState(x).contains(y)); + + } + @Test public void testConstructor() { SubstringDomain first = new SubstringDomain(); diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index efbdc81db..59b64ca4f 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -121,7 +121,7 @@ public void testSubstringDomain() { conf.testDir = "string"; conf.testSubDir = "subs-domain"; conf.programFile = "strings-subs.imp"; - //conf.analysisGraphs = GraphType.DOT; + conf.analysisGraphs = GraphType.DOT; perform(conf); } From 1a657e2f16813d41950bfebfd69f8e27a7b1c951 Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Tue, 16 Apr 2024 15:11:37 +0200 Subject: [PATCH 10/34] String type is retrieved from type system, spotless apply --- .../lisa/analysis/string/SubstringDomain.java | 550 ++++++++++-------- .../analysis/string/SubstringDomainTest.java | 476 ++++++++------- .../unive/lisa/cron/StringAnalysesTest.java | 7 +- .../lattices/ExpressionInverseSet.java | 2 +- 4 files changed, 569 insertions(+), 466 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index e6a0533fb..c67b23afc 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -1,14 +1,5 @@ package it.unive.lisa.analysis.string; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Predicate; -import java.util.stream.Collectors; - import it.unive.lisa.analysis.ScopeToken; import it.unive.lisa.analysis.SemanticException; import it.unive.lisa.analysis.SemanticOracle; @@ -34,30 +25,50 @@ import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; import it.unive.lisa.type.StringType; import it.unive.lisa.type.Type; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +public class SubstringDomain extends FunctionalLattice + implements + ValueDomain { -public class SubstringDomain extends FunctionalLattice implements ValueDomain { - - public SubstringDomain(ExpressionInverseSet lattice, Map function) { + public SubstringDomain( + ExpressionInverseSet lattice, + Map function) { super(lattice, function); } - - public SubstringDomain(ExpressionInverseSet lattice) { + + public SubstringDomain( + ExpressionInverseSet lattice) { super(lattice); } - + public SubstringDomain() { this(new ExpressionInverseSet()); } - + @Override - public SubstringDomain lubAux(SubstringDomain other) throws SemanticException { - return functionalLift(other, lattice.top(), this::glbKeys, (o1, o2) -> o1.lub(o2)).clear(); + public SubstringDomain lubAux( + SubstringDomain other) + throws SemanticException { + return functionalLift(other, lattice.top(), this::glbKeys, ( + o1, + o2) -> o1.lub(o2)).clear(); } - + @Override - public SubstringDomain glbAux(SubstringDomain other) throws SemanticException { - return functionalLift(other, lattice.top(), this::lubKeys, (o1, o2) -> o1.glb(o2)).closure(); + public SubstringDomain glbAux( + SubstringDomain other) + throws SemanticException { + return functionalLift(other, lattice.top(), this::lubKeys, ( + o1, + o2) -> o1.glb(o2)).closure(); } @Override @@ -71,536 +82,595 @@ public SubstringDomain bottom() { } @Override - public ExpressionInverseSet stateOfUnknown(Identifier key) { + public ExpressionInverseSet stateOfUnknown( + Identifier key) { return lattice.top(); } @Override - public SubstringDomain mk(ExpressionInverseSet lattice, Map function) { + public SubstringDomain mk( + ExpressionInverseSet lattice, + Map function) { return new SubstringDomain(lattice.isBottom() ? lattice.bottom() : lattice.top(), function); } @Override - public SubstringDomain assign(Identifier id, ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) + public SubstringDomain assign( + Identifier id, + ValueExpression expression, + ProgramPoint pp, + SemanticOracle oracle) throws SemanticException { - - Set identifiers = extrPlus(expression); - + + /* + * The string type is unique and can be retrieved from the type system. + */ + Type strType = pp.getProgram().getTypes().getStringType(); + + Set identifiers = extrPlus(expression, strType); + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - + result = result.remove(identifiers, id); - + result = result.add(identifiers, id); - + result = result.interasg(id, expression); - + result = result.closure(); - + return result.clear(); } @Override - public SubstringDomain smallStepSemantics(ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) + public SubstringDomain smallStepSemantics( + ValueExpression expression, + ProgramPoint pp, + SemanticOracle oracle) throws SemanticException { return this; } @Override - public SubstringDomain assume(ValueExpression expression, ProgramPoint src, ProgramPoint dest, - SemanticOracle oracle) throws SemanticException { + public SubstringDomain assume( + ValueExpression expression, + ProgramPoint src, + ProgramPoint dest, + SemanticOracle oracle) + throws SemanticException { - + StringType strType = src.getProgram().getTypes().getStringType(); SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - + if (expression instanceof BinaryExpression) { - + BinaryExpression binaryExpression = (BinaryExpression) expression; BinaryOperator binaryOperator = binaryExpression.getOperator(); - + SymbolicExpression left = binaryExpression.getLeft(); SymbolicExpression right = binaryExpression.getRight(); - - if (binaryOperator instanceof StringContains + + if (binaryOperator instanceof StringContains || binaryOperator instanceof StringStartsWith || binaryOperator instanceof StringEndsWith) { - + if (!(left instanceof Identifier)) return this; - + if (!(right instanceof ValueExpression)) throw new SemanticException("instanceof right"); - - Set extracted = extrPlus((ValueExpression) right); - + + Set extracted = extrPlus((ValueExpression) right, strType); + result = result.add(extracted, (Identifier) left); - + result = result.closure(); - - } else if (binaryOperator instanceof StringEquals){ + + } else if (binaryOperator instanceof StringEquals) { // both are identifiers if ((left instanceof Identifier) && (right instanceof Identifier)) { - result = result.add(extrPlus((ValueExpression) left), (Identifier) right); - result = result.add(extrPlus((ValueExpression) right), (Identifier)left); - + result = result.add(extrPlus((ValueExpression) left, strType), (Identifier) right); + result = result.add(extrPlus((ValueExpression) right, strType), (Identifier) left); + result = result.closure(); } // one is identifier - else if((left instanceof Identifier) || (right instanceof Identifier)) { - - if (right instanceof Identifier) { // left instance of Identifier, right SymbolicExpression + else if ((left instanceof Identifier) || (right instanceof Identifier)) { + + if (right instanceof Identifier) { // left instance of + // Identifier, right + // SymbolicExpression SymbolicExpression temp = left; - left = right; - right = temp; + left = right; + right = temp; } - + if (!(right instanceof ValueExpression)) throw new SemanticException("instanceof right != ValueExpression.class"); - - Set add = extrPlus((ValueExpression) right); - + + Set add = extrPlus((ValueExpression) right, strType); + result = result.add(add, (Identifier) left); - + result = result.closure(); - } - } else if(binaryOperator instanceof LogicalOr || binaryOperator instanceof LogicalAnd){ - + } + } else if (binaryOperator instanceof LogicalOr || binaryOperator instanceof LogicalAnd) { + if (!(left instanceof ValueExpression) || !(right instanceof ValueExpression)) - throw new SemanticException("!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); - + throw new SemanticException( + "!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); + ValueExpression rightValueExpression = (ValueExpression) right; ValueExpression leftValueExpression = (ValueExpression) left; - + SubstringDomain leftDomain = assume(leftValueExpression, src, dest, oracle); - SubstringDomain rightDomain = assume(rightValueExpression, src, dest, oracle); - + SubstringDomain rightDomain = assume(rightValueExpression, src, dest, oracle); + if (binaryOperator instanceof LogicalOr) { result = leftDomain.lub(rightDomain); } else { result = leftDomain.glb(rightDomain); } } - + } - + return result.clear(); } @Override - public boolean knowsIdentifier(Identifier id) { + public boolean knowsIdentifier( + Identifier id) { if (id == null || function == null) return false; - + if (function.containsKey(id)) return true; - - return false; + + return false; } @Override - public SubstringDomain forgetIdentifier(Identifier id) throws SemanticException { + public SubstringDomain forgetIdentifier( + Identifier id) + throws SemanticException { if (!knowsIdentifier(id)) return this; - - Map newFunction = mkNewFunction(function, false); //function != null - + + Map newFunction = mkNewFunction(function, false); // function + // != + // null + newFunction.remove(id); - + return mk(lattice, newFunction); } @Override - public SubstringDomain forgetIdentifiersIf(Predicate test) throws SemanticException { + public SubstringDomain forgetIdentifiersIf( + Predicate test) + throws SemanticException { if (function == null || function.keySet().isEmpty()) return this; - - Map newFunction = mkNewFunction(function, false); //function != null - + + Map newFunction = mkNewFunction(function, false); // function + // != + // null + Set keys = newFunction.keySet().stream().filter(test::test).collect(Collectors.toSet()); - + keys.forEach(newFunction::remove); - + return mk(lattice, newFunction); } @Override - public Satisfiability satisfies(ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) + public Satisfiability satisfies( + ValueExpression expression, + ProgramPoint pp, + SemanticOracle oracle) throws SemanticException { - + if (isBottom() || !(expression instanceof BinaryExpression)) return Satisfiability.UNKNOWN; - - + BinaryExpression binaryExpression = (BinaryExpression) expression; BinaryOperator binaryOperator = binaryExpression.getOperator(); - + SymbolicExpression left = binaryExpression.getLeft(); SymbolicExpression right = binaryExpression.getRight(); - + if (binaryOperator instanceof StringContains) { if (!(left instanceof Variable)) return Satisfiability.UNKNOWN; - + return getState((Identifier) left).contains(right) ? Satisfiability.SATISFIED : Satisfiability.UNKNOWN; - } else if (binaryOperator instanceof StringEquals || binaryOperator instanceof StringEndsWith || binaryOperator instanceof StringStartsWith) { - //******* + } else if (binaryOperator instanceof StringEquals || binaryOperator instanceof StringEndsWith + || binaryOperator instanceof StringStartsWith) { + // ******* if (!(left instanceof Variable) || !(right instanceof Variable)) return Satisfiability.UNKNOWN; - - return (getState((Identifier) left).contains(right)) && (getState((Identifier) right).contains(left)) - ? Satisfiability.SATISFIED + + return (getState((Identifier) left).contains(right)) && (getState((Identifier) right).contains(left)) + ? Satisfiability.SATISFIED : Satisfiability.UNKNOWN; - //****** + // ****** } else if (binaryOperator instanceof LogicalOr) { if (!(left instanceof ValueExpression) || !(right instanceof ValueExpression)) - throw new SemanticException("!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); + throw new SemanticException( + "!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); Satisfiability leftSatisfiability = satisfies((ValueExpression) left, pp, oracle); - + if (leftSatisfiability.equals(Satisfiability.SATISFIED)) return Satisfiability.SATISFIED; - + Satisfiability rightSatisfiability = satisfies((ValueExpression) right, pp, oracle); - + return rightSatisfiability; - + } else if (binaryOperator instanceof LogicalAnd) { if (!(left instanceof ValueExpression) || !(right instanceof ValueExpression)) - throw new SemanticException("!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); + throw new SemanticException( + "!(left instanceof ValueExpression) || !(right instanceof ValueExpression)"); Satisfiability leftSatisfiability = satisfies((ValueExpression) left, pp, oracle); Satisfiability rightSatisfiability = satisfies((ValueExpression) right, pp, oracle); - if (leftSatisfiability.equals(Satisfiability.SATISFIED) && rightSatisfiability.equals(Satisfiability.SATISFIED)) + if (leftSatisfiability.equals(Satisfiability.SATISFIED) + && rightSatisfiability.equals(Satisfiability.SATISFIED)) return Satisfiability.SATISFIED; else return Satisfiability.UNKNOWN; } - + return Satisfiability.UNKNOWN; - + } @Override - public SubstringDomain pushScope(ScopeToken token) throws SemanticException { + public SubstringDomain pushScope( + ScopeToken token) + throws SemanticException { return new SubstringDomain(lattice.pushScope(token), mkNewFunction(function, true)); } @Override - public SubstringDomain popScope(ScopeToken token) throws SemanticException { + public SubstringDomain popScope( + ScopeToken token) + throws SemanticException { return new SubstringDomain(lattice.popScope(token), mkNewFunction(function, true)); } - - private static List extr(ValueExpression expression) throws SemanticException{ - + + private static List extr( + ValueExpression expression) + throws SemanticException { + List result = new ArrayList<>(); if (expression instanceof BinaryExpression) { BinaryExpression binaryExpression = (BinaryExpression) expression; BinaryOperator binaryOperator = binaryExpression.getOperator(); if (!(binaryOperator instanceof StringConcat)) return Collections.emptyList(); - + ValueExpression left = (ValueExpression) binaryExpression.getLeft(); ValueExpression right = (ValueExpression) binaryExpression.getRight(); - + result.addAll(extr(left)); result.addAll(extr(right)); - } else if(expression instanceof Variable || expression instanceof Constant) { + } else if (expression instanceof Variable || expression instanceof Constant) { result.add(expression); - } - + } + return result; } - - private static Set extrPlus(ValueExpression expression) throws SemanticException{ + + private static Set extrPlus( + ValueExpression expression, + Type strType) + throws SemanticException { List extracted = extr(expression); - - extracted = mergeStringLiterals(extracted); - + + extracted = mergeStringLiterals(extracted, strType); + Set result = new HashSet<>(); - + for (int l = 1; l <= extracted.size(); l++) { for (int i = 0; i <= (extracted.size() - l); i++) { - List subList = extracted.subList(i, i+l); + List subList = extracted.subList(i, i + l); result.add(composeExpression(subList)); - + if (subList.size() == 1 && subList.get(0) instanceof Constant) { Set substrings = getSubstrings((Constant) subList.get(0)); - + for (SymbolicExpression substring : substrings) { List newList = new ArrayList<>(); newList.add(substring); - + result.add(composeExpression(newList)); } } else if (subList.get(0) instanceof Constant) { Set suffixes = getSuffix((Constant) subList.get(0)); - + for (SymbolicExpression suffix : suffixes) { List newList = new ArrayList<>(subList); newList.set(0, suffix); - if (subList.get(subList.size() - 1) instanceof Constant) { Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); - + for (SymbolicExpression prefix : prefixes) { newList.set(newList.size() - 1, prefix); - + result.add(composeExpression(newList)); } } else result.add(composeExpression(newList)); - } } else if (subList.get(subList.size() - 1) instanceof Constant) { Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); - + for (SymbolicExpression prefix : prefixes) { List newList = new ArrayList<>(subList); newList.set(newList.size() - 1, prefix); - + result.add(composeExpression(newList)); } } - - + } } - + return new HashSet<>(result); } - - private static List mergeStringLiterals(List extracted){ + + private static List mergeStringLiterals( + List extracted, + Type strType) { List result = new ArrayList<>(); StringBuilder recent = new StringBuilder(); - Type stringType = null; - + for (SymbolicExpression expr : extracted) { if (expr instanceof Constant) { Constant c = (Constant) expr; - stringType = expr.getStaticType(); recent.append(c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString()); - - + } else { if (!recent.isEmpty()) { - result.add(new Constant(stringType, recent.toString(), SyntheticLocation.INSTANCE)); + result.add(new Constant(strType, recent.toString(), SyntheticLocation.INSTANCE)); recent.delete(0, recent.length()); } result.add(expr); } } - - + if (!recent.isEmpty()) - result.add(new Constant(stringType, recent.toString(), SyntheticLocation.INSTANCE)); - + result.add(new Constant(strType, recent.toString(), SyntheticLocation.INSTANCE)); + return result; } - - private static Set getSubstrings(Constant c){ + + private static Set getSubstrings( + Constant c) { Set result = new HashSet<>(); - + String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); for (int l = 1; l < str.length(); l++) { - for (int i=0; i <= str.length() - l; i++) { - ValueExpression substring = new Constant(c.getStaticType(), str.substring(i, i+l), SyntheticLocation.INSTANCE); - + for (int i = 0; i <= str.length() - l; i++) { + ValueExpression substring = new Constant(c.getStaticType(), str.substring(i, i + l), + SyntheticLocation.INSTANCE); + result.add(substring); } } - + return result; } - - - private static Set getPrefix(Constant c){ + + private static Set getPrefix( + Constant c) { Set result = new HashSet<>(); - + String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); for (int i = 1; i <= str.length(); i++) { ValueExpression prefix = new Constant(c.getStaticType(), str.substring(0, i), SyntheticLocation.INSTANCE); - + result.add(prefix); } - + return result; } - - private static Set getSuffix(Constant c){ + + private static Set getSuffix( + Constant c) { Set result = new HashSet<>(); - + String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); int length = str.length(); for (int i = 1; i <= length; i++) { - ValueExpression suffix = new Constant(c.getStaticType(), str.substring(length - i, length), SyntheticLocation.INSTANCE); - + ValueExpression suffix = new Constant(c.getStaticType(), str.substring(length - i, length), + SyntheticLocation.INSTANCE); + result.add(suffix); } - + return result; } - - private static SymbolicExpression composeExpression(List expressions) { + + private static SymbolicExpression composeExpression( + List expressions) { if (expressions.size() == 1) return expressions.get(0); - - return new BinaryExpression(expressions.get(0).getStaticType(), expressions.get(0), composeExpression(expressions.subList(1, expressions.size())), StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + return new BinaryExpression(expressions.get(0).getStaticType(), expressions.get(0), + composeExpression(expressions.subList(1, expressions.size())), StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); } - - - private SubstringDomain add(Set symbolicExpressions, Identifier id) throws SemanticException{ - + + private SubstringDomain add( + Set symbolicExpressions, + Identifier id) + throws SemanticException { + Map newFunction = mkNewFunction(function, false); - + Set expressionsToRemove = new HashSet<>(); for (SymbolicExpression se : symbolicExpressions) { if (!appears(id, se)) expressionsToRemove.add(se); } - //symbolicExpressions.remove(id); - - + // symbolicExpressions.remove(id); + if (expressionsToRemove.isEmpty()) return this; - + ExpressionInverseSet newSet = new ExpressionInverseSet(expressionsToRemove); - + if (!(newFunction.get(id) == null)) newSet = newSet.glb(newFunction.get(id)); - + newFunction.put(id, newSet); - + return mk(lattice, newFunction); } - - private SubstringDomain remove(Set extracted, Identifier id) throws SemanticException { + + private SubstringDomain remove( + Set extracted, + Identifier id) + throws SemanticException { Map newFunction = mkNewFunction(function, false); - - if(!extracted.contains(id)) { // x = x + ..... --> keep relations for x + + if (!extracted.contains(id)) { // x = x + ..... --> keep relations for x newFunction.remove(id); } - + for (Map.Entry entry : newFunction.entrySet()) { Set newSet = entry.getValue().elements.stream() - .filter(element -> !appears(id, element)) - .collect(Collectors.toSet()); + .filter(element -> !appears(id, element)) + .collect(Collectors.toSet()); + + ExpressionInverseSet value = newSet.isEmpty() ? new ExpressionInverseSet().top() + : new ExpressionInverseSet(newSet); - ExpressionInverseSet value = newSet.isEmpty() ? new ExpressionInverseSet().top() : new ExpressionInverseSet(newSet); - entry.setValue(value); - + } - + return mk(lattice, newFunction); } - - private SubstringDomain interasg(Identifier assignedId, SymbolicExpression assignedExpression) throws SemanticException { + + private SubstringDomain interasg( + Identifier assignedId, + SymbolicExpression assignedExpression) + throws SemanticException { Map newFunction = mkNewFunction(function, false); - + if (!knowsIdentifier(assignedId)) return this; - + for (Map.Entry entry : function.entrySet()) { if (entry.getKey().equals(assignedId)) continue; - + if (entry.getValue().contains(assignedExpression)) { Set newRelation = new HashSet<>(); newRelation.add(assignedId); - - ExpressionInverseSet newSet = newFunction.get(entry.getKey()).glb(new ExpressionInverseSet(newRelation)); + + ExpressionInverseSet newSet = newFunction.get(entry.getKey()) + .glb(new ExpressionInverseSet(newRelation)); newFunction.put(entry.getKey(), newSet); } - + } - + return mk(lattice, newFunction); } - - private SubstringDomain closure(Identifier id) throws SemanticException { + + private SubstringDomain closure( + Identifier id) + throws SemanticException { if (isTop() || isBottom()) return this; - + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - + ExpressionInverseSet toModify; ExpressionInverseSet iterate; - + do { toModify = result.getState(id); iterate = result.getState(id); - + for (SymbolicExpression se : toModify) { if (se instanceof Variable) { Variable variable = (Variable) se; - + if (result.knowsIdentifier(variable)) { Set add = new HashSet<>(result.getState(variable).elements); - result = result.add(add , id); + result = result.add(add, id); } } } - } while(!iterate.equals(toModify)); - + } while (!iterate.equals(toModify)); + return result; } - + private SubstringDomain closure() throws SemanticException { if (isTop() || isBottom()) return this; - + SubstringDomain prev; - SubstringDomain result = mk(lattice, mkNewFunction(function, false)); + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - do { - prev = mk(lattice, mkNewFunction(result.function, false)); + prev = mk(lattice, mkNewFunction(result.function, false)); Set set = prev.function.keySet(); - - for(Identifier id : set) { + + for (Identifier id : set) { result = result.closure(id); } - + result = result.clear(); - }while(!prev.equals(result)); - - + } while (!prev.equals(result)); + return result; - + } - + private SubstringDomain clear() throws SemanticException { SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - + Map iterate = mkNewFunction(result.function, false); - for (Map.Entry entry : iterate.entrySet() ) { + for (Map.Entry entry : iterate.entrySet()) { if (entry.getValue().isTop()) { result = result.forgetIdentifier(entry.getKey()); } - + } - + return result; } - - private static boolean appears(Identifier id, SymbolicExpression expr) { + + private static boolean appears( + Identifier id, + SymbolicExpression expr) { if (expr instanceof Identifier) return id.equals(expr); - + if (expr instanceof Constant) return false; - + if (expr instanceof BinaryExpression) { BinaryExpression expression = (BinaryExpression) expr; SymbolicExpression left = expression.getLeft(); SymbolicExpression right = expression.getRight(); - + return appears(id, left) || appears(id, right); } - + return false; - + } } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 103e799bc..156838c51 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -4,13 +4,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.junit.Test; - import it.unive.lisa.analysis.SemanticException; import it.unive.lisa.analysis.lattices.ExpressionInverseSet; import it.unive.lisa.analysis.lattices.Satisfiability; @@ -30,14 +23,19 @@ import it.unive.lisa.symbolic.value.operator.binary.StringEndsWith; import it.unive.lisa.symbolic.value.operator.binary.StringEquals; import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.junit.Test; public class SubstringDomainTest { - + Identifier y = new Variable(StringType.INSTANCE, "y", SyntheticLocation.INSTANCE); Identifier x = new Variable(StringType.INSTANCE, "x", SyntheticLocation.INSTANCE); Identifier z = new Variable(StringType.INSTANCE, "z", SyntheticLocation.INSTANCE); Identifier w = new Variable(StringType.INSTANCE, "w", SyntheticLocation.INSTANCE); - + ValueExpression a = new Constant(StringType.INSTANCE, "a", SyntheticLocation.INSTANCE); ValueExpression b = new Constant(StringType.INSTANCE, "b", SyntheticLocation.INSTANCE); ValueExpression c = new Constant(StringType.INSTANCE, "c", SyntheticLocation.INSTANCE); @@ -45,71 +43,87 @@ public class SubstringDomainTest { ValueExpression bc = new Constant(StringType.INSTANCE, "bc", SyntheticLocation.INSTANCE); ValueExpression abc = new Constant(StringType.INSTANCE, "abc", SyntheticLocation.INSTANCE); - SubstringDomain domainA; SubstringDomain domainB; - + SubstringDomain domainC; SubstringDomain domainD; - + SubstringDomain domainE; - + SubstringDomain domainF; - + SubstringDomain TOP; SubstringDomain BOTTOM; - - ValueExpression XEqualsY = new BinaryExpression(BoolType.INSTANCE, x, y, StringEquals.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XEqualsW = new BinaryExpression(BoolType.INSTANCE, x, w, StringEquals.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression YSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, y, StringContains.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression WSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, w, StringContains.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XStartsWithY = new BinaryExpression(BoolType.INSTANCE, x, y, StringStartsWith.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XStartsWithW = new BinaryExpression(BoolType.INSTANCE, x, w, StringStartsWith.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XEndsWithY = new BinaryExpression(BoolType.INSTANCE, x, y, StringEndsWith.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XEndsWithW = new BinaryExpression(BoolType.INSTANCE, x, w, StringEndsWith.INSTANCE, SyntheticLocation.INSTANCE); - - ValueExpression invalid = new BinaryExpression(StringType.INSTANCE, x, XEqualsY, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - - ValueExpression XConcatY = new BinaryExpression(StringType.INSTANCE, x, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression ZConcatX = new BinaryExpression(StringType.INSTANCE, z, x, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression ZConcatXConcatY = new BinaryExpression(StringType.INSTANCE, z, XConcatY, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - - ValueExpression XConcatAB = new BinaryExpression(StringType.INSTANCE, x, ab, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XConcatA = new BinaryExpression(StringType.INSTANCE, x, a, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XConcatBC = new BinaryExpression(StringType.INSTANCE, x, bc, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XConcatABC = new BinaryExpression(StringType.INSTANCE, x, abc, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XConcatABCConcatY = new BinaryExpression(StringType.INSTANCE, XConcatABC, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - - - ValueExpression CSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, c, StringContains.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XSubstringOfC = new BinaryExpression(BoolType.INSTANCE, c, x, StringContains.INSTANCE, SyntheticLocation.INSTANCE); - - + + ValueExpression XEqualsY = new BinaryExpression(BoolType.INSTANCE, x, y, StringEquals.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XEqualsW = new BinaryExpression(BoolType.INSTANCE, x, w, StringEquals.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression YSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, y, StringContains.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression WSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, w, StringContains.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XStartsWithY = new BinaryExpression(BoolType.INSTANCE, x, y, StringStartsWith.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XStartsWithW = new BinaryExpression(BoolType.INSTANCE, x, w, StringStartsWith.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XEndsWithY = new BinaryExpression(BoolType.INSTANCE, x, y, StringEndsWith.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XEndsWithW = new BinaryExpression(BoolType.INSTANCE, x, w, StringEndsWith.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression invalid = new BinaryExpression(StringType.INSTANCE, x, XEqualsY, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression XConcatY = new BinaryExpression(StringType.INSTANCE, x, y, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression ZConcatX = new BinaryExpression(StringType.INSTANCE, z, x, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression ZConcatXConcatY = new BinaryExpression(StringType.INSTANCE, z, XConcatY, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression XConcatAB = new BinaryExpression(StringType.INSTANCE, x, ab, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XConcatA = new BinaryExpression(StringType.INSTANCE, x, a, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XConcatBC = new BinaryExpression(StringType.INSTANCE, x, bc, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XConcatABC = new BinaryExpression(StringType.INSTANCE, x, abc, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XConcatABCConcatY = new BinaryExpression(StringType.INSTANCE, XConcatABC, y, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression CSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, c, StringContains.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XSubstringOfC = new BinaryExpression(BoolType.INSTANCE, c, x, StringContains.INSTANCE, + SyntheticLocation.INSTANCE); + public SubstringDomainTest() { Map mapA = new HashMap<>(); Set setA = new HashSet<>(); setA.add(y); setA.add(w); mapA.put(x, new ExpressionInverseSet(setA)); - + Map mapB = new HashMap<>(); Set setB = new HashSet<>(); Set setB2 = new HashSet<>(); setB.add(z); setB2.add(w); - mapB.put(y, new ExpressionInverseSet(setB)); + mapB.put(y, new ExpressionInverseSet(setB)); mapB.put(x, new ExpressionInverseSet(setB2)); - + Map mapC = new HashMap<>(); Set setC = new HashSet<>(); setC.add(z); mapC.put(x, new ExpressionInverseSet(setC)); - + Map mapD = new HashMap<>(); Set setD = new HashSet<>(); setD.add(w); mapD.put(y, new ExpressionInverseSet(setD)); - + Map mapE = new HashMap<>(); Set setE1 = new HashSet<>(); Set setE2 = new HashSet<>(); @@ -117,7 +131,7 @@ public SubstringDomainTest() { setE2.add(x); mapE.put(x, new ExpressionInverseSet(setE1)); mapE.put(y, new ExpressionInverseSet(setE2)); - + Map mapF = new HashMap<>(); Set setF1 = new HashSet<>(); Set setF2 = new HashSet<>(); @@ -126,16 +140,17 @@ public SubstringDomainTest() { setF2.add(z); mapF.put(x, new ExpressionInverseSet(setF1)); mapF.put(w, new ExpressionInverseSet(setF2)); - + domainA = new SubstringDomain(new ExpressionInverseSet(), mapA); domainB = new SubstringDomain(new ExpressionInverseSet(), mapB); domainC = new SubstringDomain(new ExpressionInverseSet(), mapC); domainD = new SubstringDomain(new ExpressionInverseSet(), mapD); domainE = new SubstringDomain(new ExpressionInverseSet(), mapE); domainF = new SubstringDomain(new ExpressionInverseSet(), mapF); - + TOP = new SubstringDomain().top(); - BOTTOM = new SubstringDomain().bottom();; + BOTTOM = new SubstringDomain().bottom(); + ; } @Test @@ -147,7 +162,7 @@ public void testAssumeEmpty() throws SemanticException { assertFalse(assumed.getState(y).contains(y)); assertFalse(assumed.getState(x).contains(x)); } - + @Test public void testAssumeEmpty2() throws SemanticException { SubstringDomain empty = new SubstringDomain(); @@ -157,7 +172,7 @@ public void testAssumeEmpty2() throws SemanticException { assertFalse(assumed.getState(y).contains(y)); assertFalse(assumed.getState(x).contains(x)); } - + @Test public void testAssumeEmpty3() throws SemanticException { SubstringDomain empty = new SubstringDomain(); @@ -167,7 +182,7 @@ public void testAssumeEmpty3() throws SemanticException { assertFalse(assumed.getState(y).contains(y)); assertFalse(assumed.getState(x).contains(x)); } - + @Test public void testAssumeEmpty4() throws SemanticException { SubstringDomain empty = new SubstringDomain(); @@ -177,7 +192,7 @@ public void testAssumeEmpty4() throws SemanticException { assertFalse(assumed.getState(y).contains(y)); assertFalse(assumed.getState(x).contains(x)); } - + @Test public void testAssumeEmpty5() throws SemanticException { ValueExpression orOperation = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, @@ -188,10 +203,10 @@ public void testAssumeEmpty5() throws SemanticException { assertFalse(assumed.getState(y).contains(x)); assertFalse(assumed.getState(y).contains(y)); assertFalse(assumed.getState(x).contains(x)); - + assertEquals(assumed, BOTTOM); } - + @Test public void testAssumeEmpty6() throws SemanticException { ValueExpression andOperation = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, @@ -203,13 +218,13 @@ public void testAssumeEmpty6() throws SemanticException { assertFalse(assumed.getState(y).contains(w)); assertTrue(assumed.getState(x).contains(w)); } - + @Test public void testAssume1() throws SemanticException { SubstringDomain assume1 = domainB.assume(YSubstringOfX, null, null, null); SubstringDomain assume2 = domainB.assume(XEndsWithY, null, null, null); SubstringDomain assume3 = domainB.assume(XStartsWithY, null, null, null); - + assertEquals(assume1, assume2); assertEquals(assume1, assume3); assertTrue(assume1.getState(x).contains(y)); @@ -217,11 +232,11 @@ public void testAssume1() throws SemanticException { assertTrue(assume1.getState(x).contains(z)); assertTrue(assume1.getState(y).contains(z)); } - + @Test public void testAssume2() throws SemanticException { SubstringDomain assume = domainB.assume(XEqualsY, null, null, null); - + assertTrue(assume.getState(x).contains(y)); assertTrue(assume.getState(x).contains(w)); assertTrue(assume.getState(x).contains(z)); @@ -229,16 +244,17 @@ public void testAssume2() throws SemanticException { assertTrue(assume.getState(y).contains(x)); assertTrue(assume.getState(y).contains(z)); } - + @Test public void testAssume3() throws SemanticException { Identifier j = new Variable(StringType.INSTANCE, "j", SyntheticLocation.INSTANCE); - ValueExpression JSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, j, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression JSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, j, StringContains.INSTANCE, + SyntheticLocation.INSTANCE); ValueExpression andOperation = new BinaryExpression(BoolType.INSTANCE, JSubstringOfY, YSubstringOfX, LogicalAnd.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain assume = domainB.assume(andOperation, null, null, null); - + assertTrue(assume.getState(x).contains(w)); assertTrue(assume.getState(x).contains(y)); assertTrue(assume.getState(x).contains(z)); @@ -249,16 +265,17 @@ public void testAssume3() throws SemanticException { assertFalse(assume.getState(y).contains(y)); } - + @Test public void testAssume4() throws SemanticException { Identifier j = new Variable(StringType.INSTANCE, "j", SyntheticLocation.INSTANCE); - ValueExpression JSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, j, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression JSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, j, StringContains.INSTANCE, + SyntheticLocation.INSTANCE); ValueExpression orOperation = new BinaryExpression(BoolType.INSTANCE, JSubstringOfY, YSubstringOfX, LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain assume = domainB.assume(orOperation, null, null, null); - + assertTrue(assume.getState(x).contains(w)); assertFalse(assume.getState(x).contains(y)); assertFalse(assume.getState(x).contains(z)); @@ -269,41 +286,43 @@ public void testAssume4() throws SemanticException { assertFalse(assume.getState(y).contains(y)); } - + @Test public void testAssume5() throws SemanticException { SubstringDomain assume = domainB.assume(CSubstringOfX, null, null, null); - + assertTrue(assume.getState(x).contains(c)); assertTrue(assume.getState(x).contains(w)); assertTrue(assume.getState(y).contains(z)); } - + @Test public void testAssume6() throws SemanticException { SubstringDomain assume = domainF.assume(XSubstringOfC, null, null, null); - + assertEquals(assume, domainF); } - + @Test public void testSatisfies() throws SemanticException { assertEquals(Satisfiability.SATISFIED, domainA.satisfies(YSubstringOfX, null, null)); - + assertEquals(Satisfiability.SATISFIED, domainE.satisfies(XEqualsY, null, null)); assertEquals(Satisfiability.SATISFIED, domainE.satisfies(YSubstringOfX, null, null)); assertEquals(Satisfiability.UNKNOWN, domainE.satisfies(XEqualsW, null, null)); - + assertEquals(Satisfiability.SATISFIED, domainE.satisfies(XStartsWithY, null, null)); assertEquals(Satisfiability.UNKNOWN, domainA.satisfies(XStartsWithY, null, null)); assertEquals(Satisfiability.SATISFIED, domainE.satisfies(XEndsWithY, null, null)); assertEquals(Satisfiability.UNKNOWN, domainA.satisfies(XEndsWithY, null, null)); - - ValueExpression andOperation = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, LogicalAnd.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression orOperation1 = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression orOperation2 = new BinaryExpression(BoolType.INSTANCE, YSubstringOfX, WSubstringOfX, LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression andOperation = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, + LogicalAnd.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression orOperation1 = new BinaryExpression(BoolType.INSTANCE, WSubstringOfX, YSubstringOfX, + LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression orOperation2 = new BinaryExpression(BoolType.INSTANCE, YSubstringOfX, WSubstringOfX, + LogicalOr.INSTANCE, SyntheticLocation.INSTANCE); + assertEquals(Satisfiability.SATISFIED, domainA.satisfies(andOperation, null, null)); assertEquals(Satisfiability.SATISFIED, domainE.satisfies(orOperation1, null, null)); assertEquals(Satisfiability.SATISFIED, domainA.satisfies(orOperation1, null, null)); @@ -311,18 +330,18 @@ public void testSatisfies() throws SemanticException { assertEquals(Satisfiability.UNKNOWN, domainD.satisfies(orOperation1, null, null)); assertEquals(domainE.satisfies(orOperation2, null, null), domainE.satisfies(orOperation1, null, null)); - + assertEquals(Satisfiability.SATISFIED, domainF.satisfies(CSubstringOfX, null, null)); assertEquals(Satisfiability.UNKNOWN, domainF.satisfies(XSubstringOfC, null, null)); } - + @Test public void testAssignEmptyDomain1() throws SemanticException { SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(x, y, null, null); assertTrue(assigned.getState(x).contains(y)); } - + @Test public void testAssignEmptyDomain2() throws SemanticException { SubstringDomain empty = new SubstringDomain(); @@ -330,7 +349,7 @@ public void testAssignEmptyDomain2() throws SemanticException { assertTrue(assigned.getState(x).contains(y)); assertFalse(assigned.getState(x).contains(x)); } - + @Test public void testAssignEmptyDomain3() throws SemanticException { SubstringDomain empty = new SubstringDomain(); @@ -339,26 +358,25 @@ public void testAssignEmptyDomain3() throws SemanticException { assertFalse(assigned.getState(x).contains(x)); assertTrue(assigned.getState(x).contains(z)); } - + @Test public void testAssignEmptyDomain4() throws SemanticException { SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(x, c, null, null); assertTrue(assigned.getState(x).contains(c)); } - + @Test public void testAssignEmptyDomain5() throws SemanticException { SubstringDomain empty = new SubstringDomain(); Identifier j = new Variable(StringType.INSTANCE, "j", SyntheticLocation.INSTANCE); - SubstringDomain assigned = empty.assign(j, c, null, null) .assign(w, j, null, null) .assign(y, x, null, null); - + assigned = assigned.assume(WSubstringOfX, null, null, null); - + assertTrue(assigned.getState(j).contains(c)); assertTrue(assigned.getState(w).contains(c)); assertTrue(assigned.getState(w).contains(j)); @@ -370,34 +388,36 @@ public void testAssignEmptyDomain5() throws SemanticException { assertTrue(assigned.getState(y).contains(c)); assertTrue(assigned.getState(y).contains(j)); } - + @Test - public void testAssignEmptyDomain6() throws SemanticException{ + public void testAssignEmptyDomain6() throws SemanticException { SubstringDomain empty = new SubstringDomain(); - + ValueExpression a = new Constant(StringType.INSTANCE, "a", SyntheticLocation.INSTANCE); ValueExpression b = new Constant(StringType.INSTANCE, "b", SyntheticLocation.INSTANCE); - ValueExpression AConcatB = new BinaryExpression(StringType.INSTANCE, a, b, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression AConcatB = new BinaryExpression(StringType.INSTANCE, a, b, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); SubstringDomain assigned = empty.assign(x, AConcatB, null, null); assigned = assigned.assign(y, a, null, null); - + assertTrue(assigned.getState(x).contains(y)); - + assigned = assigned.assign(x, c, null, null); assertTrue(assigned.getState(y).contains(a)); assertFalse(assigned.getState(x).contains(a)); assertTrue(assigned.getState(x).contains(c)); } - + @Test - public void testAssignEmptyDomain7() throws SemanticException{ + public void testAssignEmptyDomain7() throws SemanticException { SubstringDomain empty = new SubstringDomain(); - + ValueExpression a = new Constant(StringType.INSTANCE, "a", SyntheticLocation.INSTANCE); ValueExpression b = new Constant(StringType.INSTANCE, "b", SyntheticLocation.INSTANCE); - ValueExpression AConcatB = new BinaryExpression(StringType.INSTANCE, a, b, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression AConcatB = new BinaryExpression(StringType.INSTANCE, a, b, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); SubstringDomain assigned = empty.assign(x, AConcatB, null, null); assigned = assigned.assign(y, x, null, null); @@ -409,17 +429,18 @@ public void testAssignEmptyDomain7() throws SemanticException{ assertTrue(assigned.getState(x).contains(c)); assertFalse(assigned.getState(y).contains(x)); } - + @Test - public void testAssignEmptyDomain8() throws SemanticException{ + public void testAssignEmptyDomain8() throws SemanticException { SubstringDomain empty = new SubstringDomain(); - + ValueExpression a = new Constant(StringType.INSTANCE, "a", SyntheticLocation.INSTANCE); ValueExpression b = new Constant(StringType.INSTANCE, "b", SyntheticLocation.INSTANCE); - ValueExpression AConcatB = new BinaryExpression(StringType.INSTANCE, a, b, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XConcatC = new BinaryExpression(StringType.INSTANCE, x, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression AConcatB = new BinaryExpression(StringType.INSTANCE, a, b, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XConcatC = new BinaryExpression(StringType.INSTANCE, x, c, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); - SubstringDomain assigned = empty.assign(x, AConcatB, null, null); assigned = assigned.assign(y, x, null, null); assigned = assigned.assign(x, XConcatC, null, null); @@ -430,15 +451,14 @@ public void testAssignEmptyDomain8() throws SemanticException{ assertTrue(assigned.getState(x).contains(c)); assertFalse(assigned.getState(y).contains(c)); } - + @Test - public void testAssignEmptyDomain9() throws SemanticException{ + public void testAssignEmptyDomain9() throws SemanticException { SubstringDomain empty = new SubstringDomain(); - + SubstringDomain assigned = empty.assign(x, c, null, null); assigned = assigned.assign(y, x, null, null); - } @Test @@ -447,7 +467,7 @@ public void testAssign1() throws SemanticException { assertTrue(assigned.getState(x).contains(z)); assertFalse(assigned.getState(x).contains(y)); } - + @Test public void testAssign2() throws SemanticException { SubstringDomain assigned = domainA.assign(x, XConcatY, null, null); @@ -455,10 +475,11 @@ public void testAssign2() throws SemanticException { assertFalse(assigned.getState(x).contains(x)); assertTrue(assigned.getState(x).contains(w)); } - + @Test public void testAssign3() throws SemanticException { - ValueExpression XConcatZ = new BinaryExpression(StringType.INSTANCE, x, z, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XConcatZ = new BinaryExpression(StringType.INSTANCE, x, z, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); SubstringDomain assigned = domainA.assign(x, XConcatZ, null, null); assertTrue(assigned.getState(x).contains(y)); @@ -466,14 +487,14 @@ public void testAssign3() throws SemanticException { assertTrue(assigned.getState(x).contains(w)); assertTrue(assigned.getState(x).contains(z)); } - + @Test public void testAssign4() throws SemanticException { SubstringDomain assigned = domainA.assign(x, y, null, null); assertTrue(assigned.getState(x).contains(y)); assertFalse(assigned.getState(x).contains(w)); } - + @Test public void testAssign5() throws SemanticException { SubstringDomain assigned = domainD.assign(x, XConcatY, null, null); @@ -481,10 +502,11 @@ public void testAssign5() throws SemanticException { assertTrue(assigned.getState(x).contains(w)); assertTrue(assigned.getState(y).contains(w)); } - + @Test public void testAssign6() throws SemanticException { - ValueExpression WConcatY = new BinaryExpression(StringType.INSTANCE, w, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression WConcatY = new BinaryExpression(StringType.INSTANCE, w, y, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); SubstringDomain assigned = domainA.assign(z, WConcatY, null, null); assertTrue(assigned.getState(x).contains(y)); assertTrue(assigned.getState(x).contains(w)); @@ -492,7 +514,7 @@ public void testAssign6() throws SemanticException { assertTrue(assigned.getState(z).contains(y)); assertFalse(assigned.getState(x).contains(z)); } - + @Test public void testAssign7() throws SemanticException { SubstringDomain assigned = domainE.assign(y, z, null, null); @@ -501,10 +523,11 @@ public void testAssign7() throws SemanticException { assertTrue(assigned.getState(y).contains(z)); } - + @Test public void testAssign8() throws SemanticException { - ValueExpression XConcatZ = new BinaryExpression(StringType.INSTANCE, x, z, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression XConcatZ = new BinaryExpression(StringType.INSTANCE, x, z, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); SubstringDomain assigned = domainA.assign(x, XConcatZ, null, null); assigned = assigned.assign(w, x, null, null); assertFalse(assigned.getState(x).contains(w)); @@ -514,7 +537,7 @@ public void testAssign8() throws SemanticException { assertTrue(assigned.getState(w).contains(y)); assertTrue(assigned.getState(w).contains(z)); } - + @Test public void testAssign9() throws SemanticException { SubstringDomain assigned = new SubstringDomain().assign(x, w, null, null) @@ -526,13 +549,13 @@ public void testAssign9() throws SemanticException { assertFalse(assigned.getState(y).contains(x)); assertTrue(assigned.getState(y).contains(w)); } - + @Test public void testAssign10() throws SemanticException { Identifier j = new Variable(StringType.INSTANCE, "j", SyntheticLocation.INSTANCE); SubstringDomain assigned = domainF.assign(j, x, null, null); - + assertTrue(assigned.getState(x).contains(c)); assertTrue(assigned.getState(x).contains(y)); assertTrue(assigned.getState(w).contains(z)); @@ -540,30 +563,31 @@ public void testAssign10() throws SemanticException { assertTrue(assigned.getState(j).contains(c)); assertTrue(assigned.getState(j).contains(y)); } - + @Test public void testAssign11() throws SemanticException { SubstringDomain assigned = new SubstringDomain().assign(y, c, null, null).assign(x, y, null, null); - + assertTrue(assigned.getState(x).contains(y)); assertTrue(assigned.getState(x).contains(c)); assertTrue(assigned.getState(y).contains(c)); } - + @Test public void testAssign12() throws SemanticException { SubstringDomain assigned = new SubstringDomain().assign(y, c, null, null).assign(x, c, null, null); - + assertTrue(assigned.getState(y).contains(x)); } - + @Test public void testEmptyAssignComplex1() throws SemanticException { - ValueExpression ZConcatY = new BinaryExpression(StringType.INSTANCE, z, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression ZConcatY = new BinaryExpression(StringType.INSTANCE, z, y, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(w, ZConcatXConcatY, null, null); - + assertTrue(assigned.getState(w).contains(ZConcatX)); assertTrue(assigned.getState(w).contains(XConcatY)); assertTrue(assigned.getState(w).contains(ZConcatXConcatY)); @@ -572,12 +596,12 @@ public void testEmptyAssignComplex1() throws SemanticException { assertTrue(assigned.getState(w).contains(y)); assertFalse(assigned.getState(w).contains(ZConcatY)); } - + @Test - public void testEmptyAssignComplex2() throws SemanticException { + public void testEmptyAssignComplex2() throws SemanticException { SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(w, XConcatABC, null, null); - + assertTrue(assigned.getState(w).contains(XConcatABC)); assertTrue(assigned.getState(w).contains(x)); assertTrue(assigned.getState(w).contains(abc)); @@ -590,46 +614,50 @@ public void testEmptyAssignComplex2() throws SemanticException { assertFalse(assigned.getState(w).contains(XConcatBC)); } - + @Test - public void testEmptyAssignComplex3() throws SemanticException{ + public void testEmptyAssignComplex3() throws SemanticException { ValueExpression abcd = new Constant(StringType.INSTANCE, "abcd", SyntheticLocation.INSTANCE); ValueExpression ab = new Constant(StringType.INSTANCE, "ab", SyntheticLocation.INSTANCE); ValueExpression cd = new Constant(StringType.INSTANCE, "cd", SyntheticLocation.INSTANCE); - ValueExpression ABConcatCD = new BinaryExpression(StringType.INSTANCE, ab, cd, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression ABConcatCD = new BinaryExpression(StringType.INSTANCE, ab, cd, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned1 = empty.assign(x, abcd, null, null); SubstringDomain assigned2 = empty.assign(x, ABConcatCD, null, null); - + assertEquals(assigned1, assigned2); } - + @Test - public void testEmptyAssignComplex4() throws SemanticException{ + public void testEmptyAssignComplex4() throws SemanticException { ValueExpression ab = new Constant(StringType.INSTANCE, "ab", SyntheticLocation.INSTANCE); ValueExpression cd = new Constant(StringType.INSTANCE, "cd", SyntheticLocation.INSTANCE); - ValueExpression ABConcatY = new BinaryExpression(StringType.INSTANCE, ab, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression ABConcatYConcatCD = new BinaryExpression(StringType.INSTANCE, ABConcatY, cd, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression ABConcatY = new BinaryExpression(StringType.INSTANCE, ab, y, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression ABConcatYConcatCD = new BinaryExpression(StringType.INSTANCE, ABConcatY, cd, + StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(x, ABConcatYConcatCD, null, null); - + assertTrue(assigned.getState(x).size() == 15); } - + @Test - public void testEmptyAssignComplex5() throws SemanticException{ - ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression YConcatWConcatAB = new BinaryExpression(StringType.INSTANCE, YConcatW, ab, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + public void testEmptyAssignComplex5() throws SemanticException { + ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression YConcatWConcatAB = new BinaryExpression(StringType.INSTANCE, YConcatW, ab, + StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression WConcatA = new BinaryExpression(StringType.INSTANCE, w, a, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression WConcatA = new BinaryExpression(StringType.INSTANCE, w, a, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); - SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(x, YConcatWConcatAB, null, null); - + assertTrue(assigned.getState(x).contains(y)); assertTrue(assigned.getState(x).contains(w)); assertTrue(assigned.getState(x).contains(a)); @@ -638,211 +666,217 @@ public void testEmptyAssignComplex5() throws SemanticException{ assertTrue(assigned.getState(x).contains(YConcatW)); assertTrue(assigned.getState(x).contains(WConcatA)); } - + @Test - public void testEmptyAssignComplex6() throws SemanticException{ + public void testEmptyAssignComplex6() throws SemanticException { SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(x, c, null, null); assigned = assigned.assign(x, ZConcatX, null, null); - + assertTrue(assigned.getState(x).contains(c)); - + assigned = assigned.assign(x, w, null, null); - + assertTrue(assigned.getState(x).contains(w) && assigned.getState(x).size() == 1); } - + @Test - public void testEmptyAssignComplex7() throws SemanticException{ + public void testEmptyAssignComplex7() throws SemanticException { SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(y, ZConcatX, null, null); assigned = assigned.assign(x, c, null, null); - + assertFalse(assigned.getState(y).contains(x)); assertFalse(assigned.getState(y).contains(ZConcatX)); } - + @Test - public void testEmptyInterAssignComplex() throws SemanticException{ - ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression YConcatWConcatAB = new BinaryExpression(StringType.INSTANCE, YConcatW, ab, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - - ValueExpression WConcatA = new BinaryExpression(StringType.INSTANCE, w, a, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + public void testEmptyInterAssignComplex() throws SemanticException { + ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression YConcatWConcatAB = new BinaryExpression(StringType.INSTANCE, YConcatW, ab, + StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression WConcatA = new BinaryExpression(StringType.INSTANCE, w, a, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); - SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(x, YConcatWConcatAB, null, null); assigned = assigned.assign(y, WConcatA, null, null); - + assertTrue(assigned.getState(x).contains(y)); } - + @Test - public void testEmptyInterAssignComplex2() throws SemanticException{ + public void testEmptyInterAssignComplex2() throws SemanticException { SubstringDomain empty = new SubstringDomain(); - ValueExpression WConcatC = new BinaryExpression(StringType.INSTANCE, w, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + ValueExpression WConcatC = new BinaryExpression(StringType.INSTANCE, w, c, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); SubstringDomain assigned = empty.assign(x, WConcatC, null, null); assigned = assigned.assign(x, ZConcatX, null, null); assigned = assigned.assign(y, ZConcatX, null, null); - - + assertTrue(assigned.getState(y).contains(x)); assertTrue(assigned.getState(y).contains(c)); assertTrue(assigned.getState(y).contains(WConcatC)); } - + @Test - public void testAssumeComplex1() throws SemanticException{ - ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression XSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, x, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + public void testAssumeComplex1() throws SemanticException { + ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression XSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, x, StringContains.INSTANCE, + SyntheticLocation.INSTANCE); SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(x, YConcatW, null, null); assigned = assigned.assume(XSubstringOfY, null, null, null); - + assertTrue(assigned.getState(y).contains(x)); assertTrue(assigned.getState(y).contains(w)); assertFalse(assigned.getState(y).contains(YConcatW)); } - + @Test - public void testAssumeComplex2() throws SemanticException{ - ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression YConcatWSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, YConcatW, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + public void testAssumeComplex2() throws SemanticException { + ValueExpression YConcatW = new BinaryExpression(StringType.INSTANCE, y, w, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression YConcatWSubstringOfX = new BinaryExpression(BoolType.INSTANCE, x, YConcatW, + StringContains.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(z, YConcatW, null, null); assigned = assigned.assume(YConcatWSubstringOfX, null, null, null); - + assertEquals(assigned.getState(x), assigned.getState(z)); assertFalse(assigned.getState(z).contains(x)); } - + @Test - public void testAssumeComplex3() throws SemanticException{ - ValueExpression XSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, x, StringContains.INSTANCE, SyntheticLocation.INSTANCE); + public void testAssumeComplex3() throws SemanticException { + ValueExpression XSubstringOfY = new BinaryExpression(BoolType.INSTANCE, y, x, StringContains.INSTANCE, + SyntheticLocation.INSTANCE); SubstringDomain empty = new SubstringDomain(); SubstringDomain assigned = empty.assign(x, abc, null, null); assigned = assigned.assume(XSubstringOfY, null, null, null); - + assertTrue(assigned.getState(y).contains(abc)); assertTrue(assigned.getState(y).contains(x)); assertFalse(assigned.getState(x).contains(y)); } - + @Test public void testConstructor() { - SubstringDomain first = new SubstringDomain(); - - + SubstringDomain first = new SubstringDomain(); + Map f = new HashMap<>(); - + Set set = new HashSet<>(); - + set.add(y); ExpressionInverseSet eis = new ExpressionInverseSet(set); - + f.put(x, eis); - + SubstringDomain second = new SubstringDomain(new ExpressionInverseSet(), f); - + assertTrue(first.isBottom()); assertTrue(second.getState(x).contains(y)); - - assertTrue(new SubstringDomain().top().isTop()); + + assertTrue(new SubstringDomain().top().isTop()); assertTrue(new SubstringDomain().bottom().isBottom()); } - + @Test public void testForgetIdentifier() throws SemanticException { Map f = new HashMap<>(); - + Set set = new HashSet<>(); Identifier y = new Variable(StringType.INSTANCE, "y", SyntheticLocation.INSTANCE); Identifier x = new Variable(StringType.INSTANCE, "x", SyntheticLocation.INSTANCE); - + set.add(y); ExpressionInverseSet eis = new ExpressionInverseSet(set); - + f.put(x, eis); - + SubstringDomain domain = new SubstringDomain(new ExpressionInverseSet(), f); - + assertFalse(domain.forgetIdentifier(x).knowsIdentifier(x)); } - + @Test public void testGlb1() throws SemanticException { SubstringDomain glb = domainA.glb(domainB); - + assertTrue(glb.getState(x).contains(y)); assertTrue(glb.getState(y).contains(z)); assertTrue(glb.getState(x).contains(w)); assertTrue(glb.getState(x).contains(z)); } - + @Test public void testGlb2() throws SemanticException { SubstringDomain glb = domainA.glb(TOP); - + assertEquals(glb, domainA); } - + @Test public void testGlb3() throws SemanticException { SubstringDomain glb = BOTTOM.glb(domainA); - + assertEquals(glb, BOTTOM); } - + @Test public void testGlb4() throws SemanticException { SubstringDomain glb = domainC.glb(domainD); - + assertTrue(glb.getState(x).contains(z)); assertTrue(glb.getState(y).contains(w)); } - - @Test + + @Test public void testLub1() throws SemanticException { SubstringDomain lub = domainA.lub(domainB); - + assertFalse(lub.getState(x).contains(y)); assertFalse(lub.getState(y).contains(z)); assertEquals(lub.getState(y), lub.stateOfUnknown(y)); assertTrue(lub.getState(x).contains(w)); } - + @Test public void testLub2() throws SemanticException { SubstringDomain lub = TOP.lub(domainA); - + assertEquals(lub, TOP); } - + @Test public void testLub3() throws SemanticException { SubstringDomain lub = BOTTOM.lub(domainA); - + assertEquals(lub, domainA); } - + @Test public void testLub4() throws SemanticException { SubstringDomain lub = domainC.lub(domainD); - + assertEquals(lub, BOTTOM); - } - + } + @Test public void testLub5() throws SemanticException { SubstringDomain lub = domainA.lub(domainC); - + assertEquals(lub, BOTTOM); } } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 59b64ca4f..5b130ab41 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -1,7 +1,5 @@ package it.unive.lisa.cron; -import org.junit.Test; - import it.unive.lisa.AnalysisTestExecutor; import it.unive.lisa.CronConfiguration; import it.unive.lisa.DefaultConfiguration; @@ -14,6 +12,7 @@ import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; import it.unive.lisa.conf.LiSAConfiguration.GraphType; +import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { @@ -109,7 +108,7 @@ public void testTarsis() { conf.programFile = "strings.imp"; perform(conf); } - + @Test public void testSubstringDomain() { CronConfiguration conf = new CronConfiguration(); @@ -123,6 +122,6 @@ public void testSubstringDomain() { conf.programFile = "strings-subs.imp"; conf.analysisGraphs = GraphType.DOT; perform(conf); - + } } diff --git a/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java b/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java index 696606e76..6b6dc32d0 100644 --- a/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java +++ b/lisa/lisa-sdk/src/main/java/it/unive/lisa/analysis/lattices/ExpressionInverseSet.java @@ -113,7 +113,7 @@ public ExpressionInverseSet lubAux( id2) -> id1.getName().equals(id2.getName()), ExpressionInverseSet::wrapper); idlub.forEach(lub::add); - + if (lub.isEmpty()) return top(); From c3e93a1df521b916d34064492012490fe1d25dd9 Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Tue, 16 Apr 2024 15:43:29 +0200 Subject: [PATCH 11/34] assign is done only if the assigned expression has string type --- .../it/unive/lisa/analysis/string/SubstringDomain.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index c67b23afc..e65869439 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -102,11 +102,17 @@ public SubstringDomain assign( SemanticOracle oracle) throws SemanticException { + /** + * If the assigned expression is not dynamically typed as a string (or untyped) return this. + */ + if (oracle.getRuntimeTypesOf(expression, pp, oracle).stream().allMatch(t -> !t.isStringType() && !t.isUntyped())) + return this; + /* * The string type is unique and can be retrieved from the type system. */ Type strType = pp.getProgram().getTypes().getStringType(); - + Set identifiers = extrPlus(expression, strType); SubstringDomain result = mk(lattice, mkNewFunction(function, false)); From 30d8d5a85d274d426068376570d7851c5dbadbda Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Thu, 18 Apr 2024 15:55:14 +0200 Subject: [PATCH 12/34] Removed dot output in cron tests --- .../string/subs-domain/report.json | 18 +++++++++--------- .../untyped_strings.assume(strings__this).json | 1 + ...rings.assume(strings__this,_untyped_x).json | 1 - ...gs.branching(strings__this,_untyped_x).json | 2 +- ...ntyped_strings.closure2(strings__this).json | 1 + ...ngs.closure2(strings__this,_untyped_x).json | 1 - ...ntyped_strings.closure3(strings__this).json | 2 +- ...ntyped_strings.closure4(strings__this).json | 1 - ...typed_strings.constants(strings__this).json | 2 +- ...untyped_strings.iftest1(strings__this).json | 2 +- ...untyped_strings.iftest2(strings__this).json | 2 +- ...typed_strings.iftestand(strings__this).json | 2 +- ...ntyped_strings.iftestor(strings__this).json | 2 +- ...ped_strings.interassign(strings__this).json | 2 +- .../untyped_strings.paper1(strings__this).json | 1 + .../untyped_strings.paper2(strings__this).json | 1 + ...rings.paper3(strings__this,_untyped_x).json | 1 + ...ed_strings.stringconcat(strings__this).json | 1 + .../it/unive/lisa/cron/StringAnalysesTest.java | 2 +- 19 files changed, 24 insertions(+), 21 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this).json delete mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this,_untyped_x).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this).json delete mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this,_untyped_x).json delete mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure4(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper1(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper3(strings__this,_untyped_x).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.stringconcat(strings__this).json diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json index 4373b4f83..f156b1996 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json @@ -1,17 +1,17 @@ { "warnings" : [ ], - "files" : [ "report.json", "untyped_strings.assume(strings__this,_untyped_x).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this,_untyped_x).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.closure4(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json" ], + "files" : [ "report.json", "untyped_strings.assume(strings__this).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json", "untyped_strings.paper1(strings__this).json", "untyped_strings.paper2(strings__this).json", "untyped_strings.paper3(strings__this,_untyped_x).json", "untyped_strings.stringconcat(strings__this).json" ], "info" : { - "cfgs" : "13", - "duration" : "34ms", - "end" : "2024-04-05T13:00:03.612+02:00", - "expressions" : "122", - "files" : "13", + "cfgs" : "16", + "duration" : "69ms", + "end" : "2024-04-09T00:10:06.303+02:00", + "expressions" : "180", + "files" : "16", "globals" : "0", - "members" : "13", + "members" : "16", "programs" : "1", - "start" : "2024-04-05T13:00:03.578+02:00", - "statements" : "64", + "start" : "2024-04-09T00:10:06.234+02:00", + "statements" : "86", "units" : "1", "version" : "0.1b9", "warnings" : "0" diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this).json new file mode 100644 index 000000000..3fbf8d03a --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::assume(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"\""},{"id":1,"text":"x"},{"id":2,"text":"\"\""},{"id":3,"subNodes":[4,5],"text":"b = \"abc\""},{"id":4,"text":"b"},{"id":5,"text":"\"abc\""},{"id":6,"subNodes":[7,8],"text":"contains(x, b)"},{"id":7,"text":"x"},{"id":8,"text":"b"},{"id":9,"subNodes":[10,11],"text":"b = \"hello\""},{"id":10,"text":"b"},{"id":11,"text":"\"hello\""},{"id":12,"subNodes":[13,14],"text":"b = +(b, \"hello\")"},{"id":13,"text":"b"},{"id":14,"subNodes":[15,16],"text":"+(b, \"hello\")"},{"id":15,"text":"b"},{"id":16,"text":"\"hello\""},{"id":17,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"TrueEdge"},{"sourceId":6,"destId":12,"kind":"FalseEdge"},{"sourceId":9,"destId":17,"kind":"SequentialEdge"},{"sourceId":12,"destId":17,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":4,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["x strcontains b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":8,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":9,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""],"x":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":10,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""],"x":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\"","b"]}}}},{"nodeId":11,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""],"x":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\"","b"]}}}},{"nodeId":12,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\"","\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":13,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":14,"description":{"expressions":["b strcat \"hello\""],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":15,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":16,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":17,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":["string"]},"value":{"b":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this,_untyped_x).json deleted file mode 100644 index e59ee1578..000000000 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.assume(strings__this,_untyped_x).json +++ /dev/null @@ -1 +0,0 @@ -{"name":"untyped strings::assume(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"b = \"abc\""},{"id":1,"text":"b"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"contains(x, b)"},{"id":4,"text":"x"},{"id":5,"text":"b"},{"id":6,"subNodes":[7,8],"text":"b = \"hello\""},{"id":7,"text":"b"},{"id":8,"text":"\"hello\""},{"id":9,"subNodes":[10,11],"text":"b = +(b, \"hello\")"},{"id":10,"text":"b"},{"id":11,"subNodes":[12,13],"text":"+(b, \"hello\")"},{"id":12,"text":"b"},{"id":13,"text":"\"hello\""},{"id":14,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":14,"kind":"SequentialEdge"},{"sourceId":9,"destId":14,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":1,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x strcontains b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":5,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":6,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"hello\""],"x":["\"abc\""]}}}},{"nodeId":7,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""],"x":["\"abc\"","b"]}}}},{"nodeId":8,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""],"x":["\"abc\"","b"]}}}},{"nodeId":9,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\"","\"hello\""]}}}},{"nodeId":10,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":11,"description":{"expressions":["b strcat \"hello\""],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":12,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":13,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"abc\""]}}}},{"nodeId":14,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["\"hello\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json index 5d91e9303..8024d3d6b 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.branching(strings__this,_untyped_x).json @@ -1 +1 @@ -{"name":"untyped strings::branching(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = \"abc\""},{"id":1,"text":"a"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"==(x, 2)"},{"id":4,"text":"x"},{"id":5,"text":"2"},{"id":6,"subNodes":[7,8],"text":"a = \"hello\""},{"id":7,"text":"a"},{"id":8,"text":"\"hello\""},{"id":9,"subNodes":[10,11],"text":"a = \"world\""},{"id":10,"text":"a"},{"id":11,"text":"\"world\""},{"id":12,"subNodes":[13,14],"text":"b = a"},{"id":13,"text":"b"},{"id":14,"text":"a"},{"id":15,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":15,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":1,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x == 2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":5,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":6,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"hello\""]}}}},{"nodeId":7,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":8,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":9,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"world\""]}}}},{"nodeId":10,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":11,"description":{"expressions":["\"world\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"abc\""]}}}},{"nodeId":12,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["a"]}}}},{"nodeId":13,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":14,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":15,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"b":["a"]}}}}]} \ No newline at end of file +{"name":"untyped strings::branching(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = \"abc\""},{"id":1,"text":"a"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"==(x, 2)"},{"id":4,"text":"x"},{"id":5,"text":"2"},{"id":6,"subNodes":[7,8],"text":"a = \"hello\""},{"id":7,"text":"a"},{"id":8,"text":"\"hello\""},{"id":9,"subNodes":[10,11],"text":"a = \"world\""},{"id":10,"text":"a"},{"id":11,"text":"\"world\""},{"id":12,"subNodes":[13,14],"text":"b = a"},{"id":13,"text":"b"},{"id":14,"text":"a"},{"id":15,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":15,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":1,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x == 2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":5,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":6,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":7,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":8,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":9,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"d\"","\"l\"","\"ld\"","\"o\"","\"or\"","\"orl\"","\"orld\"","\"r\"","\"rl\"","\"rld\"","\"w\"","\"wo\"","\"wor\"","\"worl\"","\"world\""]}}}},{"nodeId":10,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":11,"description":{"expressions":["\"world\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":12,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"l\"","\"o\""],"b":["\"l\"","\"o\"","a"]}}}},{"nodeId":13,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"l\"","\"o\""]}}}},{"nodeId":14,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"l\"","\"o\""]}}}},{"nodeId":15,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"a":["\"l\"","\"o\""],"b":["\"l\"","\"o\"","a"]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this).json new file mode 100644 index 000000000..7e2217bd3 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::closure2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"j = \"j\""},{"id":1,"text":"j"},{"id":2,"text":"\"j\""},{"id":3,"subNodes":[4,5],"text":"w = j"},{"id":4,"text":"w"},{"id":5,"text":"j"},{"id":6,"subNodes":[7,8],"text":"x = \"x\""},{"id":7,"text":"x"},{"id":8,"text":"\"x\""},{"id":9,"subNodes":[10,11],"text":"y = x"},{"id":10,"text":"y"},{"id":11,"text":"x"},{"id":12,"subNodes":[13,14],"text":"x = w"},{"id":13,"text":"x"},{"id":14,"text":"w"},{"id":15,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":15,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"j\""]}}}},{"nodeId":1,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"j\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":4,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"j\""]}}}},{"nodeId":5,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"j\""]}}}},{"nodeId":6,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""]}}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":8,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""],"y":["\"x\"","x"]}}}},{"nodeId":10,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"],"y":["\"x\""]}}}},{"nodeId":13,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""],"y":["\"x\"","x"]}}}},{"nodeId":14,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""],"y":["\"x\"","x"]}}}},{"nodeId":15,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"],"y":["\"x\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this,_untyped_x).json deleted file mode 100644 index bfa088168..000000000 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure2(strings__this,_untyped_x).json +++ /dev/null @@ -1 +0,0 @@ -{"name":"untyped strings::closure2(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"j = \"j\""},{"id":1,"text":"j"},{"id":2,"text":"\"j\""},{"id":3,"subNodes":[4,5],"text":"w = j"},{"id":4,"text":"w"},{"id":5,"text":"j"},{"id":6,"subNodes":[7,8],"text":"y = x"},{"id":7,"text":"y"},{"id":8,"text":"x"},{"id":9,"subNodes":[10,11],"text":"x = w"},{"id":10,"text":"x"},{"id":11,"text":"w"},{"id":12,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"j":["\"j\""]}}}},{"nodeId":1,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"j\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":4,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"j":["\"j\""]}}}},{"nodeId":5,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"j":["\"j\""]}}}},{"nodeId":6,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#","y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"y":["x"]}}}},{"nodeId":7,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":8,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":9,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#","y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"y":["x"]}}}},{"nodeId":11,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":"#TOP#","y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"y":["x"]}}}},{"nodeId":12,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":"#TOP#"},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure3(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure3(strings__this).json index ea260a957..94231558c 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure3(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure3(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::closure3(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"j = \"j\""},{"id":1,"text":"j"},{"id":2,"text":"\"j\""},{"id":3,"subNodes":[4,5],"text":"w = j"},{"id":4,"text":"w"},{"id":5,"text":"j"},{"id":6,"subNodes":[7,8],"text":"x = \"x\""},{"id":7,"text":"x"},{"id":8,"text":"\"x\""},{"id":9,"subNodes":[10,11],"text":"y = x"},{"id":10,"text":"y"},{"id":11,"text":"x"},{"id":12,"subNodes":[13,14],"text":"x = w"},{"id":13,"text":"x"},{"id":14,"text":"w"},{"id":15,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":15,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"j\""]}}}},{"nodeId":1,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"j\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":4,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"j\""]}}}},{"nodeId":5,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"j\""]}}}},{"nodeId":6,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""]}}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":8,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""],"y":["\"x\"","x"]}}}},{"nodeId":10,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"],"y":["\"x\""]}}}},{"nodeId":13,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""],"y":["\"x\"","x"]}}}},{"nodeId":14,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"x\""],"y":["\"x\"","x"]}}}},{"nodeId":15,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"w":["string"],"x":["string"],"y":["string"]},"value":{"j":["\"j\""],"w":["\"j\"","j"],"x":["\"j\"","j","w"],"y":["\"x\""]}}}}]} \ No newline at end of file +{"name":"untyped strings::closure3(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"w = \"w\""},{"id":1,"text":"w"},{"id":2,"text":"\"w\""},{"id":3,"subNodes":[4,5],"text":"z = +(\"z\", w)"},{"id":4,"text":"z"},{"id":5,"subNodes":[6,7],"text":"+(\"z\", w)"},{"id":6,"text":"\"z\""},{"id":7,"text":"w"},{"id":8,"subNodes":[9,10],"text":"y = \"y\""},{"id":9,"text":"y"},{"id":10,"text":"\"y\""},{"id":11,"subNodes":[12,13],"text":"x = +(\"x\", y)"},{"id":12,"text":"x"},{"id":13,"subNodes":[14,15],"text":"+(\"x\", y)"},{"id":14,"text":"\"x\""},{"id":15,"text":"y"},{"id":16,"subNodes":[17,18],"text":"contains(y, z)"},{"id":17,"text":"y"},{"id":18,"text":"z"},{"id":19,"subNodes":[20,21],"text":"w = \"hello\""},{"id":20,"text":"w"},{"id":21,"text":"\"hello\""},{"id":22,"subNodes":[23,24],"text":"w = \"world\""},{"id":23,"text":"w"},{"id":24,"text":"\"world\""},{"id":25,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":8,"kind":"SequentialEdge"},{"sourceId":8,"destId":11,"kind":"SequentialEdge"},{"sourceId":11,"destId":16,"kind":"SequentialEdge"},{"sourceId":16,"destId":19,"kind":"TrueEdge"},{"sourceId":16,"destId":22,"kind":"FalseEdge"},{"sourceId":19,"destId":25,"kind":"SequentialEdge"},{"sourceId":22,"destId":25,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":1,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"w\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"z":["string"]},"value":{"w":["\"w\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":4,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":5,"description":{"expressions":["\"z\" strcat w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":6,"description":{"expressions":["\"z\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":7,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"z":["string"]},"value":{"w":["\"w\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":10,"description":{"expressions":["\"y\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"z":["string"]},"value":{"w":["\"w\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"x\" strcat y","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":13,"description":{"expressions":["\"x\" strcat y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":14,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":15,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":16,"description":{"expressions":["y strcontains z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"x\" strcat y","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"x\" strcat y","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":18,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"x\" strcat y","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":19,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""],"x":["\"w\"","\"x\"","\"x\" strcat y","\"y\"","\"z\"","y","z"],"y":["\"w\"","\"y\"","\"z\"","z"],"z":["\"w\"","\"z\""]}}}},{"nodeId":20,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"w\"","\"x\"","\"x\" strcat y","\"y\"","\"z\"","\"z\" strcat w","w","y","z"],"y":["\"w\"","\"y\"","\"z\"","\"z\" strcat w","w","z"],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":21,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"w\"","\"x\"","\"x\" strcat y","\"y\"","\"z\"","\"z\" strcat w","w","y","z"],"y":["\"w\"","\"y\"","\"z\"","\"z\" strcat w","w","z"],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":22,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"d\"","\"l\"","\"ld\"","\"o\"","\"or\"","\"orl\"","\"orld\"","\"r\"","\"rl\"","\"rld\"","\"w\"","\"wo\"","\"wor\"","\"worl\"","\"world\""],"x":["\"x\"","\"x\" strcat y","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\""]}}}},{"nodeId":23,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"x\" strcat y","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":24,"description":{"expressions":["\"world\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"x\" strcat y","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","\"z\" strcat w","w"]}}}},{"nodeId":25,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"l\"","\"o\""],"x":["\"x\"","\"x\" strcat y","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure4(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure4(strings__this).json deleted file mode 100644 index a3d282b56..000000000 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.closure4(strings__this).json +++ /dev/null @@ -1 +0,0 @@ -{"name":"untyped strings::closure4(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"w = \"w\""},{"id":1,"text":"w"},{"id":2,"text":"\"w\""},{"id":3,"subNodes":[4,5],"text":"z = +(\"z\", w)"},{"id":4,"text":"z"},{"id":5,"subNodes":[6,7],"text":"+(\"z\", w)"},{"id":6,"text":"\"z\""},{"id":7,"text":"w"},{"id":8,"subNodes":[9,10],"text":"y = \"y\""},{"id":9,"text":"y"},{"id":10,"text":"\"y\""},{"id":11,"subNodes":[12,13],"text":"x = +(\"x\", y)"},{"id":12,"text":"x"},{"id":13,"subNodes":[14,15],"text":"+(\"x\", y)"},{"id":14,"text":"\"x\""},{"id":15,"text":"y"},{"id":16,"subNodes":[17,18],"text":"contains(y, z)"},{"id":17,"text":"y"},{"id":18,"text":"z"},{"id":19,"subNodes":[20,21],"text":"w = \"hello\""},{"id":20,"text":"w"},{"id":21,"text":"\"hello\""},{"id":22,"subNodes":[23,24],"text":"w = \"world\""},{"id":23,"text":"w"},{"id":24,"text":"\"world\""},{"id":25,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":8,"kind":"SequentialEdge"},{"sourceId":8,"destId":11,"kind":"SequentialEdge"},{"sourceId":11,"destId":16,"kind":"SequentialEdge"},{"sourceId":16,"destId":19,"kind":"TrueEdge"},{"sourceId":16,"destId":22,"kind":"FalseEdge"},{"sourceId":19,"destId":25,"kind":"SequentialEdge"},{"sourceId":22,"destId":25,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":1,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"w\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"z":["string"]},"value":{"w":["\"w\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":4,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":5,"description":{"expressions":["\"z\" strcat w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":6,"description":{"expressions":["\"z\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":7,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"]},"value":{"w":["\"w\""]}}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"z":["string"]},"value":{"w":["\"w\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":10,"description":{"expressions":["\"y\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"z":["string"]},"value":{"w":["\"w\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":13,"description":{"expressions":["\"x\" strcat y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":14,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":15,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":16,"description":{"expressions":["y strcontains z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":18,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":19,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"hello\""],"x":["\"w\"","\"x\"","\"y\"","\"z\"","y","z"],"y":["\"w\"","\"y\"","\"z\"","z"],"z":["\"w\"","\"z\""]}}}},{"nodeId":20,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"w\"","\"x\"","\"y\"","\"z\"","w","y","z"],"y":["\"w\"","\"y\"","\"z\"","w","z"],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":21,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"w\"","\"x\"","\"y\"","\"z\"","w","y","z"],"y":["\"w\"","\"y\"","\"z\"","w","z"],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":22,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"world\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\""]}}}},{"nodeId":23,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":24,"description":{"expressions":["\"world\""],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"w\""],"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\"","w"]}}}},{"nodeId":25,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"x\"","\"y\"","y"],"y":["\"y\""],"z":["\"w\"","\"z\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.constants(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.constants(strings__this).json index 5456d152a..5862666cc 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.constants(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.constants(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::constants(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = \"abc\""},{"id":1,"text":"a"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"b = \"def\""},{"id":4,"text":"b"},{"id":5,"text":"\"def\""},{"id":6,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"]},"value":{"a":["\"abc\""]}}}},{"nodeId":1,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"]},"value":{"a":["\"abc\""],"b":["\"def\""]}}}},{"nodeId":4,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"]},"value":{"a":["\"abc\""]}}}},{"nodeId":5,"description":{"expressions":["\"def\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"]},"value":{"a":["\"abc\""]}}}},{"nodeId":6,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"]},"value":{"a":["\"abc\""],"b":["\"def\""]}}}}]} \ No newline at end of file +{"name":"untyped strings::constants(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = \"abc\""},{"id":1,"text":"a"},{"id":2,"text":"\"abc\""},{"id":3,"subNodes":[4,5],"text":"b = \"def\""},{"id":4,"text":"b"},{"id":5,"text":"\"def\""},{"id":6,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"]},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":1,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"]},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""],"b":["\"d\"","\"de\"","\"def\"","\"e\"","\"ef\"","\"f\""]}}}},{"nodeId":4,"description":{"expressions":["b"],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"]},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":5,"description":{"expressions":["\"def\""],"state":{"heap":"monolith","type":{"a":["string"],"this":["strings*"]},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":6,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"a":["string"],"b":["string"],"this":["strings*"]},"value":{"a":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""],"b":["\"d\"","\"de\"","\"def\"","\"e\"","\"ef\"","\"f\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json index eb0ef1536..2cd29b37d 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest1(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::iftest1(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"a\""},{"id":1,"text":"str"},{"id":2,"text":"\"a\""},{"id":3,"subNodes":[4,5],"text":"startsWith(str, \"c\")"},{"id":4,"text":"str"},{"id":5,"text":"\"c\""},{"id":6,"subNodes":[7,8],"text":"str = +(str, \" true\")"},{"id":7,"text":"str"},{"id":8,"subNodes":[9,10],"text":"+(str, \" true\")"},{"id":9,"text":"str"},{"id":10,"text":"\" true\""},{"id":11,"subNodes":[12,13],"text":"str = \"false\""},{"id":12,"text":"str"},{"id":13,"text":"\"false\""},{"id":14,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":11,"kind":"FalseEdge"},{"sourceId":6,"destId":14,"kind":"SequentialEdge"},{"sourceId":11,"destId":14,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strstarts \"c\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":4,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":5,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":6,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\" true\"","\"a\"","\"c\""]}}}},{"nodeId":7,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":8,"description":{"expressions":["str strcat \" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":9,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":10,"description":{"expressions":["\" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":11,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"false\""]}}}},{"nodeId":12,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":13,"description":{"expressions":["\"false\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":14,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":"#TOP#"}}}]} \ No newline at end of file +{"name":"untyped strings::iftest1(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"a\""},{"id":1,"text":"str"},{"id":2,"text":"\"a\""},{"id":3,"subNodes":[4,5],"text":"startsWith(str, \"c\")"},{"id":4,"text":"str"},{"id":5,"text":"\"c\""},{"id":6,"subNodes":[7,8],"text":"str = +(str, \" true\")"},{"id":7,"text":"str"},{"id":8,"subNodes":[9,10],"text":"+(str, \" true\")"},{"id":9,"text":"str"},{"id":10,"text":"\" true\""},{"id":11,"subNodes":[12,13],"text":"str = \"false\""},{"id":12,"text":"str"},{"id":13,"text":"\"false\""},{"id":14,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":11,"kind":"FalseEdge"},{"sourceId":6,"destId":14,"kind":"SequentialEdge"},{"sourceId":11,"destId":14,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strstarts \"c\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":4,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":5,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":6,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\" \"","\" t\"","\" tr\"","\" tru\"","\" true\"","\"a\"","\"c\"","\"e\"","\"r\"","\"ru\"","\"rue\"","\"t\"","\"tr\"","\"tru\"","\"true\"","\"u\"","\"ue\""]}}}},{"nodeId":7,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":8,"description":{"expressions":["str strcat \" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":9,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":10,"description":{"expressions":["\" true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"c\""]}}}},{"nodeId":11,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"al\"","\"als\"","\"alse\"","\"e\"","\"f\"","\"fa\"","\"fal\"","\"fals\"","\"false\"","\"l\"","\"ls\"","\"lse\"","\"s\"","\"se\""]}}}},{"nodeId":12,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":13,"description":{"expressions":["\"false\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\""]}}}},{"nodeId":14,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"e\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest2(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest2(strings__this).json index d2d084a36..0de2e225e 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest2(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftest2(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::iftest2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"hello\""},{"id":1,"text":"str"},{"id":2,"text":"\"hello\""},{"id":3,"subNodes":[4,5],"text":"endsWith(str, \"o\")"},{"id":4,"text":"str"},{"id":5,"text":"\"o\""},{"id":6,"subNodes":[7,8],"text":"str = \"true\""},{"id":7,"text":"str"},{"id":8,"text":"\"true\""},{"id":9,"subNodes":[10,11],"text":"str = \"false\""},{"id":10,"text":"str"},{"id":11,"text":"\"false\""},{"id":12,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":4,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":5,"description":{"expressions":["\"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":6,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"true\""]}}}},{"nodeId":7,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\"","\"o\""]}}}},{"nodeId":8,"description":{"expressions":["\"true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\"","\"o\""]}}}},{"nodeId":9,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"false\""]}}}},{"nodeId":10,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":11,"description":{"expressions":["\"false\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"hello\""]}}}},{"nodeId":12,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":"#TOP#"}}}]} \ No newline at end of file +{"name":"untyped strings::iftest2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"hello\""},{"id":1,"text":"str"},{"id":2,"text":"\"hello\""},{"id":3,"subNodes":[4,5],"text":"endsWith(str, \"o\")"},{"id":4,"text":"str"},{"id":5,"text":"\"o\""},{"id":6,"subNodes":[7,8],"text":"str = \"true\""},{"id":7,"text":"str"},{"id":8,"text":"\"true\""},{"id":9,"subNodes":[10,11],"text":"str = \"false\""},{"id":10,"text":"str"},{"id":11,"text":"\"false\""},{"id":12,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"hello\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":4,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":5,"description":{"expressions":["\"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":6,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\"","\"r\"","\"ru\"","\"rue\"","\"t\"","\"tr\"","\"tru\"","\"true\"","\"u\"","\"ue\""]}}}},{"nodeId":7,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":8,"description":{"expressions":["\"true\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":9,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"al\"","\"als\"","\"alse\"","\"e\"","\"f\"","\"fa\"","\"fal\"","\"fals\"","\"false\"","\"l\"","\"ls\"","\"lse\"","\"s\"","\"se\""]}}}},{"nodeId":10,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":11,"description":{"expressions":["\"false\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\"","\"el\"","\"ell\"","\"ello\"","\"h\"","\"he\"","\"hel\"","\"hell\"","\"hello\"","\"l\"","\"ll\"","\"llo\"","\"lo\"","\"o\""]}}}},{"nodeId":12,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"e\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json index cd6d4b99e..6248c48ee 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestand(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::iftestand(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"string\""},{"id":1,"text":"str"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,7],"text":"&&(endsWith(str, \"o\"), equals(str, \"ing\"))"},{"id":4,"subNodes":[5,6],"text":"endsWith(str, \"o\")"},{"id":5,"text":"str"},{"id":6,"text":"\"o\""},{"id":7,"subNodes":[8,9],"text":"equals(str, \"ing\")"},{"id":8,"text":"str"},{"id":9,"text":"\"ing\""},{"id":10,"subNodes":[11,12],"text":"x = \"x\""},{"id":11,"text":"x"},{"id":12,"text":"\"x\""},{"id":13,"subNodes":[14,15],"text":"y = \"y\""},{"id":14,"text":"y"},{"id":15,"text":"\"y\""},{"id":16,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":10,"kind":"TrueEdge"},{"sourceId":3,"destId":13,"kind":"FalseEdge"},{"sourceId":10,"destId":16,"kind":"SequentialEdge"},{"sourceId":13,"destId":16,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"o\" && str strcmp \"ing\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":4,"description":{"expressions":["str strends \"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":5,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":6,"description":{"expressions":["\"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":7,"description":{"expressions":["str strcmp \"ing\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":8,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":9,"description":{"expressions":["\"ing\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"]},"value":{"str":["\"ing\"","\"o\"","\"string\""],"x":["\"x\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"ing\"","\"o\"","\"string\""]}}}},{"nodeId":12,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"ing\"","\"o\"","\"string\""]}}}},{"nodeId":13,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"y":["string"]},"value":{"str":["\"string\""],"y":["\"y\""]}}}},{"nodeId":14,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":15,"description":{"expressions":["\"y\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":16,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"str":["\"string\""]}}}}]} \ No newline at end of file +{"name":"untyped strings::iftestand(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"string\""},{"id":1,"text":"str"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,7],"text":"&&(endsWith(str, \"o\"), equals(str, \"ing\"))"},{"id":4,"subNodes":[5,6],"text":"endsWith(str, \"o\")"},{"id":5,"text":"str"},{"id":6,"text":"\"o\""},{"id":7,"subNodes":[8,9],"text":"equals(str, \"ing\")"},{"id":8,"text":"str"},{"id":9,"text":"\"ing\""},{"id":10,"subNodes":[11,12],"text":"x = \"x\""},{"id":11,"text":"x"},{"id":12,"text":"\"x\""},{"id":13,"subNodes":[14,15],"text":"y = \"y\""},{"id":14,"text":"y"},{"id":15,"text":"\"y\""},{"id":16,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":10,"kind":"TrueEdge"},{"sourceId":3,"destId":13,"kind":"FalseEdge"},{"sourceId":10,"destId":16,"kind":"SequentialEdge"},{"sourceId":13,"destId":16,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"o\" && str strcmp \"ing\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":4,"description":{"expressions":["str strends \"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":5,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":6,"description":{"expressions":["\"o\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":7,"description":{"expressions":["str strcmp \"ing\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":8,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":9,"description":{"expressions":["\"ing\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"o\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""],"x":["\"x\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"o\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":12,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"o\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":13,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"y":["string"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""],"y":["\"y\""]}}}},{"nodeId":14,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":15,"description":{"expressions":["\"y\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":16,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestor(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestor(strings__this).json index 73430fc16..2b67f4fd4 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestor(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.iftestor(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::iftestor(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"string\""},{"id":1,"text":"str"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,7],"text":"||(endsWith(str, \"n\"), equals(str, \"no\"))"},{"id":4,"subNodes":[5,6],"text":"endsWith(str, \"n\")"},{"id":5,"text":"str"},{"id":6,"text":"\"n\""},{"id":7,"subNodes":[8,9],"text":"equals(str, \"no\")"},{"id":8,"text":"str"},{"id":9,"text":"\"no\""},{"id":10,"subNodes":[11,12],"text":"x = \"n\""},{"id":11,"text":"x"},{"id":12,"text":"\"n\""},{"id":13,"subNodes":[14,15],"text":"y = \"no\""},{"id":14,"text":"y"},{"id":15,"text":"\"no\""},{"id":16,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":10,"kind":"TrueEdge"},{"sourceId":3,"destId":13,"kind":"FalseEdge"},{"sourceId":10,"destId":16,"kind":"SequentialEdge"},{"sourceId":13,"destId":16,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"n\" || str strcmp \"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":4,"description":{"expressions":["str strends \"n\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":5,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":6,"description":{"expressions":["\"n\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":7,"description":{"expressions":["str strcmp \"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":8,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":9,"description":{"expressions":["\"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"]},"value":{"str":["\"string\""],"x":["\"n\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":12,"description":{"expressions":["\"n\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":13,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"y":["string"]},"value":{"str":["\"string\""],"y":["\"no\""]}}}},{"nodeId":14,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":15,"description":{"expressions":["\"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"string\""]}}}},{"nodeId":16,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"str":["\"string\""]}}}}]} \ No newline at end of file +{"name":"untyped strings::iftestor(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = \"string\""},{"id":1,"text":"str"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,7],"text":"||(endsWith(str, \"n\"), equals(str, \"no\"))"},{"id":4,"subNodes":[5,6],"text":"endsWith(str, \"n\")"},{"id":5,"text":"str"},{"id":6,"text":"\"n\""},{"id":7,"subNodes":[8,9],"text":"equals(str, \"no\")"},{"id":8,"text":"str"},{"id":9,"text":"\"no\""},{"id":10,"subNodes":[11,12],"text":"x = \"n\""},{"id":11,"text":"x"},{"id":12,"text":"\"n\""},{"id":13,"subNodes":[14,15],"text":"y = \"no\""},{"id":14,"text":"y"},{"id":15,"text":"\"no\""},{"id":16,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":10,"kind":"TrueEdge"},{"sourceId":3,"destId":13,"kind":"FalseEdge"},{"sourceId":10,"destId":16,"kind":"SequentialEdge"},{"sourceId":13,"destId":16,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["str strends \"n\" || str strcmp \"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":4,"description":{"expressions":["str strends \"n\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":5,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":6,"description":{"expressions":["\"n\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":7,"description":{"expressions":["str strcmp \"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":8,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":9,"description":{"expressions":["\"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\"","x"],"x":["\"n\""]}}}},{"nodeId":11,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":12,"description":{"expressions":["\"n\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":13,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"y":["string"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""],"y":["\"n\"","\"no\"","\"o\""]}}}},{"nodeId":14,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":15,"description":{"expressions":["\"no\""],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":16,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"str":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.interassign(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.interassign(strings__this).json index ad6dcfd40..1b02a5591 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.interassign(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.interassign(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::interassign(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"j = \"string\""},{"id":1,"text":"j"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,5],"text":"x = +(\"a\", j)"},{"id":4,"text":"x"},{"id":5,"subNodes":[6,7],"text":"+(\"a\", j)"},{"id":6,"text":"\"a\""},{"id":7,"text":"j"},{"id":8,"subNodes":[9,10],"text":"y = \"string\""},{"id":9,"text":"y"},{"id":10,"text":"\"string\""},{"id":11,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":8,"kind":"SequentialEdge"},{"sourceId":8,"destId":11,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":1,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"]},"value":{"j":["\"string\""],"x":["\"a\"","\"string\"","j"]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":5,"description":{"expressions":["\"a\" strcat j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":6,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":7,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"string\""]}}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"j":["\"string\"","y"],"x":["\"a\"","\"string\"","j","y"],"y":["\"string\""]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"]},"value":{"j":["\"string\""],"x":["\"a\"","\"string\"","j"]}}}},{"nodeId":10,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"]},"value":{"j":["\"string\""],"x":["\"a\"","\"string\"","j"]}}}},{"nodeId":11,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"j":["\"string\"","y"],"x":["\"a\"","\"string\"","j","y"],"y":["\"string\""]}}}}]} \ No newline at end of file +{"name":"untyped strings::interassign(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"j = \"string\""},{"id":1,"text":"j"},{"id":2,"text":"\"string\""},{"id":3,"subNodes":[4,5],"text":"x = +(\"a\", j)"},{"id":4,"text":"x"},{"id":5,"subNodes":[6,7],"text":"+(\"a\", j)"},{"id":6,"text":"\"a\""},{"id":7,"text":"j"},{"id":8,"subNodes":[9,10],"text":"y = \"string\""},{"id":9,"text":"y"},{"id":10,"text":"\"string\""},{"id":11,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":8,"kind":"SequentialEdge"},{"sourceId":8,"destId":11,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":1,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""],"x":["\"a\"","\"a\" strcat j","\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\"","j"]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":5,"description":{"expressions":["\"a\" strcat j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":6,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":7,"description":{"expressions":["j"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\"","y"],"x":["\"a\"","\"a\" strcat j","\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\"","j","y"],"y":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""],"x":["\"a\"","\"a\" strcat j","\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\"","j"]}}}},{"nodeId":10,"description":{"expressions":["\"string\""],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""],"x":["\"a\"","\"a\" strcat j","\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\"","j"]}}}},{"nodeId":11,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"j":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":{"j":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\"","y"],"x":["\"a\"","\"a\" strcat j","\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\"","j","y"],"y":["\"g\"","\"i\"","\"in\"","\"ing\"","\"n\"","\"ng\"","\"r\"","\"ri\"","\"rin\"","\"ring\"","\"s\"","\"st\"","\"str\"","\"stri\"","\"strin\"","\"string\"","\"t\"","\"tr\"","\"tri\"","\"trin\"","\"tring\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper1(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper1(strings__this).json new file mode 100644 index 000000000..0540a9bc0 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper1(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::paper1(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"ab\""},{"id":1,"text":"x"},{"id":2,"text":"\"ab\""},{"id":3,"subNodes":[4,5],"text":"y = \"a\""},{"id":4,"text":"y"},{"id":5,"text":"\"a\""},{"id":6,"subNodes":[7,8],"text":"z = \"b\""},{"id":7,"text":"z"},{"id":8,"text":"\"b\""},{"id":9,"subNodes":[10,11],"text":"w = +(y, z)"},{"id":10,"text":"w"},{"id":11,"subNodes":[12,13],"text":"+(y, z)"},{"id":12,"text":"y"},{"id":13,"text":"z"},{"id":14,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"SequentialEdge"},{"sourceId":9,"destId":14,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\""]}}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"ab\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","y"],"y":["\"a\""]}}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\""]}}}},{"nodeId":5,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\""]}}}},{"nodeId":6,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}}}},{"nodeId":7,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","y"],"y":["\"a\""]}}}},{"nodeId":8,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","y"],"y":["\"a\""]}}}},{"nodeId":9,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"a\"","\"b\"","y","y strcat z","z"],"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}}}},{"nodeId":10,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}}}},{"nodeId":11,"description":{"expressions":["y strcat z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}}}},{"nodeId":12,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}}}},{"nodeId":13,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}}}},{"nodeId":14,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":{"w":["\"a\"","\"b\"","y","y strcat z","z"],"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json new file mode 100644 index 000000000..103be06d2 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::paper2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"\""},{"id":1,"text":"x"},{"id":2,"text":"\"\""},{"id":3,"subNodes":[4,5],"text":"y = \"\""},{"id":4,"text":"y"},{"id":5,"text":"\"\""},{"id":6,"subNodes":[7,8],"text":"equals(x, y)"},{"id":7,"text":"x"},{"id":8,"text":"y"},{"id":9,"subNodes":[10,11],"text":"x = +(x, \"c\")"},{"id":10,"text":"x"},{"id":11,"subNodes":[12,13],"text":"+(x, \"c\")"},{"id":12,"text":"x"},{"id":13,"text":"\"c\""},{"id":14,"subNodes":[15,16],"text":"x = +(y, \"c\")"},{"id":15,"text":"x"},{"id":16,"subNodes":[17,18],"text":"+(y, \"c\")"},{"id":17,"text":"y"},{"id":18,"text":"\"c\""},{"id":19,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"TrueEdge"},{"sourceId":6,"destId":14,"kind":"FalseEdge"},{"sourceId":9,"destId":19,"kind":"SequentialEdge"},{"sourceId":14,"destId":19,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["x strcmp y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":9,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y"]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":11,"description":{"expressions":["x strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":13,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y","y strcat \"c\""]}}}},{"nodeId":15,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":16,"description":{"expressions":["y strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":18,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":19,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y"]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper3(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper3(strings__this,_untyped_x).json new file mode 100644 index 000000000..29ebc8fea --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper3(strings__this,_untyped_x).json @@ -0,0 +1 @@ +{"name":"untyped strings::paper3(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"v = \"\""},{"id":1,"text":"v"},{"id":2,"text":"\"\""},{"id":3,"subNodes":[4,5],"text":"%(x, 2)"},{"id":4,"text":"x"},{"id":5,"text":"2"},{"id":6,"subNodes":[7,8],"text":"v = \"abc\""},{"id":7,"text":"v"},{"id":8,"text":"\"abc\""},{"id":9,"subNodes":[10,11],"text":"v = \"def\""},{"id":10,"text":"v"},{"id":11,"text":"\"def\""},{"id":12,"subNodes":[13,14],"text":"r = +(+(\"Elem: \\n\", v), \"\\n\")"},{"id":13,"text":"r"},{"id":14,"subNodes":[15,18],"text":"+(+(\"Elem: \\n\", v), \"\\n\")"},{"id":15,"subNodes":[16,17],"text":"+(\"Elem: \\n\", v)"},{"id":16,"text":"\"Elem: \\n\""},{"id":17,"text":"v"},{"id":18,"text":"\"\\n\""},{"id":19,"subNodes":[20,21],"text":"i = 0"},{"id":20,"text":"i"},{"id":21,"text":"0"},{"id":22,"subNodes":[23,24],"text":"<(i, 20)"},{"id":23,"text":"i"},{"id":24,"text":"20"},{"id":25,"subNodes":[26,27],"text":"%(x, 2)"},{"id":26,"text":"x"},{"id":27,"text":"2"},{"id":28,"subNodes":[29,30],"text":"v = \"abc\""},{"id":29,"text":"v"},{"id":30,"text":"\"abc\""},{"id":31,"subNodes":[32,33],"text":"v = \"def\""},{"id":32,"text":"v"},{"id":33,"text":"\"def\""},{"id":34,"subNodes":[35,36],"text":"r = +(+(r, v), \"\\n\")"},{"id":35,"text":"r"},{"id":36,"subNodes":[37,40],"text":"+(+(r, v), \"\\n\")"},{"id":37,"subNodes":[38,39],"text":"+(r, v)"},{"id":38,"text":"r"},{"id":39,"text":"v"},{"id":40,"text":"\"\\n\""},{"id":41,"subNodes":[42,43],"text":"i = +(i, 1)"},{"id":42,"text":"i"},{"id":43,"subNodes":[44,45],"text":"+(i, 1)"},{"id":44,"text":"i"},{"id":45,"text":"1"},{"id":46,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":19,"kind":"SequentialEdge"},{"sourceId":19,"destId":22,"kind":"SequentialEdge"},{"sourceId":22,"destId":25,"kind":"TrueEdge"},{"sourceId":22,"destId":46,"kind":"FalseEdge"},{"sourceId":25,"destId":28,"kind":"TrueEdge"},{"sourceId":25,"destId":31,"kind":"FalseEdge"},{"sourceId":28,"destId":34,"kind":"SequentialEdge"},{"sourceId":31,"destId":34,"kind":"SequentialEdge"},{"sourceId":34,"destId":41,"kind":"SequentialEdge"},{"sourceId":41,"destId":22,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x % 2"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"v":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":7,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":8,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":9,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"v":["\"d\"","\"de\"","\"def\"","\"e\"","\"ef\"","\"f\""]}}}},{"nodeId":10,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":11,"description":{"expressions":["\"def\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":12,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":13,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":14,"description":{"expressions":["\"Elem: \\n\" strcat v strcat \"\\n\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":15,"description":{"expressions":["\"Elem: \\n\" strcat v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":16,"description":{"expressions":["\"Elem: \\n\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":17,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":18,"description":{"expressions":["\"\\n\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":19,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":20,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":21,"description":{"expressions":["0"],"state":{"heap":"monolith","type":{"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":22,"description":{"expressions":["i < 20"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":23,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":24,"description":{"expressions":["20"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":25,"description":{"expressions":["x % 2"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":26,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":27,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":28,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""],"v":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":29,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":30,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":31,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""],"v":["\"d\"","\"de\"","\"def\"","\"e\"","\"ef\"","\"f\""]}}}},{"nodeId":32,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":33,"description":{"expressions":["\"def\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":34,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":35,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":36,"description":{"expressions":["r strcat v strcat \"\\n\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":37,"description":{"expressions":["r strcat v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":38,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":39,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":40,"description":{"expressions":["\"\\n\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":41,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":42,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":43,"description":{"expressions":["i + 1"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":44,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":45,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":46,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.stringconcat(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.stringconcat(strings__this).json new file mode 100644 index 000000000..af37dca6e --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.stringconcat(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::stringconcat(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"str = +(+(\"a\", \"b\"), \"c\")"},{"id":1,"text":"str"},{"id":2,"subNodes":[3,6],"text":"+(+(\"a\", \"b\"), \"c\")"},{"id":3,"subNodes":[4,5],"text":"+(\"a\", \"b\")"},{"id":4,"text":"\"a\""},{"id":5,"text":"\"b\""},{"id":6,"text":"\"c\""},{"id":7,"text":"ret"}],"edges":[{"sourceId":0,"destId":7,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":1,"description":{"expressions":["str"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"a\" strcat \"b\" strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["\"a\" strcat \"b\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":7,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"str":["string"],"this":["strings*"]},"value":{"str":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 5b130ab41..04d41209e 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -120,7 +120,7 @@ public void testSubstringDomain() { conf.testDir = "string"; conf.testSubDir = "subs-domain"; conf.programFile = "strings-subs.imp"; - conf.analysisGraphs = GraphType.DOT; + //conf.analysisGraphs = GraphType.DOT; perform(conf); } From df8d6cfe23a1f7d0a638c5f922ba43b81cd9c0ce Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Thu, 18 Apr 2024 21:12:55 +0200 Subject: [PATCH 13/34] Fixed minor errors + added basic documentation of substring domain --- .../imp-testcases/string/strings-subs.imp | 9 + .../string/subs-domain/report.json | 18 +- ...typed_strings.integers(strings__this).json | 1 + ...ings.paper3(strings__this,_untyped_x).json | 2 +- ...trings.type(strings__this,_untyped_x).json | 1 + .../lisa/analysis/string/SubstringDomain.java | 266 +++++++++++++++--- .../analysis/string/SubstringDomainTest.java | 8 + 7 files changed, 259 insertions(+), 46 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.integers(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.type(strings__this,_untyped_x).json diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp index 38d1a33c4..f325625bc 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp @@ -133,5 +133,14 @@ class strings { } } + integers(){ + def a = 1; + a = a + 1; + } + + type(x){ + x = "a"; + } + } \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json index f156b1996..0632b5f13 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json @@ -1,17 +1,17 @@ { "warnings" : [ ], - "files" : [ "report.json", "untyped_strings.assume(strings__this).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json", "untyped_strings.paper1(strings__this).json", "untyped_strings.paper2(strings__this).json", "untyped_strings.paper3(strings__this,_untyped_x).json", "untyped_strings.stringconcat(strings__this).json" ], + "files" : [ "report.json", "untyped_strings.assume(strings__this).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.integers(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json", "untyped_strings.paper1(strings__this).json", "untyped_strings.paper2(strings__this).json", "untyped_strings.paper3(strings__this,_untyped_x).json", "untyped_strings.stringconcat(strings__this).json", "untyped_strings.type(strings__this,_untyped_x).json" ], "info" : { - "cfgs" : "16", - "duration" : "69ms", - "end" : "2024-04-09T00:10:06.303+02:00", - "expressions" : "180", - "files" : "16", + "cfgs" : "18", + "duration" : "77ms", + "end" : "2024-04-18T17:41:10.990+02:00", + "expressions" : "188", + "files" : "18", "globals" : "0", - "members" : "16", + "members" : "18", "programs" : "1", - "start" : "2024-04-09T00:10:06.234+02:00", - "statements" : "86", + "start" : "2024-04-18T17:41:10.913+02:00", + "statements" : "91", "units" : "1", "version" : "0.1b9", "warnings" : "0" diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.integers(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.integers(strings__this).json new file mode 100644 index 000000000..9a7108f6f --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.integers(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::integers(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"a = 1"},{"id":1,"text":"a"},{"id":2,"text":"1"},{"id":3,"subNodes":[4,5],"text":"a = +(a, 1)"},{"id":4,"text":"a"},{"id":5,"subNodes":[6,7],"text":"+(a, 1)"},{"id":6,"text":"a"},{"id":7,"text":"1"},{"id":8,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":8,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["int32"],"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["int32"],"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["int32"],"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["a + 1"],"state":{"heap":"monolith","type":{"a":["int32"],"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["a"],"state":{"heap":"monolith","type":{"a":["int32"],"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":7,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"a":["int32"],"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":8,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"a":["int32"],"this":["strings*"]},"value":"#TOP#"}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper3(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper3(strings__this,_untyped_x).json index 29ebc8fea..b1e87424f 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper3(strings__this,_untyped_x).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper3(strings__this,_untyped_x).json @@ -1 +1 @@ -{"name":"untyped strings::paper3(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"v = \"\""},{"id":1,"text":"v"},{"id":2,"text":"\"\""},{"id":3,"subNodes":[4,5],"text":"%(x, 2)"},{"id":4,"text":"x"},{"id":5,"text":"2"},{"id":6,"subNodes":[7,8],"text":"v = \"abc\""},{"id":7,"text":"v"},{"id":8,"text":"\"abc\""},{"id":9,"subNodes":[10,11],"text":"v = \"def\""},{"id":10,"text":"v"},{"id":11,"text":"\"def\""},{"id":12,"subNodes":[13,14],"text":"r = +(+(\"Elem: \\n\", v), \"\\n\")"},{"id":13,"text":"r"},{"id":14,"subNodes":[15,18],"text":"+(+(\"Elem: \\n\", v), \"\\n\")"},{"id":15,"subNodes":[16,17],"text":"+(\"Elem: \\n\", v)"},{"id":16,"text":"\"Elem: \\n\""},{"id":17,"text":"v"},{"id":18,"text":"\"\\n\""},{"id":19,"subNodes":[20,21],"text":"i = 0"},{"id":20,"text":"i"},{"id":21,"text":"0"},{"id":22,"subNodes":[23,24],"text":"<(i, 20)"},{"id":23,"text":"i"},{"id":24,"text":"20"},{"id":25,"subNodes":[26,27],"text":"%(x, 2)"},{"id":26,"text":"x"},{"id":27,"text":"2"},{"id":28,"subNodes":[29,30],"text":"v = \"abc\""},{"id":29,"text":"v"},{"id":30,"text":"\"abc\""},{"id":31,"subNodes":[32,33],"text":"v = \"def\""},{"id":32,"text":"v"},{"id":33,"text":"\"def\""},{"id":34,"subNodes":[35,36],"text":"r = +(+(r, v), \"\\n\")"},{"id":35,"text":"r"},{"id":36,"subNodes":[37,40],"text":"+(+(r, v), \"\\n\")"},{"id":37,"subNodes":[38,39],"text":"+(r, v)"},{"id":38,"text":"r"},{"id":39,"text":"v"},{"id":40,"text":"\"\\n\""},{"id":41,"subNodes":[42,43],"text":"i = +(i, 1)"},{"id":42,"text":"i"},{"id":43,"subNodes":[44,45],"text":"+(i, 1)"},{"id":44,"text":"i"},{"id":45,"text":"1"},{"id":46,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":19,"kind":"SequentialEdge"},{"sourceId":19,"destId":22,"kind":"SequentialEdge"},{"sourceId":22,"destId":25,"kind":"TrueEdge"},{"sourceId":22,"destId":46,"kind":"FalseEdge"},{"sourceId":25,"destId":28,"kind":"TrueEdge"},{"sourceId":25,"destId":31,"kind":"FalseEdge"},{"sourceId":28,"destId":34,"kind":"SequentialEdge"},{"sourceId":31,"destId":34,"kind":"SequentialEdge"},{"sourceId":34,"destId":41,"kind":"SequentialEdge"},{"sourceId":41,"destId":22,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x % 2"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"v":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":7,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":8,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":9,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"v":["\"d\"","\"de\"","\"def\"","\"e\"","\"ef\"","\"f\""]}}}},{"nodeId":10,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":11,"description":{"expressions":["\"def\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":12,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":13,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":14,"description":{"expressions":["\"Elem: \\n\" strcat v strcat \"\\n\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":15,"description":{"expressions":["\"Elem: \\n\" strcat v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":16,"description":{"expressions":["\"Elem: \\n\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":17,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":18,"description":{"expressions":["\"\\n\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":19,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":20,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":21,"description":{"expressions":["0"],"state":{"heap":"monolith","type":{"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":22,"description":{"expressions":["i < 20"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":23,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":24,"description":{"expressions":["20"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":25,"description":{"expressions":["x % 2"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":26,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":27,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":28,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""],"v":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":29,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":30,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":31,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""],"v":["\"d\"","\"de\"","\"def\"","\"e\"","\"ef\"","\"f\""]}}}},{"nodeId":32,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":33,"description":{"expressions":["\"def\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":34,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":35,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":36,"description":{"expressions":["r strcat v strcat \"\\n\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":37,"description":{"expressions":["r strcat v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":38,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":39,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":40,"description":{"expressions":["\"\\n\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":41,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":42,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":43,"description":{"expressions":["i + 1"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":44,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":45,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"i":["\"0\""],"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":46,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}}]} \ No newline at end of file +{"name":"untyped strings::paper3(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"v = \"\""},{"id":1,"text":"v"},{"id":2,"text":"\"\""},{"id":3,"subNodes":[4,5],"text":"%(x, 2)"},{"id":4,"text":"x"},{"id":5,"text":"2"},{"id":6,"subNodes":[7,8],"text":"v = \"abc\""},{"id":7,"text":"v"},{"id":8,"text":"\"abc\""},{"id":9,"subNodes":[10,11],"text":"v = \"def\""},{"id":10,"text":"v"},{"id":11,"text":"\"def\""},{"id":12,"subNodes":[13,14],"text":"r = +(+(\"Elem: \\n\", v), \"\\n\")"},{"id":13,"text":"r"},{"id":14,"subNodes":[15,18],"text":"+(+(\"Elem: \\n\", v), \"\\n\")"},{"id":15,"subNodes":[16,17],"text":"+(\"Elem: \\n\", v)"},{"id":16,"text":"\"Elem: \\n\""},{"id":17,"text":"v"},{"id":18,"text":"\"\\n\""},{"id":19,"subNodes":[20,21],"text":"i = 0"},{"id":20,"text":"i"},{"id":21,"text":"0"},{"id":22,"subNodes":[23,24],"text":"<(i, 20)"},{"id":23,"text":"i"},{"id":24,"text":"20"},{"id":25,"subNodes":[26,27],"text":"%(x, 2)"},{"id":26,"text":"x"},{"id":27,"text":"2"},{"id":28,"subNodes":[29,30],"text":"v = \"abc\""},{"id":29,"text":"v"},{"id":30,"text":"\"abc\""},{"id":31,"subNodes":[32,33],"text":"v = \"def\""},{"id":32,"text":"v"},{"id":33,"text":"\"def\""},{"id":34,"subNodes":[35,36],"text":"r = +(+(r, v), \"\\n\")"},{"id":35,"text":"r"},{"id":36,"subNodes":[37,40],"text":"+(+(r, v), \"\\n\")"},{"id":37,"subNodes":[38,39],"text":"+(r, v)"},{"id":38,"text":"r"},{"id":39,"text":"v"},{"id":40,"text":"\"\\n\""},{"id":41,"subNodes":[42,43],"text":"i = +(i, 1)"},{"id":42,"text":"i"},{"id":43,"subNodes":[44,45],"text":"+(i, 1)"},{"id":44,"text":"i"},{"id":45,"text":"1"},{"id":46,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"TrueEdge"},{"sourceId":3,"destId":9,"kind":"FalseEdge"},{"sourceId":6,"destId":12,"kind":"SequentialEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":19,"kind":"SequentialEdge"},{"sourceId":19,"destId":22,"kind":"SequentialEdge"},{"sourceId":22,"destId":25,"kind":"TrueEdge"},{"sourceId":22,"destId":46,"kind":"FalseEdge"},{"sourceId":25,"destId":28,"kind":"TrueEdge"},{"sourceId":25,"destId":31,"kind":"FalseEdge"},{"sourceId":28,"destId":34,"kind":"SequentialEdge"},{"sourceId":31,"destId":34,"kind":"SequentialEdge"},{"sourceId":34,"destId":41,"kind":"SequentialEdge"},{"sourceId":41,"destId":22,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x % 2"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"v":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":7,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":8,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":9,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"v":["\"d\"","\"de\"","\"def\"","\"e\"","\"ef\"","\"f\""]}}}},{"nodeId":10,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":11,"description":{"expressions":["\"def\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":12,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":13,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":14,"description":{"expressions":["\"Elem: \\n\" strcat v strcat \"\\n\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":15,"description":{"expressions":["\"Elem: \\n\" strcat v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":16,"description":{"expressions":["\"Elem: \\n\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":17,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":18,"description":{"expressions":["\"\\n\""],"state":{"heap":"monolith","type":{"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":19,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":20,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":21,"description":{"expressions":["0"],"state":{"heap":"monolith","type":{"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\" \\n\" strcat v","\" \\n\" strcat v strcat \"\\\"","\" \\n\" strcat v strcat \"\\n\"","\": \"","\": \\\"","\": \\n\"","\": \\n\" strcat v","\": \\n\" strcat v strcat \"\\\"","\": \\n\" strcat v strcat \"\\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem: \\n\" strcat v","\"Elem: \\n\" strcat v strcat \"\\\"","\"Elem: \\n\" strcat v strcat \"\\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"\\n\" strcat v","\"\\n\" strcat v strcat \"\\\"","\"\\n\" strcat v strcat \"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em: \\n\" strcat v","\"em: \\n\" strcat v strcat \"\\\"","\"em: \\n\" strcat v strcat \"\\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem: \\n\" strcat v","\"lem: \\n\" strcat v strcat \"\\\"","\"lem: \\n\" strcat v strcat \"\\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m: \\n\" strcat v","\"m: \\n\" strcat v strcat \"\\\"","\"m: \\n\" strcat v strcat \"\\n\"","\"m:\"","\"n\"","\"n\" strcat v","\"n\" strcat v strcat \"\\\"","\"n\" strcat v strcat \"\\n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":22,"description":{"expressions":["i < 20"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":23,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":24,"description":{"expressions":["20"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":25,"description":{"expressions":["x % 2"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":26,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":27,"description":{"expressions":["2"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":28,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""],"v":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}}}},{"nodeId":29,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":30,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":31,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""],"v":["\"d\"","\"de\"","\"def\"","\"e\"","\"ef\"","\"f\""]}}}},{"nodeId":32,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":33,"description":{"expressions":["\"def\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":34,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":35,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":36,"description":{"expressions":["r strcat v strcat \"\\n\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":37,"description":{"expressions":["r strcat v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":38,"description":{"expressions":["r"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":39,"description":{"expressions":["v"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":40,"description":{"expressions":["\"\\n\""],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\""]}}}},{"nodeId":41,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":42,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":43,"description":{"expressions":["i + 1"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":44,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":45,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}},{"nodeId":46,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"i":["int32"],"r":["string"],"this":["strings*"],"v":["string"],"x":"#TOP#"},"value":{"r":["\" \"","\" \\\"","\" \\n\"","\": \"","\": \\\"","\": \\n\"","\":\"","\"E\"","\"El\"","\"Ele\"","\"Elem\"","\"Elem: \"","\"Elem: \\\"","\"Elem: \\n\"","\"Elem:\"","\"\\\"","\"\\n\"","\"e\"","\"em\"","\"em: \"","\"em: \\\"","\"em: \\n\"","\"em:\"","\"l\"","\"le\"","\"lem\"","\"lem: \"","\"lem: \\\"","\"lem: \\n\"","\"lem:\"","\"m\"","\"m: \"","\"m: \\\"","\"m: \\n\"","\"m:\"","\"n\"","v","v strcat \"\\\"","v strcat \"\\n\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.type(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.type(strings__this,_untyped_x).json new file mode 100644 index 000000000..e889e4c92 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.type(strings__this,_untyped_x).json @@ -0,0 +1 @@ +{"name":"untyped strings::type(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"a\""},{"id":1,"text":"x"},{"id":2,"text":"\"a\""},{"id":3,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":{"x":["\"a\""]}}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":{"x":["\"a\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index e65869439..ddb9490e2 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -23,7 +23,6 @@ import it.unive.lisa.symbolic.value.operator.binary.StringEndsWith; import it.unive.lisa.symbolic.value.operator.binary.StringEquals; import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; -import it.unive.lisa.type.StringType; import it.unive.lisa.type.Type; import java.util.ArrayList; import java.util.Collections; @@ -103,16 +102,23 @@ public SubstringDomain assign( throws SemanticException { /** - * If the assigned expression is not dynamically typed as a string (or untyped) return this. + * If the assigned expression is not dynamically typed as a string (or + * untyped) return this. */ - if (oracle.getRuntimeTypesOf(expression, pp, oracle).stream().allMatch(t -> !t.isStringType() && !t.isUntyped())) + if (oracle != null && pp != null && oracle.getRuntimeTypesOf(expression, pp, oracle).stream() + .allMatch(t -> !t.isStringType() && !t.isUntyped())) return this; - + /* * The string type is unique and can be retrieved from the type system. */ - Type strType = pp.getProgram().getTypes().getStringType(); - + Type strType; + if (pp != null) // Correct: get the string type from the program point + strType = pp.getProgram().getTypes().getStringType(); + else // Used in tests where pp is null, get the string type from the + // expression + strType = expression.getStaticType(); + Set identifiers = extrPlus(expression, strType); SubstringDomain result = mk(lattice, mkNewFunction(function, false)); @@ -123,7 +129,7 @@ public SubstringDomain assign( result = result.interasg(id, expression); - result = result.closure(); + result = result.closure(id); return result.clear(); } @@ -145,9 +151,11 @@ public SubstringDomain assume( SemanticOracle oracle) throws SemanticException { - StringType strType = src.getProgram().getTypes().getStringType(); SubstringDomain result = mk(lattice, mkNewFunction(function, false)); + /* + * Assume only binary expressions + */ if (expression instanceof BinaryExpression) { BinaryExpression binaryExpression = (BinaryExpression) expression; @@ -156,10 +164,26 @@ public SubstringDomain assume( SymbolicExpression left = binaryExpression.getLeft(); SymbolicExpression right = binaryExpression.getRight(); + /* + * The string type is unique and can be retrieved from the type + * system. + */ + Type strType; + if (src != null) // Correct: get the string type from the program + // point + strType = src.getProgram().getTypes().getStringType(); + else // Used in tests where src is null, get the string type from + // the expression + strType = left.getStaticType(); + if (binaryOperator instanceof StringContains || binaryOperator instanceof StringStartsWith || binaryOperator instanceof StringEndsWith) { + /* + * Evaluate only if the left operand is an identidier + */ + if (!(left instanceof Identifier)) return this; @@ -173,18 +197,25 @@ public SubstringDomain assume( result = result.closure(); } else if (binaryOperator instanceof StringEquals) { - // both are identifiers + /* + * Case both operands are identifiers + */ if ((left instanceof Identifier) && (right instanceof Identifier)) { result = result.add(extrPlus((ValueExpression) left, strType), (Identifier) right); result = result.add(extrPlus((ValueExpression) right, strType), (Identifier) left); result = result.closure(); - } // one is identifier + } + + /* + * Case where only one is an identifier + */ else if ((left instanceof Identifier) || (right instanceof Identifier)) { - if (right instanceof Identifier) { // left instance of - // Identifier, right - // SymbolicExpression + if (right instanceof Identifier) { + /* + * Make left the identifier + */ SymbolicExpression temp = left; left = right; right = temp; @@ -293,14 +324,12 @@ public Satisfiability satisfies( return getState((Identifier) left).contains(right) ? Satisfiability.SATISFIED : Satisfiability.UNKNOWN; } else if (binaryOperator instanceof StringEquals || binaryOperator instanceof StringEndsWith || binaryOperator instanceof StringStartsWith) { - // ******* if (!(left instanceof Variable) || !(right instanceof Variable)) return Satisfiability.UNKNOWN; return (getState((Identifier) left).contains(right)) && (getState((Identifier) right).contains(left)) ? Satisfiability.SATISFIED : Satisfiability.UNKNOWN; - // ****** } else if (binaryOperator instanceof LogicalOr) { if (!(left instanceof ValueExpression) || !(right instanceof ValueExpression)) throw new SemanticException( @@ -346,9 +375,17 @@ public SubstringDomain popScope( return new SubstringDomain(lattice.popScope(token), mkNewFunction(function, true)); } + /** + * Extract the ordered expressions of a concatenation. If the expression is + * not a concatenation returns an empty list. Example: {@code x + y + "ab"} + * returns {@code x, y, "ab"} as List + * + * @param expression to extract + * + * @return List containing the sub-expressions + */ private static List extr( - ValueExpression expression) - throws SemanticException { + ValueExpression expression) { List result = new ArrayList<>(); if (expression instanceof BinaryExpression) { @@ -369,22 +406,40 @@ private static List extr( return result; } + /** + * Returns all the possible substring of a given expression. + * + * @param expression + * @param strType + * + * @return + */ private static Set extrPlus( ValueExpression expression, - Type strType) - throws SemanticException { + Type strType) { List extracted = extr(expression); + /* + * If there are more than 2 consecutive constants, merge them into a + * single constant + */ extracted = mergeStringLiterals(extracted, strType); Set result = new HashSet<>(); + // Iterate over the length of the expression for (int l = 1; l <= extracted.size(); l++) { + // Iterate from the start to the end according to the size of the + // expression to create for (int i = 0; i <= (extracted.size() - l); i++) { List subList = extracted.subList(i, i + l); result.add(composeExpression(subList)); if (subList.size() == 1 && subList.get(0) instanceof Constant) { + /* + * Case the expression to ass is a single constant -> add + * its substrings + */ Set substrings = getSubstrings((Constant) subList.get(0)); for (SymbolicExpression substring : substrings) { @@ -395,6 +450,11 @@ private static Set extrPlus( } } else if (subList.get(0) instanceof Constant) { + /* + * Case the first expression of the expression to add is a + * constant -> add an expression for each suffix of the + * constant + */ Set suffixes = getSuffix((Constant) subList.get(0)); for (SymbolicExpression suffix : suffixes) { @@ -402,6 +462,12 @@ private static Set extrPlus( newList.set(0, suffix); if (subList.get(subList.size() - 1) instanceof Constant) { + + /* + * Case the last expression of the expression to add + * is a constant -> add an expression for each + * prefix of the constant + */ Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); for (SymbolicExpression prefix : prefixes) { @@ -414,6 +480,13 @@ private static Set extrPlus( } } else if (subList.get(subList.size() - 1) instanceof Constant) { + + /* + * Case the last expression of the expression to add is a + * constant -> add an expression for each prefix of the + * constant + */ + Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); for (SymbolicExpression prefix : prefixes) { @@ -430,6 +503,16 @@ private static Set extrPlus( return new HashSet<>(result); } + /** + * Returns a list with no more than one consecutive constant where if + * {@code extracted} has consecutive constants, the returned value merges + * them + * + * @param extracted List to analyze + * @param strType + * + * @return The list without consecutive constants. + */ private static List mergeStringLiterals( List extracted, Type strType) { @@ -438,30 +521,50 @@ private static List mergeStringLiterals( for (SymbolicExpression expr : extracted) { if (expr instanceof Constant) { + // Update the string builder value addinf the value of the + // constant Constant c = (Constant) expr; recent.append(c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString()); } else { + /* + * Iterating an Variable + */ if (!recent.isEmpty()) { + // The previous value / values are constants; add to the + // list the constant with value the built string result.add(new Constant(strType, recent.toString(), SyntheticLocation.INSTANCE)); + // Clear the string builder recent.delete(0, recent.length()); } + // Add the variable result.add(expr); } } + // If the last element is a constant add the last built string if (!recent.isEmpty()) result.add(new Constant(strType, recent.toString(), SyntheticLocation.INSTANCE)); return result; } + /** + * Returns the set containing the substrings of a Constant + * + * @param c Constant to analyze + * + * @return The set containing the substrings of a Constant + */ private static Set getSubstrings( Constant c) { Set result = new HashSet<>(); String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); + + // Iterate over the length of the resulting string for (int l = 1; l < str.length(); l++) { + // Iterate over the starting char for (int i = 0; i <= str.length() - l; i++) { ValueExpression substring = new Constant(c.getStaticType(), str.substring(i, i + l), SyntheticLocation.INSTANCE); @@ -473,11 +576,19 @@ private static Set getSubstrings( return result; } + /** + * Returns the set containing the prefixes of a Constant + * + * @param c Constant to analyze + * + * @return The set containing the prefixes of a Constant + */ private static Set getPrefix( Constant c) { Set result = new HashSet<>(); String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); + // Iterate over the length for (int i = 1; i <= str.length(); i++) { ValueExpression prefix = new Constant(c.getStaticType(), str.substring(0, i), SyntheticLocation.INSTANCE); @@ -487,12 +598,20 @@ private static Set getPrefix( return result; } + /** + * Returns the set containing the suffixes of a Constant + * + * @param c Constant to analyze + * + * @return The set containing the suffixes of a Constant + */ private static Set getSuffix( Constant c) { Set result = new HashSet<>(); String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); int length = str.length(); + // Iterate over the length for (int i = 1; i <= length; i++) { ValueExpression suffix = new Constant(c.getStaticType(), str.substring(length - i, length), SyntheticLocation.INSTANCE); @@ -503,6 +622,15 @@ private static Set getSuffix( return result; } + /** + * Creates am expression given a list. The returned expression is the + * ordered concatenation of the expression in the list. + * + * @param expressions + * + * @return The expression representing concatenation of the expressions in + * the list. + */ private static SymbolicExpression composeExpression( List expressions) { if (expressions.size() == 1) @@ -513,6 +641,16 @@ private static SymbolicExpression composeExpression( SyntheticLocation.INSTANCE); } + /** + * Adds a set of expressions to the domain. + * + * @param symbolicExpressions + * @param id + * + * @return A new domain with the added expressions + * + * @throws SemanticException + */ private SubstringDomain add( Set symbolicExpressions, Identifier id) @@ -520,12 +658,13 @@ private SubstringDomain add( Map newFunction = mkNewFunction(function, false); + // Don't add the expressions that contain the key variable (ex: x -> x, + // x -> x + y will not be added) Set expressionsToRemove = new HashSet<>(); for (SymbolicExpression se : symbolicExpressions) { if (!appears(id, se)) expressionsToRemove.add(se); } - // symbolicExpressions.remove(id); if (expressionsToRemove.isEmpty()) return this; @@ -540,16 +679,29 @@ private SubstringDomain add( return mk(lattice, newFunction); } + /** + * First step of assignment, removing obsolete relations. + * + * @param extracted Expression assigned + * @param id Expression getting assigned + * + * @return Copy of the domain, with the holding relations after the + * assignment. + * + * @throws SemanticException + */ private SubstringDomain remove( Set extracted, - Identifier id) - throws SemanticException { + Identifier id) { Map newFunction = mkNewFunction(function, false); - if (!extracted.contains(id)) { // x = x + ..... --> keep relations for x + // If assignment is similar to x = x + ..., then we keep current + // relations to x, otherwise we remove them. + if (!extracted.contains(id)) { newFunction.remove(id); } + // Remove relations containing id from the other entries for (Map.Entry entry : newFunction.entrySet()) { Set newSet = entry.getValue().elements.stream() .filter(element -> !appears(id, element)) @@ -565,6 +717,17 @@ private SubstringDomain remove( return mk(lattice, newFunction); } + /** + * Performs the inter-assignment phase + * + * @param assignedId Variable getting assigned + * @param assignedExpression Expression assigned + * + * @return Copy of the domain with new relations following the + * inter-assignment phase + * + * @throws SemanticException + */ private SubstringDomain interasg( Identifier assignedId, SymbolicExpression assignedExpression) @@ -575,6 +738,7 @@ private SubstringDomain interasg( return this; for (Map.Entry entry : function.entrySet()) { + // skip same entry if (entry.getKey().equals(assignedId)) continue; @@ -592,6 +756,14 @@ private SubstringDomain interasg( return mk(lattice, newFunction); } + /** + * Performs the closure over an identifier. The method adds to {@code id} + * the expressions found in the variables mapped to {@code id} + * + * @return A copy of the domain with the added relations + * + * @throws SemanticException + */ private SubstringDomain closure( Identifier id) throws SemanticException { @@ -600,28 +772,31 @@ private SubstringDomain closure( SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - ExpressionInverseSet toModify; - ExpressionInverseSet iterate; + ExpressionInverseSet set = result.getState(id); - do { - toModify = result.getState(id); - iterate = result.getState(id); + for (SymbolicExpression se : set) { + if (se instanceof Variable) { + Variable variable = (Variable) se; - for (SymbolicExpression se : toModify) { - if (se instanceof Variable) { - Variable variable = (Variable) se; + // Variable found --> add the relations of variable to id - if (result.knowsIdentifier(variable)) { - Set add = new HashSet<>(result.getState(variable).elements); - result = result.add(add, id); - } + if (result.knowsIdentifier(variable)) { + Set add = new HashSet<>(result.getState(variable).elements); + result = result.add(add, id); } } - } while (!iterate.equals(toModify)); + } return result; } + /** + * Performs the closure over the domain. + * + * @return A copy of the domain with the added relations + * + * @throws SemanticException + */ private SubstringDomain closure() throws SemanticException { if (isTop() || isBottom()) return this; @@ -634,16 +809,27 @@ private SubstringDomain closure() throws SemanticException { Set set = prev.function.keySet(); for (Identifier id : set) { + // Perform the closure on every identifier of the domain result = result.closure(id); } result = result.clear(); + + // Some relations may be added; check that close is applied + // correctly to the added relations } while (!prev.equals(result)); return result; } + /** + * Removes values mapped to empty set (top) + * + * @return A copy of the domain without variables mapped to empty set + * + * @throws SemanticException + */ private SubstringDomain clear() throws SemanticException { SubstringDomain result = mk(lattice, mkNewFunction(function, false)); @@ -658,6 +844,14 @@ private SubstringDomain clear() throws SemanticException { return result; } + /** + * Checks if a variable appears in an expression + * + * @param id Variable to check + * @param expr expression to analyze + * + * @return {@code true} if {@code id} appears, {@code false} otherwise + */ private static boolean appears( Identifier id, SymbolicExpression expr) { diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 156838c51..012e09330 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -219,6 +219,14 @@ public void testAssumeEmpty6() throws SemanticException { assertTrue(assumed.getState(x).contains(w)); } + @Test + public void testAssumeEmpty7() throws SemanticException { + SubstringDomain empty = new SubstringDomain(); + SubstringDomain assumed = empty.assume(XEqualsY, null, null, null); + assertTrue(assumed.getState(x).contains(y)); + assertTrue(assumed.getState(y).contains(x)); + } + @Test public void testAssume1() throws SemanticException { SubstringDomain assume1 = domainB.assume(YSubstringOfX, null, null, null); From 047d7a7bf8a7f170f62e999f4ff74473c33cbfc1 Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Tue, 23 Apr 2024 15:35:20 +0200 Subject: [PATCH 14/34] String constant propagation --- .../string/StringConstantPropagation.java | 259 ++++++++++++++++++ .../unive/lisa/cron/StringAnalysesTest.java | 3 +- 2 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java new file mode 100644 index 000000000..13dcb9cd4 --- /dev/null +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -0,0 +1,259 @@ +package it.unive.lisa.analysis.string; + +import it.unive.lisa.analysis.BaseLattice; +import it.unive.lisa.analysis.Lattice; +import it.unive.lisa.analysis.SemanticException; +import it.unive.lisa.analysis.SemanticOracle; +import it.unive.lisa.analysis.lattices.Satisfiability; +import it.unive.lisa.analysis.nonrelational.value.BaseNonRelationalValueDomain; +import it.unive.lisa.analysis.nonrelational.value.ValueEnvironment; +import it.unive.lisa.program.cfg.ProgramPoint; +import it.unive.lisa.symbolic.value.Constant; +import it.unive.lisa.symbolic.value.Identifier; +import it.unive.lisa.symbolic.value.ValueExpression; +import it.unive.lisa.symbolic.value.operator.AdditionOperator; +import it.unive.lisa.symbolic.value.operator.DivisionOperator; +import it.unive.lisa.symbolic.value.operator.ModuloOperator; +import it.unive.lisa.symbolic.value.operator.MultiplicationOperator; +import it.unive.lisa.symbolic.value.operator.RemainderOperator; +import it.unive.lisa.symbolic.value.operator.SubtractionOperator; +import it.unive.lisa.symbolic.value.operator.binary.BinaryOperator; +import it.unive.lisa.symbolic.value.operator.binary.ComparisonEq; +import it.unive.lisa.symbolic.value.operator.binary.ComparisonGe; +import it.unive.lisa.symbolic.value.operator.binary.ComparisonGt; +import it.unive.lisa.symbolic.value.operator.binary.ComparisonLe; +import it.unive.lisa.symbolic.value.operator.binary.ComparisonLt; +import it.unive.lisa.symbolic.value.operator.binary.ComparisonNe; +import it.unive.lisa.symbolic.value.operator.binary.StringConcat; +import it.unive.lisa.symbolic.value.operator.ternary.TernaryOperator; +import it.unive.lisa.symbolic.value.operator.unary.NumericNegation; +import it.unive.lisa.symbolic.value.operator.unary.UnaryOperator; +import it.unive.lisa.util.representation.StringRepresentation; +import it.unive.lisa.util.representation.StructuredRepresentation; + +public class StringConstantPropagation implements BaseNonRelationalValueDomain { + + private static final StringConstantPropagation TOP = new StringConstantPropagation(true, false); + private static final StringConstantPropagation BOTTOM = new StringConstantPropagation(false, true); + + private final boolean isTop, isBottom; + + private final String value; + + /** + * Builds the top abstract value. + */ + public StringConstantPropagation() { + this(null, true, false); + } + + private StringConstantPropagation( + String value, + boolean isTop, + boolean isBottom) { + this.value = value; + this.isTop = isTop; + this.isBottom = isBottom; + } + + /** + * Builds the abstract value for the given constant. + * + * @param value the constant + */ + public StringConstantPropagation( + String value) { + this(value, false, false); + } + + private StringConstantPropagation( + boolean isTop, + boolean isBottom) { + this(null, isTop, isBottom); + } + + @Override + public StringConstantPropagation top() { + return TOP; + } + + @Override + public boolean isTop() { + return isTop; + } + + @Override + public StringConstantPropagation bottom() { + return BOTTOM; + } + + @Override + public StructuredRepresentation representation() { + if (isBottom()) + return Lattice.bottomRepresentation(); + if (isTop()) + return Lattice.topRepresentation(); + + return new StringRepresentation(value); + } + + @Override + public StringConstantPropagation evalNullConstant( + ProgramPoint pp, + SemanticOracle oracle) { + return top(); + } + + @Override + public StringConstantPropagation evalNonNullConstant( + Constant constant, + ProgramPoint pp, + SemanticOracle oracle) { + if (constant.getValue() instanceof String) + return new StringConstantPropagation((String) constant.getValue()); + + return top(); + } + + @Override + public StringConstantPropagation evalUnaryExpression( + UnaryOperator operator, + StringConstantPropagation arg, + ProgramPoint pp, + SemanticOracle oracle) { + + // return top(); + + return this; + } + + @Override + public StringConstantPropagation evalBinaryExpression( + BinaryOperator operator, + StringConstantPropagation left, + StringConstantPropagation right, + ProgramPoint pp, + SemanticOracle oracle) { + + if (operator instanceof StringConcat) + return left.isTop() || right.isTop() ? top() : new StringConstantPropagation(left.value + right.value); + + // return top(); + return this; + } + + @Override + public StringConstantPropagation evalTernaryExpression( + TernaryOperator operator, + StringConstantPropagation left, + StringConstantPropagation middle, + StringConstantPropagation right, + ProgramPoint pp, + SemanticOracle oracle) { + // return top(); + + return this; + } + + @Override + public StringConstantPropagation lubAux( + StringConstantPropagation other) + throws SemanticException { + return TOP; + } + + @Override + public boolean lessOrEqualAux( + StringConstantPropagation other) + throws SemanticException { + return false; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (isBottom ? 1231 : 1237); + result = prime * result + (isTop ? 1231 : 1237); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals( + Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StringConstantPropagation other = (StringConstantPropagation) obj; + if (isBottom != other.isBottom) + return false; + if (isTop != other.isTop) + return false; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + + @Override + public Satisfiability satisfiesBinaryExpression( + BinaryOperator operator, + StringConstantPropagation left, + StringConstantPropagation right, + ProgramPoint pp, + SemanticOracle oracle) { + + if (left.isTop() || right.isTop()) + return Satisfiability.UNKNOWN; + + if (operator == ComparisonEq.INSTANCE) + return left.value.equals(right.value) ? Satisfiability.SATISFIED + : Satisfiability.NOT_SATISFIED; + else if (operator == ComparisonGe.INSTANCE) + return left.value.compareTo(right.value) >= 0 ? Satisfiability.SATISFIED : Satisfiability.NOT_SATISFIED; + else if (operator == ComparisonGt.INSTANCE) + return left.value.compareTo(right.value) > 0 ? Satisfiability.SATISFIED : Satisfiability.NOT_SATISFIED; + else if (operator == ComparisonLe.INSTANCE) + return left.value.compareTo(right.value) <= 0 ? Satisfiability.SATISFIED : Satisfiability.NOT_SATISFIED; + else if (operator == ComparisonLt.INSTANCE) + return left.value.compareTo(right.value) < 0 ? Satisfiability.SATISFIED : Satisfiability.NOT_SATISFIED; + else if (operator == ComparisonNe.INSTANCE) + return !left.value.equals(right.value) ? Satisfiability.SATISFIED + : Satisfiability.NOT_SATISFIED; + + else + return Satisfiability.UNKNOWN; + } + + @Override + public ValueEnvironment assumeBinaryExpression( + ValueEnvironment environment, + BinaryOperator operator, + ValueExpression left, + ValueExpression right, + ProgramPoint src, + ProgramPoint dest, + SemanticOracle oracle) + throws SemanticException { + + if (operator == ComparisonEq.INSTANCE) + if (left instanceof Identifier) { + StringConstantPropagation eval = eval(right, environment, src, oracle); + if (eval.isBottom()) + return environment.bottom(); + return environment.putState((Identifier) left, eval); + } else if (right instanceof Identifier) { + StringConstantPropagation eval = eval(left, environment, src, oracle); + if (eval.isBottom()) + return environment.bottom(); + return environment.putState((Identifier) right, eval); + } + return environment; + } +} diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 04d41209e..df9b5b158 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -11,7 +11,6 @@ import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; -import it.unive.lisa.conf.LiSAConfiguration.GraphType; import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { @@ -120,7 +119,7 @@ public void testSubstringDomain() { conf.testDir = "string"; conf.testSubDir = "subs-domain"; conf.programFile = "strings-subs.imp"; - //conf.analysisGraphs = GraphType.DOT; + // conf.analysisGraphs = GraphType.DOT; perform(conf); } From 911fd54192dacf6d7958c5643f25f01640f182e0 Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Thu, 25 Apr 2024 12:20:35 +0200 Subject: [PATCH 15/34] Substring domain with string constant propagation + tests --- .../string/strings-subs-constants.imp | 11 ++++ .../string/subs-domain-constants/report.json | 38 ++++++++++++ ...yped_strings.constants(strings__this).json | 1 + .../string/StringConstantPropagation.java | 49 +++++----------- .../lisa/analysis/string/SubstringDomain.java | 6 +- .../string/SubstringDomainWithConstants.java | 58 +++++++++++++++++++ .../string/StringConstantPropagationTest.java | 47 +++++++++++++++ .../unive/lisa/cron/StringAnalysesTest.java | 19 ++++++ 8 files changed, 193 insertions(+), 36 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.constants(strings__this).json create mode 100644 lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java create mode 100644 lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/StringConstantPropagationTest.java diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp new file mode 100644 index 000000000..c97ed161c --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp @@ -0,0 +1,11 @@ +class strings { + + constants(){ + + def x = "ab"; + def y = "a"; + def z = "b"; + def w = y + z; + + } +} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json new file mode 100644 index 000000000..6ffe44530 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json @@ -0,0 +1,38 @@ +{ + "warnings" : [ ], + "files" : [ "report.json", "untyped_strings.constants(strings__this).json" ], + "info" : { + "cfgs" : "1", + "duration" : "4ms", + "end" : "2024-04-25T12:15:23.636+02:00", + "expressions" : "10", + "files" : "1", + "globals" : "0", + "members" : "1", + "programs" : "1", + "start" : "2024-04-25T12:15:23.632+02:00", + "statements" : "5", + "units" : "1", + "version" : "0.1b9", + "warnings" : "0" + }, + "configuration" : { + "analysisGraphs" : "NONE", + "descendingPhaseType" : "NONE", + "dumpForcesUnwinding" : "false", + "fixpointWorkingSet" : "DuplicateFreeFIFOWorkingSet", + "glbThreshold" : "5", + "hotspots" : "unset", + "jsonOutput" : "true", + "openCallPolicy" : "WorstCasePolicy", + "optimize" : "false", + "recursionWideningThreshold" : "5", + "semanticChecks" : "", + "serializeInputs" : "false", + "serializeResults" : "true", + "syntacticChecks" : "", + "useWideningPoints" : "true", + "wideningThreshold" : "5", + "workdir" : "test-outputs/string/subs-domain-constants" + } +} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.constants(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.constants(strings__this).json new file mode 100644 index 000000000..7cf053228 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.constants(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::constants(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"ab\""},{"id":1,"text":"x"},{"id":2,"text":"\"ab\""},{"id":3,"subNodes":[4,5],"text":"y = \"a\""},{"id":4,"text":"y"},{"id":5,"text":"\"a\""},{"id":6,"subNodes":[7,8],"text":"z = \"b\""},{"id":7,"text":"z"},{"id":8,"text":"\"b\""},{"id":9,"subNodes":[10,11],"text":"w = +(y, z)"},{"id":10,"text":"w"},{"id":11,"subNodes":[12,13],"text":"+(y, z)"},{"id":12,"text":"y"},{"id":13,"text":"z"},{"id":14,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"SequentialEdge"},{"sourceId":9,"destId":14,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":[{"x":"ab"},{"x":["\"a\"","\"ab\"","\"b\""]}]}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":["#TOP#","#TOP#"]}}},{"nodeId":2,"description":{"expressions":["\"ab\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":["#TOP#","#TOP#"]}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"x":"ab","y":"a"},{"x":["\"a\"","\"ab\"","\"b\"","y"],"y":["\"a\""]}]}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":[{"x":"ab"},{"x":["\"a\"","\"ab\"","\"b\""]}]}}},{"nodeId":5,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":[{"x":"ab"},{"x":["\"a\"","\"ab\"","\"b\""]}]}}},{"nodeId":6,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"x":"ab","y":"a","z":"b"},{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}]}}},{"nodeId":7,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"x":"ab","y":"a"},{"x":["\"a\"","\"ab\"","\"b\"","y"],"y":["\"a\""]}]}}},{"nodeId":8,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"x":"ab","y":"a"},{"x":["\"a\"","\"ab\"","\"b\"","y"],"y":["\"a\""]}]}}},{"nodeId":9,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"w":"ab","x":"ab","y":"a","z":"b"},{"w":["\"a\"","\"ab\"","\"b\"","x","y","y strcat z","z"],"x":["\"a\"","\"ab\"","\"b\"","w","y","y strcat z","z"],"y":["\"a\""],"z":["\"b\""]}]}}},{"nodeId":10,"description":{"expressions":["w"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"x":"ab","y":"a","z":"b"},{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}]}}},{"nodeId":11,"description":{"expressions":["y strcat z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"x":"ab","y":"a","z":"b"},{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}]}}},{"nodeId":12,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"x":"ab","y":"a","z":"b"},{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}]}}},{"nodeId":13,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"x":"ab","y":"a","z":"b"},{"x":["\"a\"","\"ab\"","\"b\"","y","z"],"y":["\"a\""],"z":["\"b\""]}]}}},{"nodeId":14,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"w":["string"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"w":"ab","x":"ab","y":"a","z":"b"},{"w":["\"a\"","\"ab\"","\"b\"","x","y","y strcat z","z"],"x":["\"a\"","\"ab\"","\"b\"","w","y","y strcat z","z"],"y":["\"a\""],"z":["\"b\""]}]}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index 13dcb9cd4..026050e32 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -24,7 +24,10 @@ import it.unive.lisa.symbolic.value.operator.binary.ComparisonLe; import it.unive.lisa.symbolic.value.operator.binary.ComparisonLt; import it.unive.lisa.symbolic.value.operator.binary.ComparisonNe; +import it.unive.lisa.symbolic.value.operator.binary.LogicalAnd; +import it.unive.lisa.symbolic.value.operator.binary.LogicalOr; import it.unive.lisa.symbolic.value.operator.binary.StringConcat; +import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; import it.unive.lisa.symbolic.value.operator.ternary.TernaryOperator; import it.unive.lisa.symbolic.value.operator.unary.NumericNegation; import it.unive.lisa.symbolic.value.operator.unary.UnaryOperator; @@ -122,9 +125,7 @@ public StringConstantPropagation evalUnaryExpression( ProgramPoint pp, SemanticOracle oracle) { - // return top(); - - return this; + return top(); } @Override @@ -138,8 +139,7 @@ public StringConstantPropagation evalBinaryExpression( if (operator instanceof StringConcat) return left.isTop() || right.isTop() ? top() : new StringConstantPropagation(left.value + right.value); - // return top(); - return this; + return top(); } @Override @@ -150,9 +150,18 @@ public StringConstantPropagation evalTernaryExpression( StringConstantPropagation right, ProgramPoint pp, SemanticOracle oracle) { - // return top(); - return this; + if (operator instanceof StringReplace) { + if (left.isTop() || right.isTop() || middle.isTop()) + return top(); + + String replaced = left.value; + replaced = replaced.replace(middle.value, right.value); + + return new StringConstantPropagation(replaced); + } + return top(); + } @Override @@ -230,30 +239,4 @@ else if (operator == ComparisonNe.INSTANCE) else return Satisfiability.UNKNOWN; } - - @Override - public ValueEnvironment assumeBinaryExpression( - ValueEnvironment environment, - BinaryOperator operator, - ValueExpression left, - ValueExpression right, - ProgramPoint src, - ProgramPoint dest, - SemanticOracle oracle) - throws SemanticException { - - if (operator == ComparisonEq.INSTANCE) - if (left instanceof Identifier) { - StringConstantPropagation eval = eval(right, environment, src, oracle); - if (eval.isBottom()) - return environment.bottom(); - return environment.putState((Identifier) left, eval); - } else if (right instanceof Identifier) { - StringConstantPropagation eval = eval(left, environment, src, oracle); - if (eval.isBottom()) - return environment.bottom(); - return environment.putState((Identifier) right, eval); - } - return environment; - } } diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index ddb9490e2..59fec3dff 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -521,7 +521,7 @@ private static List mergeStringLiterals( for (SymbolicExpression expr : extracted) { if (expr instanceof Constant) { - // Update the string builder value addinf the value of the + // Update the string builder value adding the value of the // constant Constant c = (Constant) expr; recent.append(c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString()); @@ -651,7 +651,7 @@ private static SymbolicExpression composeExpression( * * @throws SemanticException */ - private SubstringDomain add( + protected SubstringDomain add( Set symbolicExpressions, Identifier id) throws SemanticException { @@ -797,7 +797,7 @@ private SubstringDomain closure( * * @throws SemanticException */ - private SubstringDomain closure() throws SemanticException { + protected SubstringDomain closure() throws SemanticException { if (isTop() || isBottom()) return this; diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java new file mode 100644 index 000000000..18482a0d6 --- /dev/null +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java @@ -0,0 +1,58 @@ +package it.unive.lisa.analysis.string; +import java.util.HashSet; +import java.util.Map.Entry; +import java.util.Set; + +import it.unive.lisa.analysis.SemanticException; +import it.unive.lisa.analysis.SemanticOracle; +import it.unive.lisa.analysis.combination.ValueCartesianProduct; +import it.unive.lisa.analysis.nonrelational.value.ValueEnvironment; +import it.unive.lisa.program.cfg.ProgramPoint; +import it.unive.lisa.symbolic.SymbolicExpression; +import it.unive.lisa.symbolic.value.Identifier; +import it.unive.lisa.symbolic.value.ValueExpression; + + +public class SubstringDomainWithConstants extends ValueCartesianProduct, SubstringDomain>{ + public SubstringDomainWithConstants(ValueEnvironment left, SubstringDomain right) { + super(left, right); + } + + public SubstringDomainWithConstants() { + this(new ValueEnvironment(new StringConstantPropagation()), new SubstringDomain()); + } + + @Override + public SubstringDomainWithConstants assign(Identifier id, + ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) throws SemanticException { + + + ValueEnvironment a = this.left.assign(id, expression, pp, oracle); + SubstringDomain b = this.right.assign(id, expression, pp, oracle); + + StringConstantPropagation compare = a.getState(id); + + if (!compare.isTop() && !compare.isBottom()) { + for (Entry elem : a) { + if (elem.getKey().equals(id)) + continue; + + if (elem.getValue().equals(compare)) { + Set add = new HashSet<>(); + add.add(elem.getKey()); + add.add(id); + + b = b.add(add , id).add(add, elem.getKey()).closure(); + } + } + } + + return mk(a, b); + } + + @Override + public SubstringDomainWithConstants mk( + ValueEnvironment left, SubstringDomain right) { + return new SubstringDomainWithConstants(left, right); + } +} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/StringConstantPropagationTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/StringConstantPropagationTest.java new file mode 100644 index 000000000..7884f2b81 --- /dev/null +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/StringConstantPropagationTest.java @@ -0,0 +1,47 @@ +package it.unive.lisa.analysis.string; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import it.unive.lisa.symbolic.value.operator.binary.StringConcat; +import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; + +public class StringConstantPropagationTest { + + @Test + public void testConstructor() { + new StringConstantPropagation(); + } + + @Test + public void testConstructor1() { + new StringConstantPropagation("Hello World!"); + } + + @Test + public void testEvalBinary() { + StringConstantPropagation domain = new StringConstantPropagation(); + StringConstantPropagation s1 = new StringConstantPropagation("abc"); + StringConstantPropagation s2 = new StringConstantPropagation("def"); + + domain = domain.evalBinaryExpression(StringConcat.INSTANCE, s1, s2, null, null); + + assertEquals(domain, new StringConstantPropagation("abcdef")); + } + + @Test + public void testEvalTernary() { + StringConstantPropagation domain = new StringConstantPropagation(); + StringConstantPropagation s1 = new StringConstantPropagation("aaa"); + StringConstantPropagation s2 = new StringConstantPropagation("aa"); + StringConstantPropagation s3 = new StringConstantPropagation("b"); + + domain = domain.evalTernaryExpression(StringReplace.INSTANCE, s1, s2, s3, null, null); + + assertEquals(domain, new StringConstantPropagation("ba")); + } + +} diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index df9b5b158..1f5748683 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -7,10 +7,13 @@ import it.unive.lisa.analysis.string.CharInclusion; import it.unive.lisa.analysis.string.Prefix; import it.unive.lisa.analysis.string.SubstringDomain; +import it.unive.lisa.analysis.string.SubstringDomainWithConstants; import it.unive.lisa.analysis.string.Suffix; import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; +import it.unive.lisa.conf.LiSAConfiguration.GraphType; + import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { @@ -123,4 +126,20 @@ public void testSubstringDomain() { perform(conf); } + + @Test + public void testSubstringDomainWithConstants() { + CronConfiguration conf = new CronConfiguration(); + conf.serializeResults = true; // dump results + conf.abstractState = DefaultConfiguration.simpleState( + DefaultConfiguration.defaultHeapDomain(), + new SubstringDomainWithConstants(), + DefaultConfiguration.defaultTypeDomain()); + conf.testDir = "string"; + conf.testSubDir = "subs-domain-constants"; + conf.programFile = "strings-subs-constants.imp"; + // conf.analysisGraphs = GraphType.DOT; + perform(conf); + + } } From 13e80945fe50798a780bfc010c99b8745df2ebee Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Thu, 25 Apr 2024 12:27:10 +0200 Subject: [PATCH 16/34] More tests --- .../string/strings-subs-constants.imp | 10 ++++++++++ .../string/subs-domain-constants/report.json | 18 +++++++++--------- ...ings.replace(strings__this,_untyped_s).json | 1 + 3 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp index c97ed161c..127f88919 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp @@ -8,4 +8,14 @@ class strings { def w = y + z; } + + replace(s){ + def x = "aaaaa"; + def y = "bba"; + def k = "bb" + "a"; + def z = strrep(x, "aa", "b"); + + if (streq(s, k)) + def i = 1 + 1; + } } \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json index 6ffe44530..75979178f 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json @@ -1,17 +1,17 @@ { "warnings" : [ ], - "files" : [ "report.json", "untyped_strings.constants(strings__this).json" ], + "files" : [ "report.json", "untyped_strings.constants(strings__this).json", "untyped_strings.replace(strings__this,_untyped_s).json" ], "info" : { - "cfgs" : "1", - "duration" : "4ms", - "end" : "2024-04-25T12:15:23.636+02:00", - "expressions" : "10", - "files" : "1", + "cfgs" : "2", + "duration" : "11ms", + "end" : "2024-04-25T12:26:36.264+02:00", + "expressions" : "29", + "files" : "2", "globals" : "0", - "members" : "1", + "members" : "2", "programs" : "1", - "start" : "2024-04-25T12:15:23.632+02:00", - "statements" : "5", + "start" : "2024-04-25T12:26:36.253+02:00", + "statements" : "12", "units" : "1", "version" : "0.1b9", "warnings" : "0" diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json new file mode 100644 index 000000000..493bd9d8f --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json @@ -0,0 +1 @@ +{"name":"untyped strings::replace(strings* this, untyped s)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"aaaaa\""},{"id":1,"text":"x"},{"id":2,"text":"\"aaaaa\""},{"id":3,"subNodes":[4,5],"text":"y = \"bba\""},{"id":4,"text":"y"},{"id":5,"text":"\"bba\""},{"id":6,"subNodes":[7,8],"text":"k = +(\"bb\", \"a\")"},{"id":7,"text":"k"},{"id":8,"subNodes":[9,10],"text":"+(\"bb\", \"a\")"},{"id":9,"text":"\"bb\""},{"id":10,"text":"\"a\""},{"id":11,"subNodes":[12,13],"text":"z = replace(x, \"aa\", \"b\")"},{"id":12,"text":"z"},{"id":13,"subNodes":[14,15,16],"text":"replace(x, \"aa\", \"b\")"},{"id":14,"text":"x"},{"id":15,"text":"\"aa\""},{"id":16,"text":"\"b\""},{"id":17,"subNodes":[18,19],"text":"equals(s, k)"},{"id":18,"text":"s"},{"id":19,"text":"k"},{"id":20,"subNodes":[21,22],"text":"i = +(1, 1)"},{"id":21,"text":"i"},{"id":22,"subNodes":[23,24],"text":"+(1, 1)"},{"id":23,"text":"1"},{"id":24,"text":"1"},{"id":25,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":11,"kind":"SequentialEdge"},{"sourceId":11,"destId":17,"kind":"SequentialEdge"},{"sourceId":17,"destId":20,"kind":"TrueEdge"},{"sourceId":17,"destId":25,"kind":"FalseEdge"},{"sourceId":20,"destId":25,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":2,"description":{"expressions":["\"aaaaa\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":5,"description":{"expressions":["\"bba\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":6,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":7,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":8,"description":{"expressions":["\"bb\" strcat \"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":9,"description":{"expressions":["\"bb\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":10,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":11,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":12,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":13,"description":{"expressions":["x strreplace(\"aa\", \"b\")"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":15,"description":{"expressions":["\"aa\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":16,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":17,"description":{"expressions":["s strcmp k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":18,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":19,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":20,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"i":"#TOP#","k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":21,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":22,"description":{"expressions":["1 + 1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":23,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":24,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":25,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"i":["int32"],"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"i":"#TOP#","k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}}]} \ No newline at end of file From 9c4198b59261009159a95a648783fba3d8652ae8 Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Thu, 25 Apr 2024 12:29:31 +0200 Subject: [PATCH 17/34] Spotless apply --- .../string/StringConstantPropagation.java | 25 +++-------- .../string/SubstringDomainWithConstants.java | 45 +++++++++++-------- .../string/StringConstantPropagationTest.java | 15 +++---- .../unive/lisa/cron/StringAnalysesTest.java | 4 +- 4 files changed, 39 insertions(+), 50 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index 026050e32..c71063bb9 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -1,22 +1,12 @@ package it.unive.lisa.analysis.string; -import it.unive.lisa.analysis.BaseLattice; import it.unive.lisa.analysis.Lattice; import it.unive.lisa.analysis.SemanticException; import it.unive.lisa.analysis.SemanticOracle; import it.unive.lisa.analysis.lattices.Satisfiability; import it.unive.lisa.analysis.nonrelational.value.BaseNonRelationalValueDomain; -import it.unive.lisa.analysis.nonrelational.value.ValueEnvironment; import it.unive.lisa.program.cfg.ProgramPoint; import it.unive.lisa.symbolic.value.Constant; -import it.unive.lisa.symbolic.value.Identifier; -import it.unive.lisa.symbolic.value.ValueExpression; -import it.unive.lisa.symbolic.value.operator.AdditionOperator; -import it.unive.lisa.symbolic.value.operator.DivisionOperator; -import it.unive.lisa.symbolic.value.operator.ModuloOperator; -import it.unive.lisa.symbolic.value.operator.MultiplicationOperator; -import it.unive.lisa.symbolic.value.operator.RemainderOperator; -import it.unive.lisa.symbolic.value.operator.SubtractionOperator; import it.unive.lisa.symbolic.value.operator.binary.BinaryOperator; import it.unive.lisa.symbolic.value.operator.binary.ComparisonEq; import it.unive.lisa.symbolic.value.operator.binary.ComparisonGe; @@ -24,12 +14,9 @@ import it.unive.lisa.symbolic.value.operator.binary.ComparisonLe; import it.unive.lisa.symbolic.value.operator.binary.ComparisonLt; import it.unive.lisa.symbolic.value.operator.binary.ComparisonNe; -import it.unive.lisa.symbolic.value.operator.binary.LogicalAnd; -import it.unive.lisa.symbolic.value.operator.binary.LogicalOr; import it.unive.lisa.symbolic.value.operator.binary.StringConcat; import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; import it.unive.lisa.symbolic.value.operator.ternary.TernaryOperator; -import it.unive.lisa.symbolic.value.operator.unary.NumericNegation; import it.unive.lisa.symbolic.value.operator.unary.UnaryOperator; import it.unive.lisa.util.representation.StringRepresentation; import it.unive.lisa.util.representation.StructuredRepresentation; @@ -114,7 +101,7 @@ public StringConstantPropagation evalNonNullConstant( SemanticOracle oracle) { if (constant.getValue() instanceof String) return new StringConstantPropagation((String) constant.getValue()); - + return top(); } @@ -138,7 +125,7 @@ public StringConstantPropagation evalBinaryExpression( if (operator instanceof StringConcat) return left.isTop() || right.isTop() ? top() : new StringConstantPropagation(left.value + right.value); - + return top(); } @@ -150,18 +137,18 @@ public StringConstantPropagation evalTernaryExpression( StringConstantPropagation right, ProgramPoint pp, SemanticOracle oracle) { - + if (operator instanceof StringReplace) { if (left.isTop() || right.isTop() || middle.isTop()) return top(); - + String replaced = left.value; replaced = replaced.replace(middle.value, right.value); - + return new StringConstantPropagation(replaced); } return top(); - + } @Override diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java index 18482a0d6..0f2dccd58 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java @@ -1,7 +1,4 @@ package it.unive.lisa.analysis.string; -import java.util.HashSet; -import java.util.Map.Entry; -import java.util.Set; import it.unive.lisa.analysis.SemanticException; import it.unive.lisa.analysis.SemanticOracle; @@ -11,48 +8,58 @@ import it.unive.lisa.symbolic.SymbolicExpression; import it.unive.lisa.symbolic.value.Identifier; import it.unive.lisa.symbolic.value.ValueExpression; +import java.util.HashSet; +import java.util.Map.Entry; +import java.util.Set; - -public class SubstringDomainWithConstants extends ValueCartesianProduct, SubstringDomain>{ - public SubstringDomainWithConstants(ValueEnvironment left, SubstringDomain right) { +public class SubstringDomainWithConstants + extends + ValueCartesianProduct, SubstringDomain> { + public SubstringDomainWithConstants( + ValueEnvironment left, + SubstringDomain right) { super(left, right); } - + public SubstringDomainWithConstants() { this(new ValueEnvironment(new StringConstantPropagation()), new SubstringDomain()); } - + @Override - public SubstringDomainWithConstants assign(Identifier id, - ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) throws SemanticException { - - + public SubstringDomainWithConstants assign( + Identifier id, + ValueExpression expression, + ProgramPoint pp, + SemanticOracle oracle) + throws SemanticException { + ValueEnvironment a = this.left.assign(id, expression, pp, oracle); SubstringDomain b = this.right.assign(id, expression, pp, oracle); - + StringConstantPropagation compare = a.getState(id); if (!compare.isTop() && !compare.isBottom()) { for (Entry elem : a) { if (elem.getKey().equals(id)) continue; - + if (elem.getValue().equals(compare)) { Set add = new HashSet<>(); add.add(elem.getKey()); add.add(id); - - b = b.add(add , id).add(add, elem.getKey()).closure(); + + b = b.add(add, id).add(add, elem.getKey()).closure(); } } } - + return mk(a, b); } - + @Override public SubstringDomainWithConstants mk( - ValueEnvironment left, SubstringDomain right) { + ValueEnvironment left, + SubstringDomain right) { return new SubstringDomainWithConstants(left, right); } } \ No newline at end of file diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/StringConstantPropagationTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/StringConstantPropagationTest.java index 7884f2b81..74e40e86a 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/StringConstantPropagationTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/StringConstantPropagationTest.java @@ -1,13 +1,10 @@ package it.unive.lisa.analysis.string; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; import it.unive.lisa.symbolic.value.operator.binary.StringConcat; import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; +import org.junit.Test; public class StringConstantPropagationTest { @@ -20,7 +17,7 @@ public void testConstructor() { public void testConstructor1() { new StringConstantPropagation("Hello World!"); } - + @Test public void testEvalBinary() { StringConstantPropagation domain = new StringConstantPropagation(); @@ -28,10 +25,10 @@ public void testEvalBinary() { StringConstantPropagation s2 = new StringConstantPropagation("def"); domain = domain.evalBinaryExpression(StringConcat.INSTANCE, s1, s2, null, null); - + assertEquals(domain, new StringConstantPropagation("abcdef")); } - + @Test public void testEvalTernary() { StringConstantPropagation domain = new StringConstantPropagation(); @@ -40,8 +37,8 @@ public void testEvalTernary() { StringConstantPropagation s3 = new StringConstantPropagation("b"); domain = domain.evalTernaryExpression(StringReplace.INSTANCE, s1, s2, s3, null, null); - + assertEquals(domain, new StringConstantPropagation("ba")); } - + } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 1f5748683..c91f3c194 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -12,8 +12,6 @@ import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; -import it.unive.lisa.conf.LiSAConfiguration.GraphType; - import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { @@ -126,7 +124,7 @@ public void testSubstringDomain() { perform(conf); } - + @Test public void testSubstringDomainWithConstants() { CronConfiguration conf = new CronConfiguration(); From d85b624558a1466452087a5e0b3a53a5b697c412 Mon Sep 17 00:00:00 2001 From: Michele Date: Fri, 14 Jun 2024 17:31:11 +0200 Subject: [PATCH 18/34] Bug fix in substring domain --- ...ngs.replace(strings__this,_untyped_s).json | 2 +- .../string/StringConstantPropagation.java | 6 +-- .../lisa/analysis/string/SubstringDomain.java | 43 ++++++++++--------- .../unive/lisa/cron/StringAnalysesTest.java | 7 +-- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json index 493bd9d8f..32570832f 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json @@ -1 +1 @@ -{"name":"untyped strings::replace(strings* this, untyped s)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"aaaaa\""},{"id":1,"text":"x"},{"id":2,"text":"\"aaaaa\""},{"id":3,"subNodes":[4,5],"text":"y = \"bba\""},{"id":4,"text":"y"},{"id":5,"text":"\"bba\""},{"id":6,"subNodes":[7,8],"text":"k = +(\"bb\", \"a\")"},{"id":7,"text":"k"},{"id":8,"subNodes":[9,10],"text":"+(\"bb\", \"a\")"},{"id":9,"text":"\"bb\""},{"id":10,"text":"\"a\""},{"id":11,"subNodes":[12,13],"text":"z = replace(x, \"aa\", \"b\")"},{"id":12,"text":"z"},{"id":13,"subNodes":[14,15,16],"text":"replace(x, \"aa\", \"b\")"},{"id":14,"text":"x"},{"id":15,"text":"\"aa\""},{"id":16,"text":"\"b\""},{"id":17,"subNodes":[18,19],"text":"equals(s, k)"},{"id":18,"text":"s"},{"id":19,"text":"k"},{"id":20,"subNodes":[21,22],"text":"i = +(1, 1)"},{"id":21,"text":"i"},{"id":22,"subNodes":[23,24],"text":"+(1, 1)"},{"id":23,"text":"1"},{"id":24,"text":"1"},{"id":25,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":11,"kind":"SequentialEdge"},{"sourceId":11,"destId":17,"kind":"SequentialEdge"},{"sourceId":17,"destId":20,"kind":"TrueEdge"},{"sourceId":17,"destId":25,"kind":"FalseEdge"},{"sourceId":20,"destId":25,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":2,"description":{"expressions":["\"aaaaa\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":5,"description":{"expressions":["\"bba\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":6,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":7,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":8,"description":{"expressions":["\"bb\" strcat \"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":9,"description":{"expressions":["\"bb\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":10,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":11,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":12,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":13,"description":{"expressions":["x strreplace(\"aa\", \"b\")"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":15,"description":{"expressions":["\"aa\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":16,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":17,"description":{"expressions":["s strcmp k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":18,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":19,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":20,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"i":"#TOP#","k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":21,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":22,"description":{"expressions":["1 + 1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":23,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":24,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":25,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"i":["int32"],"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"i":"#TOP#","k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}}]} \ No newline at end of file +{"name":"untyped strings::replace(strings* this, untyped s)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"aaaaa\""},{"id":1,"text":"x"},{"id":2,"text":"\"aaaaa\""},{"id":3,"subNodes":[4,5],"text":"y = \"bba\""},{"id":4,"text":"y"},{"id":5,"text":"\"bba\""},{"id":6,"subNodes":[7,8],"text":"k = +(\"bb\", \"a\")"},{"id":7,"text":"k"},{"id":8,"subNodes":[9,10],"text":"+(\"bb\", \"a\")"},{"id":9,"text":"\"bb\""},{"id":10,"text":"\"a\""},{"id":11,"subNodes":[12,13],"text":"z = replace(x, \"aa\", \"b\")"},{"id":12,"text":"z"},{"id":13,"subNodes":[14,15,16],"text":"replace(x, \"aa\", \"b\")"},{"id":14,"text":"x"},{"id":15,"text":"\"aa\""},{"id":16,"text":"\"b\""},{"id":17,"subNodes":[18,19],"text":"equals(s, k)"},{"id":18,"text":"s"},{"id":19,"text":"k"},{"id":20,"subNodes":[21,22],"text":"i = +(1, 1)"},{"id":21,"text":"i"},{"id":22,"subNodes":[23,24],"text":"+(1, 1)"},{"id":23,"text":"1"},{"id":24,"text":"1"},{"id":25,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":11,"kind":"SequentialEdge"},{"sourceId":11,"destId":17,"kind":"SequentialEdge"},{"sourceId":17,"destId":20,"kind":"TrueEdge"},{"sourceId":17,"destId":25,"kind":"FalseEdge"},{"sourceId":20,"destId":25,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":2,"description":{"expressions":["\"aaaaa\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":5,"description":{"expressions":["\"bba\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":6,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":7,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":8,"description":{"expressions":["\"bb\" strcat \"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":9,"description":{"expressions":["\"bb\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":10,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":11,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":12,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":13,"description":{"expressions":["x strreplace(\"aa\", \"b\")"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":15,"description":{"expressions":["\"aa\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":16,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":17,"description":{"expressions":["s strcmp k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":18,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":19,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":20,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"i":"#TOP#","k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":21,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":22,"description":{"expressions":["1 + 1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":23,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":24,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":25,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index c71063bb9..a6601fa6f 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -30,7 +30,7 @@ public class StringConstantPropagation implements BaseNonRelationalValueDomain implements ValueDomain { + + private static final SubstringDomain TOP = new SubstringDomain(new ExpressionInverseSet().top()); + private static final SubstringDomain BOTTOM = new SubstringDomain(new ExpressionInverseSet().bottom()); public SubstringDomain( ExpressionInverseSet lattice, @@ -72,12 +75,12 @@ public SubstringDomain glbAux( @Override public SubstringDomain top() { - return isTop() ? this : new SubstringDomain(lattice.top()); + return isTop() ? this : TOP; } @Override public SubstringDomain bottom() { - return isBottom() ? this : new SubstringDomain(lattice.bottom()); + return isBottom() ? this : BOTTOM; } @Override @@ -101,7 +104,7 @@ public SubstringDomain assign( SemanticOracle oracle) throws SemanticException { - /** + /* * If the assigned expression is not dynamically typed as a string (or * untyped) return this. */ @@ -375,7 +378,7 @@ public SubstringDomain popScope( return new SubstringDomain(lattice.popScope(token), mkNewFunction(function, true)); } - /** + /* * Extract the ordered expressions of a concatenation. If the expression is * not a concatenation returns an empty list. Example: {@code x + y + "ab"} * returns {@code x, y, "ab"} as List @@ -406,7 +409,7 @@ private static List extr( return result; } - /** + /* * Returns all the possible substring of a given expression. * * @param expression @@ -503,7 +506,7 @@ private static Set extrPlus( return new HashSet<>(result); } - /** + /* * Returns a list with no more than one consecutive constant where if * {@code extracted} has consecutive constants, the returned value merges * them @@ -528,9 +531,9 @@ private static List mergeStringLiterals( } else { /* - * Iterating an Variable + * Iterating a Variable */ - if (!recent.isEmpty()) { + if (recent.length() > 0) { // The previous value / values are constants; add to the // list the constant with value the built string result.add(new Constant(strType, recent.toString(), SyntheticLocation.INSTANCE)); @@ -543,13 +546,13 @@ private static List mergeStringLiterals( } // If the last element is a constant add the last built string - if (!recent.isEmpty()) + if (recent.length() > 0) result.add(new Constant(strType, recent.toString(), SyntheticLocation.INSTANCE)); return result; } - /** + /* * Returns the set containing the substrings of a Constant * * @param c Constant to analyze @@ -576,7 +579,7 @@ private static Set getSubstrings( return result; } - /** + /* * Returns the set containing the prefixes of a Constant * * @param c Constant to analyze @@ -598,7 +601,7 @@ private static Set getPrefix( return result; } - /** + /* * Returns the set containing the suffixes of a Constant * * @param c Constant to analyze @@ -622,7 +625,7 @@ private static Set getSuffix( return result; } - /** + /* * Creates am expression given a list. The returned expression is the * ordered concatenation of the expression in the list. * @@ -641,7 +644,7 @@ private static SymbolicExpression composeExpression( SyntheticLocation.INSTANCE); } - /** + /* * Adds a set of expressions to the domain. * * @param symbolicExpressions @@ -679,7 +682,7 @@ protected SubstringDomain add( return mk(lattice, newFunction); } - /** + /* * First step of assignment, removing obsolete relations. * * @param extracted Expression assigned @@ -717,7 +720,7 @@ private SubstringDomain remove( return mk(lattice, newFunction); } - /** + /* * Performs the inter-assignment phase * * @param assignedId Variable getting assigned @@ -756,7 +759,7 @@ private SubstringDomain interasg( return mk(lattice, newFunction); } - /** + /* * Performs the closure over an identifier. The method adds to {@code id} * the expressions found in the variables mapped to {@code id} * @@ -790,7 +793,7 @@ private SubstringDomain closure( return result; } - /** + /* * Performs the closure over the domain. * * @return A copy of the domain with the added relations @@ -823,7 +826,7 @@ protected SubstringDomain closure() throws SemanticException { } - /** + /* * Removes values mapped to empty set (top) * * @return A copy of the domain without variables mapped to empty set @@ -844,7 +847,7 @@ private SubstringDomain clear() throws SemanticException { return result; } - /** + /* * Checks if a variable appears in an expression * * @param id Variable to check diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index c91f3c194..ede65f1aa 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -12,6 +12,8 @@ import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; +import it.unive.lisa.conf.LiSAConfiguration.GraphType; + import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { @@ -120,7 +122,7 @@ public void testSubstringDomain() { conf.testDir = "string"; conf.testSubDir = "subs-domain"; conf.programFile = "strings-subs.imp"; - // conf.analysisGraphs = GraphType.DOT; + //conf.analysisGraphs = GraphType.DOT; perform(conf); } @@ -136,8 +138,7 @@ public void testSubstringDomainWithConstants() { conf.testDir = "string"; conf.testSubDir = "subs-domain-constants"; conf.programFile = "strings-subs-constants.imp"; - // conf.analysisGraphs = GraphType.DOT; + //conf.analysisGraphs = GraphType.DOT; perform(conf); - } } From 1e2a9a0a597a97616941eae8d30b5fc1b9f9d655 Mon Sep 17 00:00:00 2001 From: Michele Date: Fri, 14 Jun 2024 23:05:34 +0200 Subject: [PATCH 19/34] Fix forget identifier + tests --- .../imp-testcases/string/strings-subs.imp | 13 ++++++ .../string/subs-domain/report.json | 18 ++++---- ...untyped_strings.paper2(strings__this).json | 2 +- ...s.scopetest(strings__this,_untyped_x).json | 1 + .../lisa/analysis/string/SubstringDomain.java | 41 +++++++++++++++++-- .../analysis/string/SubstringDomainTest.java | 34 +++++++++++++++ .../unive/lisa/cron/StringAnalysesTest.java | 2 + 7 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.scopetest(strings__this,_untyped_x).json diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp index f325625bc..e87b61f13 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp @@ -142,5 +142,18 @@ class strings { x = "a"; } + scopetest(x){ + def s = "a"; + def y = "z"; + if (x > 0){ + def k = "x"; + y = k; + } else { + def k = "x"; + y = k; + } + s = s + "c"; + } + } \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json index 0632b5f13..951f3609f 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json @@ -1,17 +1,17 @@ { "warnings" : [ ], - "files" : [ "report.json", "untyped_strings.assume(strings__this).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.integers(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json", "untyped_strings.paper1(strings__this).json", "untyped_strings.paper2(strings__this).json", "untyped_strings.paper3(strings__this,_untyped_x).json", "untyped_strings.stringconcat(strings__this).json", "untyped_strings.type(strings__this,_untyped_x).json" ], + "files" : [ "report.json", "untyped_strings.assume(strings__this).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.integers(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json", "untyped_strings.paper1(strings__this).json", "untyped_strings.paper2(strings__this).json", "untyped_strings.paper3(strings__this,_untyped_x).json", "untyped_strings.scopetest(strings__this,_untyped_x).json", "untyped_strings.stringconcat(strings__this).json", "untyped_strings.type(strings__this,_untyped_x).json" ], "info" : { - "cfgs" : "18", - "duration" : "77ms", - "end" : "2024-04-18T17:41:10.990+02:00", - "expressions" : "188", - "files" : "18", + "cfgs" : "19", + "duration" : "92ms", + "end" : "2024-06-14T23:04:08.375+02:00", + "expressions" : "206", + "files" : "19", "globals" : "0", - "members" : "18", + "members" : "19", "programs" : "1", - "start" : "2024-04-18T17:41:10.913+02:00", - "statements" : "91", + "start" : "2024-06-14T23:04:08.283+02:00", + "statements" : "100", "units" : "1", "version" : "0.1b9", "warnings" : "0" diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json index 103be06d2..ebf768c1a 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::paper2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"\""},{"id":1,"text":"x"},{"id":2,"text":"\"\""},{"id":3,"subNodes":[4,5],"text":"y = \"\""},{"id":4,"text":"y"},{"id":5,"text":"\"\""},{"id":6,"subNodes":[7,8],"text":"equals(x, y)"},{"id":7,"text":"x"},{"id":8,"text":"y"},{"id":9,"subNodes":[10,11],"text":"x = +(x, \"c\")"},{"id":10,"text":"x"},{"id":11,"subNodes":[12,13],"text":"+(x, \"c\")"},{"id":12,"text":"x"},{"id":13,"text":"\"c\""},{"id":14,"subNodes":[15,16],"text":"x = +(y, \"c\")"},{"id":15,"text":"x"},{"id":16,"subNodes":[17,18],"text":"+(y, \"c\")"},{"id":17,"text":"y"},{"id":18,"text":"\"c\""},{"id":19,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"TrueEdge"},{"sourceId":6,"destId":14,"kind":"FalseEdge"},{"sourceId":9,"destId":19,"kind":"SequentialEdge"},{"sourceId":14,"destId":19,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["x strcmp y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":9,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y"]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":11,"description":{"expressions":["x strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":13,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y","y strcat \"c\""]}}}},{"nodeId":15,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":16,"description":{"expressions":["y strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":18,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":19,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y"]}}}}]} \ No newline at end of file +{"name":"untyped strings::paper2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"\""},{"id":1,"text":"x"},{"id":2,"text":"\"\""},{"id":3,"subNodes":[4,5],"text":"y = \"\""},{"id":4,"text":"y"},{"id":5,"text":"\"\""},{"id":6,"subNodes":[7,8],"text":"equals(x, y)"},{"id":7,"text":"x"},{"id":8,"text":"y"},{"id":9,"subNodes":[10,11],"text":"x = +(x, \"c\")"},{"id":10,"text":"x"},{"id":11,"subNodes":[12,13],"text":"+(x, \"c\")"},{"id":12,"text":"x"},{"id":13,"text":"\"c\""},{"id":14,"subNodes":[15,16],"text":"x = +(y, \"c\")"},{"id":15,"text":"x"},{"id":16,"subNodes":[17,18],"text":"+(y, \"c\")"},{"id":17,"text":"y"},{"id":18,"text":"\"c\""},{"id":19,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"TrueEdge"},{"sourceId":6,"destId":14,"kind":"FalseEdge"},{"sourceId":9,"destId":19,"kind":"SequentialEdge"},{"sourceId":14,"destId":19,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["x strcmp y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":9,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":11,"description":{"expressions":["x strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":13,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y","y strcat \"c\""]}}}},{"nodeId":15,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":16,"description":{"expressions":["y strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":18,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":19,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.scopetest(strings__this,_untyped_x).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.scopetest(strings__this,_untyped_x).json new file mode 100644 index 000000000..b869c5d71 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.scopetest(strings__this,_untyped_x).json @@ -0,0 +1 @@ +{"name":"untyped strings::scopetest(strings* this, untyped x)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"s = \"a\""},{"id":1,"text":"s"},{"id":2,"text":"\"a\""},{"id":3,"subNodes":[4,5],"text":"y = \"z\""},{"id":4,"text":"y"},{"id":5,"text":"\"z\""},{"id":6,"subNodes":[7,8],"text":">(x, 0)"},{"id":7,"text":"x"},{"id":8,"text":"0"},{"id":9,"subNodes":[10,11],"text":"k = \"x\""},{"id":10,"text":"k"},{"id":11,"text":"\"x\""},{"id":12,"subNodes":[13,14],"text":"y = k"},{"id":13,"text":"y"},{"id":14,"text":"k"},{"id":15,"subNodes":[16,17],"text":"k = \"x\""},{"id":16,"text":"k"},{"id":17,"text":"\"x\""},{"id":18,"subNodes":[19,20],"text":"y = k"},{"id":19,"text":"y"},{"id":20,"text":"k"},{"id":21,"subNodes":[22,23],"text":"s = +(s, \"c\")"},{"id":22,"text":"s"},{"id":23,"subNodes":[24,25],"text":"+(s, \"c\")"},{"id":24,"text":"s"},{"id":25,"text":"\"c\""},{"id":26,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"TrueEdge"},{"sourceId":6,"destId":15,"kind":"FalseEdge"},{"sourceId":9,"destId":12,"kind":"SequentialEdge"},{"sourceId":12,"destId":21,"kind":"SequentialEdge"},{"sourceId":15,"destId":18,"kind":"SequentialEdge"},{"sourceId":18,"destId":21,"kind":"SequentialEdge"},{"sourceId":21,"destId":26,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"s":["\"a\""]}}}},{"nodeId":1,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":"#TOP#"},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"s":["\"a\""]}}}},{"nodeId":5,"description":{"expressions":["\"z\""],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#"},"value":{"s":["\"a\""]}}}},{"nodeId":6,"description":{"expressions":["x > 0"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":8,"description":{"expressions":["0"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":9,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"k":["\"x\""],"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":10,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":11,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":12,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"k":["string"],"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"k":["\"x\""],"s":["\"a\""],"y":["\"x\"","k"]}}}},{"nodeId":13,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"k":["string"],"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"k":["\"x\""],"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":14,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"k":["\"x\""],"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":15,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"k":["\"x\""],"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":16,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":17,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":18,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"k":["string"],"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"k":["\"x\""],"s":["\"a\""],"y":["\"x\"","k"]}}}},{"nodeId":19,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"k":["string"],"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"k":["\"x\""],"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":20,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"k":["\"x\""],"s":["\"a\""],"y":["\"z\""]}}}},{"nodeId":21,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\"","\"c\""],"y":["\"x\""]}}}},{"nodeId":22,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"x\""]}}}},{"nodeId":23,"description":{"expressions":["s strcat \"c\""],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"x\""]}}}},{"nodeId":24,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"x\""]}}}},{"nodeId":25,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\""],"y":["\"x\""]}}}},{"nodeId":26,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"s":["string"],"this":["strings*"],"x":"#TOP#","y":["string"]},"value":{"s":["\"a\"","\"c\""],"y":["\"x\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index 7d1c35821..f3669e4ab 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -266,6 +266,13 @@ public boolean knowsIdentifier( if (function.containsKey(id)) return true; + + for (Map.Entry entry : function.entrySet()) { + for (SymbolicExpression expr : entry.getValue().elements) { + if (appears(id, expr)) + return true; + } + } return false; } @@ -282,6 +289,12 @@ public SubstringDomain forgetIdentifier( // null newFunction.remove(id); + + newFunction.replaceAll((key, value) -> + new ExpressionInverseSet(value.elements.stream() + .filter(v -> !appears(id, v)) + .collect(Collectors.toSet()) + )); return mk(lattice, newFunction); } @@ -296,10 +309,30 @@ public SubstringDomain forgetIdentifiersIf( Map newFunction = mkNewFunction(function, false); // function // != // null - - Set keys = newFunction.keySet().stream().filter(test::test).collect(Collectors.toSet()); - - keys.forEach(newFunction::remove); + + Set ids = new HashSet<>(); + for (Map.Entry entry : newFunction.entrySet()) { + ids.add(entry.getKey()); + for(SymbolicExpression s : entry.getValue().elements()) { + if (s instanceof Identifier) { + Identifier id = (Identifier) s; + ids.add(id); + } + } + } + + + for (Identifier id : ids) { + if (test.test(id)) { + newFunction.remove(id); + + newFunction.replaceAll((key, value) -> + new ExpressionInverseSet(value.elements.stream() + .filter(v -> !appears(id, v)) + .collect(Collectors.toSet()) + )); + } + } return mk(lattice, newFunction); } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 012e09330..0e19936f4 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -816,6 +816,40 @@ public void testForgetIdentifier() throws SemanticException { assertFalse(domain.forgetIdentifier(x).knowsIdentifier(x)); } + + @Test + public void testForgetIdentifier2() throws SemanticException { + SubstringDomain s = domainA.assign(y, XConcatA, null, null); + s = s.forgetIdentifier(x); + assertEquals(s.getState(x), new ExpressionInverseSet().top()); + assertFalse(s.getState(y).contains(x)); + assertFalse(s.getState(y).contains(XConcatA)); + assertFalse(s.knowsIdentifier(x)); + } + + @Test + public void testForgetIdentifier3() throws SemanticException { + SubstringDomain s = domainD.assign(y, XConcatA, null, null); + s = s.forgetIdentifier(x); + assertEquals(s.getState(x), new ExpressionInverseSet().top()); + assertFalse(s.getState(y).contains(x)); + assertFalse(s.getState(y).contains(XConcatA)); + assertFalse(s.knowsIdentifier(x)); + } + + @Test + public void testForgetIdentifiersIf() throws SemanticException { + SubstringDomain s = domainF.forgetIdentifiersIf((id) -> id.getName().equals("w") || id.getName().equals("y")); + assertEquals(s.getState(w), new ExpressionInverseSet().top()); + assertFalse(s.getState(x).contains(y)); + } + + @Test + public void testKnowsIdentifier() throws SemanticException { + assertTrue(domainA.knowsIdentifier(x)); + assertTrue(domainA.knowsIdentifier(y)); + assertFalse(domainA.knowsIdentifier(z)); + } @Test public void testGlb1() throws SemanticException { diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index ede65f1aa..1ca076f63 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -127,6 +127,8 @@ public void testSubstringDomain() { } + + @Test public void testSubstringDomainWithConstants() { CronConfiguration conf = new CronConfiguration(); From b10b71d09e08993c356917c2c80f853b1b336fd9 Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Thu, 20 Jun 2024 13:34:57 +0200 Subject: [PATCH 20/34] Apply spotless --- .../string/StringConstantPropagation.java | 3 +- .../lisa/analysis/string/SubstringDomain.java | 81 ++++++------------- .../analysis/string/SubstringDomainTest.java | 11 +-- .../unive/lisa/cron/StringAnalysesTest.java | 8 +- 4 files changed, 33 insertions(+), 70 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index a6601fa6f..0faa6d80a 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -48,7 +48,6 @@ private StringConstantPropagation( /* * Builds the abstract value for the given constant. - * * @param value the constant */ public StringConstantPropagation( @@ -125,7 +124,7 @@ public StringConstantPropagation evalBinaryExpression( if (operator instanceof StringConcat) return left.isTop() || right.isTop() ? top() : new StringConstantPropagation(left.value + right.value); - + return top(); } diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index f3669e4ab..775e8135c 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -36,7 +36,7 @@ public class SubstringDomain extends FunctionalLattice implements ValueDomain { - + private static final SubstringDomain TOP = new SubstringDomain(new ExpressionInverseSet().top()); private static final SubstringDomain BOTTOM = new SubstringDomain(new ExpressionInverseSet().bottom()); @@ -266,7 +266,7 @@ public boolean knowsIdentifier( if (function.containsKey(id)) return true; - + for (Map.Entry entry : function.entrySet()) { for (SymbolicExpression expr : entry.getValue().elements) { if (appears(id, expr)) @@ -289,12 +289,12 @@ public SubstringDomain forgetIdentifier( // null newFunction.remove(id); - - newFunction.replaceAll((key, value) -> - new ExpressionInverseSet(value.elements.stream() - .filter(v -> !appears(id, v)) - .collect(Collectors.toSet()) - )); + + newFunction.replaceAll(( + key, + value) -> new ExpressionInverseSet(value.elements.stream() + .filter(v -> !appears(id, v)) + .collect(Collectors.toSet()))); return mk(lattice, newFunction); } @@ -309,28 +309,27 @@ public SubstringDomain forgetIdentifiersIf( Map newFunction = mkNewFunction(function, false); // function // != // null - + Set ids = new HashSet<>(); for (Map.Entry entry : newFunction.entrySet()) { ids.add(entry.getKey()); - for(SymbolicExpression s : entry.getValue().elements()) { + for (SymbolicExpression s : entry.getValue().elements()) { if (s instanceof Identifier) { Identifier id = (Identifier) s; ids.add(id); } } } - for (Identifier id : ids) { if (test.test(id)) { newFunction.remove(id); - - newFunction.replaceAll((key, value) -> - new ExpressionInverseSet(value.elements.stream() - .filter(v -> !appears(id, v)) - .collect(Collectors.toSet()) - )); + + newFunction.replaceAll(( + key, + value) -> new ExpressionInverseSet(value.elements.stream() + .filter(v -> !appears(id, v)) + .collect(Collectors.toSet()))); } } @@ -415,9 +414,7 @@ public SubstringDomain popScope( * Extract the ordered expressions of a concatenation. If the expression is * not a concatenation returns an empty list. Example: {@code x + y + "ab"} * returns {@code x, y, "ab"} as List - * * @param expression to extract - * * @return List containing the sub-expressions */ private static List extr( @@ -444,10 +441,8 @@ private static List extr( /* * Returns all the possible substring of a given expression. - * * @param expression * @param strType - * * @return */ private static Set extrPlus( @@ -540,13 +535,10 @@ private static Set extrPlus( } /* - * Returns a list with no more than one consecutive constant where if - * {@code extracted} has consecutive constants, the returned value merges - * them - * + * Returns a list with no more than one consecutive constant where if {@code + * extracted} has consecutive constants, the returned value merges them * @param extracted List to analyze * @param strType - * * @return The list without consecutive constants. */ private static List mergeStringLiterals( @@ -587,9 +579,7 @@ private static List mergeStringLiterals( /* * Returns the set containing the substrings of a Constant - * * @param c Constant to analyze - * * @return The set containing the substrings of a Constant */ private static Set getSubstrings( @@ -614,9 +604,7 @@ private static Set getSubstrings( /* * Returns the set containing the prefixes of a Constant - * * @param c Constant to analyze - * * @return The set containing the prefixes of a Constant */ private static Set getPrefix( @@ -636,9 +624,7 @@ private static Set getPrefix( /* * Returns the set containing the suffixes of a Constant - * * @param c Constant to analyze - * * @return The set containing the suffixes of a Constant */ private static Set getSuffix( @@ -661,11 +647,9 @@ private static Set getSuffix( /* * Creates am expression given a list. The returned expression is the * ordered concatenation of the expression in the list. - * * @param expressions - * * @return The expression representing concatenation of the expressions in - * the list. + * the list. */ private static SymbolicExpression composeExpression( List expressions) { @@ -679,12 +663,9 @@ private static SymbolicExpression composeExpression( /* * Adds a set of expressions to the domain. - * * @param symbolicExpressions * @param id - * * @return A new domain with the added expressions - * * @throws SemanticException */ protected SubstringDomain add( @@ -717,13 +698,10 @@ protected SubstringDomain add( /* * First step of assignment, removing obsolete relations. - * * @param extracted Expression assigned - * @param id Expression getting assigned - * + * @param id Expression getting assigned * @return Copy of the domain, with the holding relations after the - * assignment. - * + * assignment. * @throws SemanticException */ private SubstringDomain remove( @@ -755,13 +733,10 @@ private SubstringDomain remove( /* * Performs the inter-assignment phase - * - * @param assignedId Variable getting assigned + * @param assignedId Variable getting assigned * @param assignedExpression Expression assigned - * * @return Copy of the domain with new relations following the - * inter-assignment phase - * + * inter-assignment phase * @throws SemanticException */ private SubstringDomain interasg( @@ -795,9 +770,7 @@ private SubstringDomain interasg( /* * Performs the closure over an identifier. The method adds to {@code id} * the expressions found in the variables mapped to {@code id} - * * @return A copy of the domain with the added relations - * * @throws SemanticException */ private SubstringDomain closure( @@ -828,9 +801,7 @@ private SubstringDomain closure( /* * Performs the closure over the domain. - * * @return A copy of the domain with the added relations - * * @throws SemanticException */ protected SubstringDomain closure() throws SemanticException { @@ -861,9 +832,7 @@ protected SubstringDomain closure() throws SemanticException { /* * Removes values mapped to empty set (top) - * * @return A copy of the domain without variables mapped to empty set - * * @throws SemanticException */ private SubstringDomain clear() throws SemanticException { @@ -882,10 +851,8 @@ private SubstringDomain clear() throws SemanticException { /* * Checks if a variable appears in an expression - * - * @param id Variable to check + * @param id Variable to check * @param expr expression to analyze - * * @return {@code true} if {@code id} appears, {@code false} otherwise */ private static boolean appears( diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 0e19936f4..af6583b44 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -816,7 +816,7 @@ public void testForgetIdentifier() throws SemanticException { assertFalse(domain.forgetIdentifier(x).knowsIdentifier(x)); } - + @Test public void testForgetIdentifier2() throws SemanticException { SubstringDomain s = domainA.assign(y, XConcatA, null, null); @@ -826,7 +826,7 @@ public void testForgetIdentifier2() throws SemanticException { assertFalse(s.getState(y).contains(XConcatA)); assertFalse(s.knowsIdentifier(x)); } - + @Test public void testForgetIdentifier3() throws SemanticException { SubstringDomain s = domainD.assign(y, XConcatA, null, null); @@ -836,14 +836,15 @@ public void testForgetIdentifier3() throws SemanticException { assertFalse(s.getState(y).contains(XConcatA)); assertFalse(s.knowsIdentifier(x)); } - + @Test public void testForgetIdentifiersIf() throws SemanticException { - SubstringDomain s = domainF.forgetIdentifiersIf((id) -> id.getName().equals("w") || id.getName().equals("y")); + SubstringDomain s = domainF.forgetIdentifiersIf(( + id) -> id.getName().equals("w") || id.getName().equals("y")); assertEquals(s.getState(w), new ExpressionInverseSet().top()); assertFalse(s.getState(x).contains(y)); } - + @Test public void testKnowsIdentifier() throws SemanticException { assertTrue(domainA.knowsIdentifier(x)); diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 1ca076f63..37ad7e412 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -12,8 +12,6 @@ import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; -import it.unive.lisa.conf.LiSAConfiguration.GraphType; - import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { @@ -122,13 +120,11 @@ public void testSubstringDomain() { conf.testDir = "string"; conf.testSubDir = "subs-domain"; conf.programFile = "strings-subs.imp"; - //conf.analysisGraphs = GraphType.DOT; + // conf.analysisGraphs = GraphType.DOT; perform(conf); } - - @Test public void testSubstringDomainWithConstants() { CronConfiguration conf = new CronConfiguration(); @@ -140,7 +136,7 @@ public void testSubstringDomainWithConstants() { conf.testDir = "string"; conf.testSubDir = "subs-domain-constants"; conf.programFile = "strings-subs-constants.imp"; - //conf.analysisGraphs = GraphType.DOT; + // conf.analysisGraphs = GraphType.DOT; perform(conf); } } From 12e7b526d8d9a661ed85cfa7879746665543748c Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Thu, 20 Jun 2024 13:46:56 +0200 Subject: [PATCH 21/34] Javadoc --- .../string/StringConstantPropagation.java | 12 ++++++++ .../lisa/analysis/string/SubstringDomain.java | 28 +++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index 0faa6d80a..99de81d32 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -1,5 +1,6 @@ package it.unive.lisa.analysis.string; +import it.unive.lisa.analysis.BaseLattice; import it.unive.lisa.analysis.Lattice; import it.unive.lisa.analysis.SemanticException; import it.unive.lisa.analysis.SemanticOracle; @@ -21,6 +22,17 @@ import it.unive.lisa.util.representation.StringRepresentation; import it.unive.lisa.util.representation.StructuredRepresentation; +/** + * The string constant propagation abstract domain, tracking if a certain string + * value has constant value or not. Top and bottom cases for least upper bounds, + * widening and less or equals operations are handled by {@link BaseLattice} in + * {@link BaseLattice#lub}, {@link BaseLattice#widening} and + * {@link BaseLattice#lessOrEqual}, respectively. + * + * @author Michele + * Martelli + * @author Vincenzo Arceri + */ public class StringConstantPropagation implements BaseNonRelationalValueDomain { private static final StringConstantPropagation TOP = new StringConstantPropagation(true, false); diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index 775e8135c..ec733647a 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -33,6 +33,19 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +/** + * The substring relational abstract domain, tracking relation between string + * expressions. The domain is implemented as a {@link FunctionalLattice}, + * mapping identifiers to string expressions, tracking which string expressions + * are definitely substring of an identifier. This domain follows the one + * defined + * in + * this paper. + * + * @author Michele + * Martelli + * @author Vincenzo Arceri + */ public class SubstringDomain extends FunctionalLattice implements ValueDomain { @@ -40,21 +53,24 @@ public class SubstringDomain extends FunctionalLattice function) { super(lattice, function); } - public SubstringDomain( + private SubstringDomain( ExpressionInverseSet lattice) { super(lattice); } - public SubstringDomain() { - this(new ExpressionInverseSet()); - } - @Override public SubstringDomain lubAux( SubstringDomain other) From 53c34c7d119f3eee217df0bd3cffe587b397c717 Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Fri, 21 Jun 2024 09:42:38 +0200 Subject: [PATCH 22/34] Javadoc --- .../java/it/unive/lisa/analysis/string/SubstringDomain.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index ec733647a..3b37dca15 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -60,6 +60,12 @@ public SubstringDomain() { this(new ExpressionInverseSet()); } + /** + * Builds the abstract value by cloning the given function. + * + * @param lattice the underlying lattice + * @param function the function to clone + */ protected SubstringDomain( ExpressionInverseSet lattice, Map function) { From 9ca80c784dcb80c7ae7a2805c034e7adeeebebb1 Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Fri, 21 Jun 2024 13:22:07 +0200 Subject: [PATCH 23/34] Javadoc --- .../string/StringConstantPropagation.java | 5 ++- .../lisa/analysis/string/SubstringDomain.java | 45 ++++++++++++------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index 99de81d32..f4f3df253 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -42,7 +42,7 @@ public class StringConstantPropagation implements BaseNonRelationalValueDomain symbolicExpressions, + Set exprs, Identifier id) throws SemanticException { @@ -700,7 +704,7 @@ protected SubstringDomain add( // Don't add the expressions that contain the key variable (ex: x -> x, // x -> x + y will not be added) Set expressionsToRemove = new HashSet<>(); - for (SymbolicExpression se : symbolicExpressions) { + for (SymbolicExpression se : exprs) { if (!appears(id, se)) expressionsToRemove.add(se); } @@ -724,7 +728,7 @@ protected SubstringDomain add( * @param id Expression getting assigned * @return Copy of the domain, with the holding relations after the * assignment. - * @throws SemanticException + * @throws SemanticException if an error occurs during the computation */ private SubstringDomain remove( Set extracted, @@ -753,13 +757,16 @@ private SubstringDomain remove( return mk(lattice, newFunction); } - /* + /** * Performs the inter-assignment phase - * @param assignedId Variable getting assigned + * + * @param assignedId Variable getting assigned * @param assignedExpression Expression assigned + * * @return Copy of the domain with new relations following the - * inter-assignment phase - * @throws SemanticException + * inter-assignment phase + * + * @throws SemanticException if an error occurs during the computation */ private SubstringDomain interasg( Identifier assignedId, @@ -789,11 +796,13 @@ private SubstringDomain interasg( return mk(lattice, newFunction); } - /* + /** * Performs the closure over an identifier. The method adds to {@code id} * the expressions found in the variables mapped to {@code id} + * * @return A copy of the domain with the added relations - * @throws SemanticException + * + * @throws SemanticException if an error occurs during the computation */ private SubstringDomain closure( Identifier id) @@ -821,10 +830,12 @@ private SubstringDomain closure( return result; } - /* + /** * Performs the closure over the domain. + * * @return A copy of the domain with the added relations - * @throws SemanticException + * + * @throws SemanticException if an error occurs during the computation */ protected SubstringDomain closure() throws SemanticException { if (isTop() || isBottom()) From 654f1fb519c7846e0128c79d33052c186983a85e Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Fri, 21 Jun 2024 14:23:38 +0200 Subject: [PATCH 24/34] Javadoc --- .../lisa/analysis/string/SubstringDomain.java | 2 +- .../string/SubstringDomainWithConstants.java | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index f004aaabc..988cf93bf 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -685,7 +685,7 @@ private static SymbolicExpression composeExpression( /** * Adds a set of expressions ({@code exprs}) for {@code id} to the this - * abstract value . + * abstract value. * * @param exprs the set of symbolic expressions * @param id the identifier diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java index 0f2dccd58..d5ec5613e 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java @@ -12,15 +12,37 @@ import java.util.Map.Entry; import java.util.Set; +/** + * The substring relational abstract domain (see {@link SubstringDomain}) + * enriched with string constant propagation. This domain is defined as the + * Cartesian product between {@link SubstringDomain} and + * {@link StringConstantPropagation}. This domain follows the one defined + * in + * this paper. + * + * @author Michele + * Martelli + * @author Vincenzo Arceri + */ public class SubstringDomainWithConstants extends ValueCartesianProduct, SubstringDomain> { + + /** + * Builds the abstract value starting from components. + * + * @param left the string constant propagation environment + * @param right the substring domain abstract value + */ public SubstringDomainWithConstants( ValueEnvironment left, SubstringDomain right) { super(left, right); } + /** + * Builds the top abstract value. + */ public SubstringDomainWithConstants() { this(new ValueEnvironment(new StringConstantPropagation()), new SubstringDomain()); } From 710ba7de7864fb10ff2391ab3d4037373a0a4f38 Mon Sep 17 00:00:00 2001 From: Michele Date: Sat, 22 Jun 2024 13:17:20 +0200 Subject: [PATCH 25/34] Fixed StringReplace and Substring expressions in extraction --- .../imp-testcases/string/strings-subs.imp | 26 +- .../string/subs-domain-constants/report.json | 6 +- .../string/subs-domain/report.json | 18 +- ...untyped_strings.paper2(strings__this).json | 2 +- ...ntyped_strings.replace(strings__this).json | 1 + ...typed_strings.replace2(strings__this).json | 1 + ...yped_strings.substring(strings__this).json | 1 + ...ped_strings.substring2(strings__this).json | 1 + .../string/StringConstantPropagation.java | 4 +- .../lisa/analysis/string/SubstringDomain.java | 359 ++++++++++-------- .../string/SubstringDomainWithConstants.java | 8 +- .../analysis/string/SubstringDomainTest.java | 73 ++++ .../unive/lisa/cron/StringAnalysesTest.java | 2 + 13 files changed, 331 insertions(+), 171 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.replace(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.replace2(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.substring(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.substring2(strings__this).json diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp index e87b61f13..3bda5c960 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp @@ -104,7 +104,8 @@ class strings { def z = "b"; def w = y + z; } - + + paper2(){ def x = ""; def y = ""; @@ -114,7 +115,6 @@ class strings { x = y + "c"; } - paper3(x){ def v = ""; if (x % 2) @@ -155,5 +155,27 @@ class strings { s = s + "c"; } + replace(){ + def y = "c"; + def x = strrep("ab", "ab", "a") + "b" + y; + def z = "b" + y; + } + + replace2(){ + def y = "xyz"; + def x = "ab" + strrep(y, "x", "yz") + "c"; + } + + substring(){ + def y = "c"; + def x = strsub("ab", 0, 1) + "b" + y; + def z = "b" + y; + } + + substring2(){ + def y = "xyz"; + def x = "ab" + strsub(y, 0, 1) + "c"; + } + } \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json index 75979178f..b3881975f 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json @@ -3,14 +3,14 @@ "files" : [ "report.json", "untyped_strings.constants(strings__this).json", "untyped_strings.replace(strings__this,_untyped_s).json" ], "info" : { "cfgs" : "2", - "duration" : "11ms", - "end" : "2024-04-25T12:26:36.264+02:00", + "duration" : "9ms", + "end" : "2024-06-22T12:58:22.543+02:00", "expressions" : "29", "files" : "2", "globals" : "0", "members" : "2", "programs" : "1", - "start" : "2024-04-25T12:26:36.253+02:00", + "start" : "2024-06-22T12:58:22.534+02:00", "statements" : "12", "units" : "1", "version" : "0.1b9", diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json index 951f3609f..b1186d127 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/report.json @@ -1,17 +1,17 @@ { "warnings" : [ ], - "files" : [ "report.json", "untyped_strings.assume(strings__this).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.integers(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json", "untyped_strings.paper1(strings__this).json", "untyped_strings.paper2(strings__this).json", "untyped_strings.paper3(strings__this,_untyped_x).json", "untyped_strings.scopetest(strings__this,_untyped_x).json", "untyped_strings.stringconcat(strings__this).json", "untyped_strings.type(strings__this,_untyped_x).json" ], + "files" : [ "report.json", "untyped_strings.assume(strings__this).json", "untyped_strings.branching(strings__this,_untyped_x).json", "untyped_strings.closure(strings__this).json", "untyped_strings.closure2(strings__this).json", "untyped_strings.closure3(strings__this).json", "untyped_strings.constants(strings__this).json", "untyped_strings.iftest1(strings__this).json", "untyped_strings.iftest2(strings__this).json", "untyped_strings.iftestand(strings__this).json", "untyped_strings.iftestor(strings__this).json", "untyped_strings.integers(strings__this).json", "untyped_strings.interassign(strings__this).json", "untyped_strings.loops(strings__this,_untyped_x).json", "untyped_strings.paper1(strings__this).json", "untyped_strings.paper2(strings__this).json", "untyped_strings.paper3(strings__this,_untyped_x).json", "untyped_strings.replace(strings__this).json", "untyped_strings.replace2(strings__this).json", "untyped_strings.scopetest(strings__this,_untyped_x).json", "untyped_strings.stringconcat(strings__this).json", "untyped_strings.substring(strings__this).json", "untyped_strings.substring2(strings__this).json", "untyped_strings.type(strings__this,_untyped_x).json" ], "info" : { - "cfgs" : "19", - "duration" : "92ms", - "end" : "2024-06-14T23:04:08.375+02:00", - "expressions" : "206", - "files" : "19", + "cfgs" : "23", + "duration" : "107ms", + "end" : "2024-06-22T12:54:35.326+02:00", + "expressions" : "258", + "files" : "23", "globals" : "0", - "members" : "19", + "members" : "23", "programs" : "1", - "start" : "2024-06-14T23:04:08.283+02:00", - "statements" : "100", + "start" : "2024-06-22T12:54:35.219+02:00", + "statements" : "114", "units" : "1", "version" : "0.1b9", "warnings" : "0" diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json index ebf768c1a..103be06d2 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.paper2(strings__this).json @@ -1 +1 @@ -{"name":"untyped strings::paper2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"\""},{"id":1,"text":"x"},{"id":2,"text":"\"\""},{"id":3,"subNodes":[4,5],"text":"y = \"\""},{"id":4,"text":"y"},{"id":5,"text":"\"\""},{"id":6,"subNodes":[7,8],"text":"equals(x, y)"},{"id":7,"text":"x"},{"id":8,"text":"y"},{"id":9,"subNodes":[10,11],"text":"x = +(x, \"c\")"},{"id":10,"text":"x"},{"id":11,"subNodes":[12,13],"text":"+(x, \"c\")"},{"id":12,"text":"x"},{"id":13,"text":"\"c\""},{"id":14,"subNodes":[15,16],"text":"x = +(y, \"c\")"},{"id":15,"text":"x"},{"id":16,"subNodes":[17,18],"text":"+(y, \"c\")"},{"id":17,"text":"y"},{"id":18,"text":"\"c\""},{"id":19,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"TrueEdge"},{"sourceId":6,"destId":14,"kind":"FalseEdge"},{"sourceId":9,"destId":19,"kind":"SequentialEdge"},{"sourceId":14,"destId":19,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["x strcmp y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":9,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\""]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":11,"description":{"expressions":["x strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":13,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y","y strcat \"c\""]}}}},{"nodeId":15,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":16,"description":{"expressions":["y strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":18,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":19,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\""]}}}}]} \ No newline at end of file +{"name":"untyped strings::paper2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"\""},{"id":1,"text":"x"},{"id":2,"text":"\"\""},{"id":3,"subNodes":[4,5],"text":"y = \"\""},{"id":4,"text":"y"},{"id":5,"text":"\"\""},{"id":6,"subNodes":[7,8],"text":"equals(x, y)"},{"id":7,"text":"x"},{"id":8,"text":"y"},{"id":9,"subNodes":[10,11],"text":"x = +(x, \"c\")"},{"id":10,"text":"x"},{"id":11,"subNodes":[12,13],"text":"+(x, \"c\")"},{"id":12,"text":"x"},{"id":13,"text":"\"c\""},{"id":14,"subNodes":[15,16],"text":"x = +(y, \"c\")"},{"id":15,"text":"x"},{"id":16,"subNodes":[17,18],"text":"+(y, \"c\")"},{"id":17,"text":"y"},{"id":18,"text":"\"c\""},{"id":19,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":9,"kind":"TrueEdge"},{"sourceId":6,"destId":14,"kind":"FalseEdge"},{"sourceId":9,"destId":19,"kind":"SequentialEdge"},{"sourceId":14,"destId":19,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":5,"description":{"expressions":["\"\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"]},"value":"#TOP#"}}},{"nodeId":6,"description":{"expressions":["x strcmp y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":9,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y"]}}}},{"nodeId":10,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":11,"description":{"expressions":["x strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":12,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":13,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["y"],"y":["x"]}}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y","y strcat \"c\""]}}}},{"nodeId":15,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":16,"description":{"expressions":["y strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":18,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":"#TOP#"}}},{"nodeId":19,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"c\"","y"]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.replace(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.replace(strings__this).json new file mode 100644 index 000000000..f730c75a9 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.replace(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::replace(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"y = \"c\""},{"id":1,"text":"y"},{"id":2,"text":"\"c\""},{"id":3,"subNodes":[4,5],"text":"x = +(+(replace(\"ab\", \"ab\", \"a\"), \"b\"), y)"},{"id":4,"text":"x"},{"id":5,"subNodes":[6,12],"text":"+(+(replace(\"ab\", \"ab\", \"a\"), \"b\"), y)"},{"id":6,"subNodes":[7,11],"text":"+(replace(\"ab\", \"ab\", \"a\"), \"b\")"},{"id":7,"subNodes":[8,9,10],"text":"replace(\"ab\", \"ab\", \"a\")"},{"id":8,"text":"\"ab\""},{"id":9,"text":"\"ab\""},{"id":10,"text":"\"a\""},{"id":11,"text":"\"b\""},{"id":12,"text":"y"},{"id":13,"subNodes":[14,15],"text":"z = +(\"b\", y)"},{"id":14,"text":"z"},{"id":15,"subNodes":[16,17],"text":"+(\"b\", y)"},{"id":16,"text":"\"b\""},{"id":17,"text":"y"},{"id":18,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":13,"kind":"SequentialEdge"},{"sourceId":13,"destId":18,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":1,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":5,"description":{"expressions":["\"ab\" strreplace(\"ab\", \"a\") strcat \"b\" strcat y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":6,"description":{"expressions":["\"ab\" strreplace(\"ab\", \"a\") strcat \"b\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":7,"description":{"expressions":["\"ab\" strreplace(\"ab\", \"a\")"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":8,"description":{"expressions":["\"ab\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":9,"description":{"expressions":["\"ab\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":10,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":11,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":12,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":13,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y","z"],"y":["\"c\""],"z":["\"b\"","\"b\" strcat y","\"c\"","y"]}}}},{"nodeId":14,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":15,"description":{"expressions":["\"b\" strcat y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":16,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":18,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y","z"],"y":["\"c\""],"z":["\"b\"","\"b\" strcat y","\"c\"","y"]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.replace2(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.replace2(strings__this).json new file mode 100644 index 000000000..8142ceec7 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.replace2(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::replace2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"y = \"xyz\""},{"id":1,"text":"y"},{"id":2,"text":"\"xyz\""},{"id":3,"subNodes":[4,5],"text":"x = +(+(\"ab\", replace(y, \"x\", \"yz\")), \"c\")"},{"id":4,"text":"x"},{"id":5,"subNodes":[6,12],"text":"+(+(\"ab\", replace(y, \"x\", \"yz\")), \"c\")"},{"id":6,"subNodes":[7,8],"text":"+(\"ab\", replace(y, \"x\", \"yz\"))"},{"id":7,"text":"\"ab\""},{"id":8,"subNodes":[9,10,11],"text":"replace(y, \"x\", \"yz\")"},{"id":9,"text":"y"},{"id":10,"text":"\"x\""},{"id":11,"text":"\"yz\""},{"id":12,"text":"\"c\""},{"id":13,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":13,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":1,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"xyz\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","\"c\""],"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":5,"description":{"expressions":["\"ab\" strcat y strreplace(\"x\", \"yz\") strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":6,"description":{"expressions":["\"ab\" strcat y strreplace(\"x\", \"yz\")"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":7,"description":{"expressions":["\"ab\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":8,"description":{"expressions":["y strreplace(\"x\", \"yz\")"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":10,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":11,"description":{"expressions":["\"yz\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":12,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":13,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","\"c\""],"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.substring(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.substring(strings__this).json new file mode 100644 index 000000000..756404695 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.substring(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::substring(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"y = \"c\""},{"id":1,"text":"y"},{"id":2,"text":"\"c\""},{"id":3,"subNodes":[4,5],"text":"x = +(+(substring(\"ab\", 0, 1), \"b\"), y)"},{"id":4,"text":"x"},{"id":5,"subNodes":[6,12],"text":"+(+(substring(\"ab\", 0, 1), \"b\"), y)"},{"id":6,"subNodes":[7,11],"text":"+(substring(\"ab\", 0, 1), \"b\")"},{"id":7,"subNodes":[8,9,10],"text":"substring(\"ab\", 0, 1)"},{"id":8,"text":"\"ab\""},{"id":9,"text":"0"},{"id":10,"text":"1"},{"id":11,"text":"\"b\""},{"id":12,"text":"y"},{"id":13,"subNodes":[14,15],"text":"z = +(\"b\", y)"},{"id":14,"text":"z"},{"id":15,"subNodes":[16,17],"text":"+(\"b\", y)"},{"id":16,"text":"\"b\""},{"id":17,"text":"y"},{"id":18,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":13,"kind":"SequentialEdge"},{"sourceId":13,"destId":18,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":1,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":5,"description":{"expressions":["\"ab\" substr(0, 1) strcat \"b\" strcat y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":6,"description":{"expressions":["\"ab\" substr(0, 1) strcat \"b\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":7,"description":{"expressions":["\"ab\" substr(0, 1)"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":8,"description":{"expressions":["\"ab\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":9,"description":{"expressions":["0"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":10,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":11,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":12,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"c\""]}}}},{"nodeId":13,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y","z"],"y":["\"c\""],"z":["\"b\"","\"b\" strcat y","\"c\"","y"]}}}},{"nodeId":14,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":15,"description":{"expressions":["\"b\" strcat y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":16,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y"],"y":["\"c\""]}}}},{"nodeId":18,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":{"x":["\"a\"","\"ab\"","\"ab\" strcat y","\"b\"","\"b\" strcat y","\"c\"","y","z"],"y":["\"c\""],"z":["\"b\"","\"b\" strcat y","\"c\"","y"]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.substring2(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.substring2(strings__this).json new file mode 100644 index 000000000..292c60e7c --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain/untyped_strings.substring2(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::substring2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"y = \"xyz\""},{"id":1,"text":"y"},{"id":2,"text":"\"xyz\""},{"id":3,"subNodes":[4,5],"text":"x = +(+(\"ab\", substring(y, 0, 1)), \"c\")"},{"id":4,"text":"x"},{"id":5,"subNodes":[6,12],"text":"+(+(\"ab\", substring(y, 0, 1)), \"c\")"},{"id":6,"subNodes":[7,8],"text":"+(\"ab\", substring(y, 0, 1))"},{"id":7,"text":"\"ab\""},{"id":8,"subNodes":[9,10,11],"text":"substring(y, 0, 1)"},{"id":9,"text":"y"},{"id":10,"text":"0"},{"id":11,"text":"1"},{"id":12,"text":"\"c\""},{"id":13,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":13,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":1,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":2,"description":{"expressions":["\"xyz\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":"#TOP#"}}},{"nodeId":3,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","\"c\""],"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":5,"description":{"expressions":["\"ab\" strcat y substr(0, 1) strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":6,"description":{"expressions":["\"ab\" strcat y substr(0, 1)"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":7,"description":{"expressions":["\"ab\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":8,"description":{"expressions":["y substr(0, 1)"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":10,"description":{"expressions":["0"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":11,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":12,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}},{"nodeId":13,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":{"x":["\"a\"","\"ab\"","\"b\"","\"c\""],"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index f4f3df253..38da7f383 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -17,6 +17,7 @@ import it.unive.lisa.symbolic.value.operator.binary.ComparisonNe; import it.unive.lisa.symbolic.value.operator.binary.StringConcat; import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; +import it.unive.lisa.symbolic.value.operator.ternary.StringSubstring; import it.unive.lisa.symbolic.value.operator.ternary.TernaryOperator; import it.unive.lisa.symbolic.value.operator.unary.UnaryOperator; import it.unive.lisa.util.representation.StringRepresentation; @@ -29,7 +30,7 @@ * {@link BaseLattice#lub}, {@link BaseLattice#widening} and * {@link BaseLattice#lessOrEqual}, respectively. * - * @author Michele + * @author Michele * Martelli * @author Vincenzo Arceri */ @@ -159,6 +160,7 @@ public StringConstantPropagation evalTernaryExpression( return new StringConstantPropagation(replaced); } + return top(); } diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index 988cf93bf..eee3df2e5 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -13,6 +13,7 @@ import it.unive.lisa.symbolic.value.BinaryExpression; import it.unive.lisa.symbolic.value.Constant; import it.unive.lisa.symbolic.value.Identifier; +import it.unive.lisa.symbolic.value.TernaryExpression; import it.unive.lisa.symbolic.value.ValueExpression; import it.unive.lisa.symbolic.value.Variable; import it.unive.lisa.symbolic.value.operator.binary.BinaryOperator; @@ -23,6 +24,9 @@ import it.unive.lisa.symbolic.value.operator.binary.StringEndsWith; import it.unive.lisa.symbolic.value.operator.binary.StringEquals; import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; +import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; +import it.unive.lisa.symbolic.value.operator.ternary.StringSubstring; +import it.unive.lisa.type.NumericType; import it.unive.lisa.type.Type; import java.util.ArrayList; import java.util.Collections; @@ -42,7 +46,7 @@ * in * this paper. * - * @author Michele + * @author Michele * Martelli * @author Vincenzo Arceri */ @@ -144,13 +148,13 @@ public SubstringDomain assign( // expression strType = expression.getStaticType(); - Set identifiers = extrPlus(expression, strType); + Set expressions = extrPlus(expression, pp, oracle, strType); SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - result = result.remove(identifiers, id); + result = result.remove(expressions, id); - result = result.add(identifiers, id); + result = result.add(expressions, id); result = result.interasg(id, expression); @@ -164,7 +168,7 @@ public SubstringDomain smallStepSemantics( ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) - throws SemanticException { + throws SemanticException { return this; } @@ -176,8 +180,6 @@ public SubstringDomain assume( SemanticOracle oracle) throws SemanticException { - SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - /* * Assume only binary expressions */ @@ -215,21 +217,30 @@ public SubstringDomain assume( if (!(right instanceof ValueExpression)) throw new SemanticException("instanceof right"); - Set extracted = extrPlus((ValueExpression) right, strType); + Set extracted = extrPlus((ValueExpression) right, src, oracle, strType); + + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); result = result.add(extracted, (Identifier) left); result = result.closure(); + + return result.clear(); } else if (binaryOperator instanceof StringEquals) { /* * Case both operands are identifiers */ if ((left instanceof Identifier) && (right instanceof Identifier)) { - result = result.add(extrPlus((ValueExpression) left, strType), (Identifier) right); - result = result.add(extrPlus((ValueExpression) right, strType), (Identifier) left); + + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); + + result = result.add(left, (Identifier) right); + result = result.add(right, (Identifier) left); result = result.closure(); + + return result.clear(); } /* @@ -249,11 +260,15 @@ else if ((left instanceof Identifier) || (right instanceof Identifier)) { if (!(right instanceof ValueExpression)) throw new SemanticException("instanceof right != ValueExpression.class"); - Set add = extrPlus((ValueExpression) right, strType); + Set add = extrPlus((ValueExpression) right, src, oracle, strType); + + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); result = result.add(add, (Identifier) left); result = result.closure(); + + return result.clear(); } } else if (binaryOperator instanceof LogicalOr || binaryOperator instanceof LogicalAnd) { @@ -269,15 +284,15 @@ else if ((left instanceof Identifier) || (right instanceof Identifier)) { SubstringDomain rightDomain = assume(rightValueExpression, src, dest, oracle); if (binaryOperator instanceof LogicalOr) { - result = leftDomain.lub(rightDomain); + return leftDomain.lub(rightDomain).clear(); } else { - result = leftDomain.glb(rightDomain); + return leftDomain.glb(rightDomain).clear(); } } } - return result.clear(); + return this; } @Override @@ -309,14 +324,11 @@ public SubstringDomain forgetIdentifier( Map newFunction = mkNewFunction(function, false); // function // != // null - newFunction.remove(id); newFunction.replaceAll(( key, - value) -> new ExpressionInverseSet(value.elements.stream() - .filter(v -> !appears(id, v)) - .collect(Collectors.toSet()))); + value) -> removeFromSet(value, id)); return mk(lattice, newFunction); } @@ -328,12 +340,9 @@ public SubstringDomain forgetIdentifiersIf( if (function == null || function.keySet().isEmpty()) return this; - Map newFunction = mkNewFunction(function, false); // function - // != - // null - + // Get all identifiers Set ids = new HashSet<>(); - for (Map.Entry entry : newFunction.entrySet()) { + for (Map.Entry entry : function.entrySet()) { ids.add(entry.getKey()); for (SymbolicExpression s : entry.getValue().elements()) { if (s instanceof Identifier) { @@ -342,20 +351,17 @@ public SubstringDomain forgetIdentifiersIf( } } } + + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); for (Identifier id : ids) { + // Test each identifier if (test.test(id)) { - newFunction.remove(id); - - newFunction.replaceAll(( - key, - value) -> new ExpressionInverseSet(value.elements.stream() - .filter(v -> !appears(id, v)) - .collect(Collectors.toSet()))); + result = result.forgetIdentifier(id); } } - return mk(lattice, newFunction); + return result; } @Override @@ -439,24 +445,21 @@ public SubstringDomain popScope( * @param expression to extract * @return List containing the sub-expressions */ - private static List extr( + private static List extr( ValueExpression expression) { - List result = new ArrayList<>(); - if (expression instanceof BinaryExpression) { + List result = new ArrayList<>(); + if (expression instanceof BinaryExpression && ((BinaryExpression)expression).getOperator() instanceof StringConcat) { BinaryExpression binaryExpression = (BinaryExpression) expression; - BinaryOperator binaryOperator = binaryExpression.getOperator(); - if (!(binaryOperator instanceof StringConcat)) - return Collections.emptyList(); ValueExpression left = (ValueExpression) binaryExpression.getLeft(); ValueExpression right = (ValueExpression) binaryExpression.getRight(); result.addAll(extr(left)); result.addAll(extr(right)); - } else if (expression instanceof Variable || expression instanceof Constant) { + } else result.add(expression); - } + return result; } @@ -467,94 +470,155 @@ private static List extr( * @param strType * @return */ - private static Set extrPlus( + private Set extrPlus( ValueExpression expression, - Type strType) { - List extracted = extr(expression); - + ProgramPoint pp, + SemanticOracle oracle, + Type strType) throws SemanticException { + List extracted = extr(expression); + /* * If there are more than 2 consecutive constants, merge them into a * single constant */ - extracted = mergeStringLiterals(extracted, strType); + List> sub_expressions = split(extracted, pp, oracle, strType); + + for (int i = 0; i < sub_expressions.size(); i++) { + List list = sub_expressions.get(i); + sub_expressions.set(i, mergeStringLiterals(list, strType)); + } Set result = new HashSet<>(); + + // Iterate sublists splitted from StringReplace expressions + for (List list : sub_expressions) { + // Iterate over the length of the expression + for (int l = 1; l <= list.size(); l++) { + // Iterate from the start to the end according to the size of the + // expression to create + for (int i = 0; i <= (list.size() - l); i++) { + List subList = list.subList(i, i + l); + result.add(composeExpression(subList)); + + if (subList.size() == 1 && subList.get(0) instanceof Constant) { + /* + * Case the expression to ass is a single constant -> add + * its substrings + */ + Set substrings = getSubstrings((Constant) subList.get(0)); - // Iterate over the length of the expression - for (int l = 1; l <= extracted.size(); l++) { - // Iterate from the start to the end according to the size of the - // expression to create - for (int i = 0; i <= (extracted.size() - l); i++) { - List subList = extracted.subList(i, i + l); - result.add(composeExpression(subList)); + for (Constant substring : substrings) { + List newList = new ArrayList<>(); + newList.add(substring); - if (subList.size() == 1 && subList.get(0) instanceof Constant) { - /* - * Case the expression to ass is a single constant -> add - * its substrings - */ - Set substrings = getSubstrings((Constant) subList.get(0)); + result.add(composeExpression(newList)); - for (SymbolicExpression substring : substrings) { - List newList = new ArrayList<>(); - newList.add(substring); + } + } else if (subList.get(0) instanceof Constant) { + /* + * Case the first expression of the expression to add is a + * constant -> add an expression for each suffix of the + * constant + */ + Set suffixes = getSuffix((Constant) subList.get(0)); - result.add(composeExpression(newList)); + for (Constant suffix : suffixes) { + List newList = new ArrayList<>(subList); + newList.set(0, suffix); - } - } else if (subList.get(0) instanceof Constant) { - /* - * Case the first expression of the expression to add is a - * constant -> add an expression for each suffix of the - * constant - */ - Set suffixes = getSuffix((Constant) subList.get(0)); - - for (SymbolicExpression suffix : suffixes) { - List newList = new ArrayList<>(subList); - newList.set(0, suffix); - - if (subList.get(subList.size() - 1) instanceof Constant) { - - /* - * Case the last expression of the expression to add - * is a constant -> add an expression for each - * prefix of the constant - */ - Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); - - for (SymbolicExpression prefix : prefixes) { - newList.set(newList.size() - 1, prefix); + if (subList.get(subList.size() - 1) instanceof Constant) { + /* + * Case the last expression of the expression to add + * is a constant -> add an expression for each + * prefix of the constant + */ + Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); + + for (Constant prefix : prefixes) { + newList.set(newList.size() - 1, prefix); + + result.add(composeExpression(newList)); + } + } else result.add(composeExpression(newList)); - } - } else - result.add(composeExpression(newList)); - } - } else if (subList.get(subList.size() - 1) instanceof Constant) { + } + } else if (subList.get(subList.size() - 1) instanceof Constant) { - /* - * Case the last expression of the expression to add is a - * constant -> add an expression for each prefix of the - * constant - */ + /* + * Case the last expression of the expression to add is a + * constant -> add an expression for each prefix of the + * constant + */ - Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); + Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); - for (SymbolicExpression prefix : prefixes) { - List newList = new ArrayList<>(subList); - newList.set(newList.size() - 1, prefix); + for (Constant prefix : prefixes) { + List newList = new ArrayList<>(subList); + newList.set(newList.size() - 1, prefix); - result.add(composeExpression(newList)); + result.add(composeExpression(newList)); + } } - } + } } } - return new HashSet<>(result); } + + private List> split(List extracted, ProgramPoint pp, SemanticOracle oracle, Type strType) throws SemanticException{ + List> result = new ArrayList<>(); + + List temp = new ArrayList<>(); + + for(ValueExpression s : extracted) { + if (!(s instanceof Identifier || s instanceof Constant)) { + // s in not Identifier or Constant -> eval s semantics + + if (s instanceof TernaryExpression) { + TernaryExpression ternaryExpression = (TernaryExpression) s; + if (ternaryExpression.getLeft() instanceof Constant && ternaryExpression.getMiddle() instanceof Constant && ternaryExpression.getRight() instanceof Constant) { + Constant c1 = (Constant) ternaryExpression.getLeft(); + Constant c2 = (Constant) ternaryExpression.getMiddle(); + Constant c3 = (Constant) ternaryExpression.getRight(); + + if (ternaryExpression.getOperator() instanceof StringReplace) { + String s1 = c1.getValue() instanceof String ? (String) c1.getValue() : c1.getValue().toString(); + String s2 = c2.getValue() instanceof String ? (String) c2.getValue() : c2.getValue().toString(); + String s3 = c3.getValue() instanceof String ? (String) c3.getValue() : c3.getValue().toString(); + + // Special case: add the constant and do not split list + temp.add(new Constant(strType, s1.replace(s2, s3), SyntheticLocation.INSTANCE)); + continue; + } + if (ternaryExpression.getOperator() instanceof StringSubstring && c2.getValue() instanceof Integer && c3.getValue() instanceof Integer) { + String s1 = c1.getValue() instanceof String ? (String) c1.getValue() : c1.getValue().toString(); + Integer i1 = (Integer) c2.getValue(); + Integer i2 = (Integer) c3.getValue(); + + // Special case: add the constant and do not split list + temp.add(new Constant(strType, s1.substring(i1, i2), SyntheticLocation.INSTANCE)); + continue; + } + } + } + + // Split list + result.add(new ArrayList<>(temp)); + temp.clear(); + + } else { + // s instance of Identifier || s instance of Constant + temp.add(s); + } + } + + result.add(temp); + + return result; + } /* * Returns a list with no more than one consecutive constant where if {@code @@ -563,13 +627,13 @@ private static Set extrPlus( * @param strType * @return The list without consecutive constants. */ - private static List mergeStringLiterals( - List extracted, + private static List mergeStringLiterals( + List extracted, Type strType) { - List result = new ArrayList<>(); + List result = new ArrayList<>(); StringBuilder recent = new StringBuilder(); - for (SymbolicExpression expr : extracted) { + for (ValueExpression expr : extracted) { if (expr instanceof Constant) { // Update the string builder value adding the value of the // constant @@ -604,9 +668,9 @@ private static List mergeStringLiterals( * @param c Constant to analyze * @return The set containing the substrings of a Constant */ - private static Set getSubstrings( + private static Set getSubstrings( Constant c) { - Set result = new HashSet<>(); + Set result = new HashSet<>(); String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); @@ -614,7 +678,7 @@ private static Set getSubstrings( for (int l = 1; l < str.length(); l++) { // Iterate over the starting char for (int i = 0; i <= str.length() - l; i++) { - ValueExpression substring = new Constant(c.getStaticType(), str.substring(i, i + l), + Constant substring = new Constant(c.getStaticType(), str.substring(i, i + l), SyntheticLocation.INSTANCE); result.add(substring); @@ -629,14 +693,14 @@ private static Set getSubstrings( * @param c Constant to analyze * @return The set containing the prefixes of a Constant */ - private static Set getPrefix( + private static Set getPrefix( Constant c) { - Set result = new HashSet<>(); + Set result = new HashSet<>(); String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); // Iterate over the length for (int i = 1; i <= str.length(); i++) { - ValueExpression prefix = new Constant(c.getStaticType(), str.substring(0, i), SyntheticLocation.INSTANCE); + Constant prefix = new Constant(c.getStaticType(), str.substring(0, i), SyntheticLocation.INSTANCE); result.add(prefix); } @@ -649,15 +713,15 @@ private static Set getPrefix( * @param c Constant to analyze * @return The set containing the suffixes of a Constant */ - private static Set getSuffix( + private static Set getSuffix( Constant c) { - Set result = new HashSet<>(); + Set result = new HashSet<>(); String str = c.getValue() instanceof String ? (String) c.getValue() : c.getValue().toString(); int length = str.length(); // Iterate over the length for (int i = 1; i <= length; i++) { - ValueExpression suffix = new Constant(c.getStaticType(), str.substring(length - i, length), + Constant suffix = new Constant(c.getStaticType(), str.substring(length - i, length), SyntheticLocation.INSTANCE); result.add(suffix); @@ -674,7 +738,7 @@ private static Set getSuffix( * the list. */ private static SymbolicExpression composeExpression( - List expressions) { + List expressions) { if (expressions.size() == 1) return expressions.get(0); @@ -703,16 +767,16 @@ protected SubstringDomain add( // Don't add the expressions that contain the key variable (ex: x -> x, // x -> x + y will not be added) - Set expressionsToRemove = new HashSet<>(); + Set expressionsToAdd = new HashSet<>(); for (SymbolicExpression se : exprs) { if (!appears(id, se)) - expressionsToRemove.add(se); + expressionsToAdd.add(se); } - if (expressionsToRemove.isEmpty()) + if (expressionsToAdd.isEmpty()) return this; - ExpressionInverseSet newSet = new ExpressionInverseSet(expressionsToRemove); + ExpressionInverseSet newSet = new ExpressionInverseSet(expressionsToAdd); if (!(newFunction.get(id) == null)) newSet = newSet.glb(newFunction.get(id)); @@ -721,6 +785,16 @@ protected SubstringDomain add( return mk(lattice, newFunction); } + + protected SubstringDomain add( + SymbolicExpression expr, + Identifier id) + throws SemanticException { + Set expression = new HashSet<>(); + expression.add(expr); + + return add(expression, id); + } /* * First step of assignment, removing obsolete relations. @@ -743,19 +817,24 @@ private SubstringDomain remove( // Remove relations containing id from the other entries for (Map.Entry entry : newFunction.entrySet()) { - Set newSet = entry.getValue().elements.stream() - .filter(element -> !appears(id, element)) - .collect(Collectors.toSet()); - - ExpressionInverseSet value = newSet.isEmpty() ? new ExpressionInverseSet().top() - : new ExpressionInverseSet(newSet); - - entry.setValue(value); + ExpressionInverseSet newSet = removeFromSet(entry.getValue(), id); + entry.setValue(newSet); } return mk(lattice, newFunction); } + + /* + * Returns a set without expressions containing id starting from source + */ + private static ExpressionInverseSet removeFromSet(ExpressionInverseSet source, Identifier id){ + Set newSet = source.elements.stream() + .filter(element -> !appears(id, element)) + .collect(Collectors.toSet()); + + return newSet.isEmpty() ? new ExpressionInverseSet().top() : new ExpressionInverseSet(newSet); + } /** * Performs the inter-assignment phase @@ -863,31 +942,14 @@ protected SubstringDomain closure() throws SemanticException { } - /* - * Removes values mapped to empty set (top) - * @return A copy of the domain without variables mapped to empty set - * @throws SemanticException - */ private SubstringDomain clear() throws SemanticException { - SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - - Map iterate = mkNewFunction(result.function, false); - for (Map.Entry entry : iterate.entrySet()) { - if (entry.getValue().isTop()) { - result = result.forgetIdentifier(entry.getKey()); - } + Map newMap = mkNewFunction(function, false); - } + newMap.entrySet().removeIf(entry -> entry.getValue().isTop()); - return result; + return new SubstringDomain(lattice, newMap); } - /* - * Checks if a variable appears in an expression - * @param id Variable to check - * @param expr expression to analyze - * @return {@code true} if {@code id} appears, {@code false} otherwise - */ private static boolean appears( Identifier id, SymbolicExpression expr) { @@ -906,7 +968,6 @@ private static boolean appears( } return false; - } } diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java index d5ec5613e..d43232f6d 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java @@ -20,7 +20,7 @@ * in * this paper. * - * @author Michele + * @author Michele * Martelli * @author Vincenzo Arceri */ @@ -66,11 +66,7 @@ public SubstringDomainWithConstants assign( continue; if (elem.getValue().equals(compare)) { - Set add = new HashSet<>(); - add.add(elem.getKey()); - add.add(id); - - b = b.add(add, id).add(add, elem.getKey()).closure(); + b = b.add(elem.getKey(), id).add(id, elem.getKey()).closure(); } } } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index af6583b44..4d02cc182 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -9,11 +9,13 @@ import it.unive.lisa.analysis.lattices.Satisfiability; import it.unive.lisa.program.SyntheticLocation; import it.unive.lisa.program.type.BoolType; +import it.unive.lisa.program.type.Int16Type; import it.unive.lisa.program.type.StringType; import it.unive.lisa.symbolic.SymbolicExpression; import it.unive.lisa.symbolic.value.BinaryExpression; import it.unive.lisa.symbolic.value.Constant; import it.unive.lisa.symbolic.value.Identifier; +import it.unive.lisa.symbolic.value.TernaryExpression; import it.unive.lisa.symbolic.value.ValueExpression; import it.unive.lisa.symbolic.value.Variable; import it.unive.lisa.symbolic.value.operator.binary.LogicalAnd; @@ -23,6 +25,9 @@ import it.unive.lisa.symbolic.value.operator.binary.StringEndsWith; import it.unive.lisa.symbolic.value.operator.binary.StringEquals; import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; +import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; +import it.unive.lisa.symbolic.value.operator.ternary.StringSubstring; + import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -922,4 +927,72 @@ public void testLub5() throws SemanticException { assertEquals(lub, BOTTOM); } + + @Test + public void testExtr1() throws SemanticException { + ValueExpression replaceYAC = new TernaryExpression(StringType.INSTANCE, y, a, c, StringReplace.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression ABConcatX = new BinaryExpression(StringType.INSTANCE, ab, x, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression BConcatX = new BinaryExpression(StringType.INSTANCE, b, x, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceYAC, ABConcatX, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain result = domainE.assign(z, assignExpr, null, null); + + assertTrue(result.getState(z).contains(ABConcatX)); + assertTrue(result.getState(z).contains(BConcatX)); + + } + + @Test + public void testExtr2() throws SemanticException { + ValueExpression cb = new Constant(StringType.INSTANCE, "cb", SyntheticLocation.INSTANCE); + + ValueExpression replaceCbCA = new TernaryExpression(StringType.INSTANCE, cb, c, a, StringReplace.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceCbCA, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); + + assertTrue(result.getState(x).contains(abc)); + } + + @Test + public void testExtr3() throws SemanticException { + ValueExpression zero = new Constant(Int16Type.INSTANCE, 0, SyntheticLocation.INSTANCE); + ValueExpression two = new Constant(Int16Type.INSTANCE, 2, SyntheticLocation.INSTANCE); + ValueExpression substringAbc02 = new TernaryExpression(StringType.INSTANCE, abc, zero, two, StringSubstring.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, substringAbc02, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); + + assertTrue(result.getState(x).contains(abc)); + } + + @Test + public void testExtr4() throws SemanticException { + ValueExpression replaceXCA = new TernaryExpression(StringType.INSTANCE, x, c, a, StringReplace.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceXCA, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); + + assertTrue(result.getState(x).contains(c)); + } + + @Test + public void testExtr5() throws SemanticException { + ValueExpression zero = new Constant(Int16Type.INSTANCE, 0, SyntheticLocation.INSTANCE); + ValueExpression two = new Constant(Int16Type.INSTANCE, 2, SyntheticLocation.INSTANCE); + ValueExpression substringY02 = new TernaryExpression(StringType.INSTANCE, y, zero, two, StringSubstring.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, substringY02, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); + + assertTrue(result.getState(x).contains(c)); + } } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 37ad7e412..eeb2f0a67 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -12,6 +12,8 @@ import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; +import it.unive.lisa.conf.LiSAConfiguration.GraphType; + import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { From fe68555fd95603ac05f271243a252ba07b73f496 Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Sat, 22 Jun 2024 13:42:27 +0200 Subject: [PATCH 26/34] Apply spotless --- .../lisa/analysis/string/SubstringDomain.java | 126 ++++++++++-------- 1 file changed, 71 insertions(+), 55 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index eee3df2e5..f85e5dba7 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -26,10 +26,8 @@ import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; import it.unive.lisa.symbolic.value.operator.ternary.StringSubstring; -import it.unive.lisa.type.NumericType; import it.unive.lisa.type.Type; import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -168,7 +166,7 @@ public SubstringDomain smallStepSemantics( ValueExpression expression, ProgramPoint pp, SemanticOracle oracle) - throws SemanticException { + throws SemanticException { return this; } @@ -218,13 +216,13 @@ public SubstringDomain assume( throw new SemanticException("instanceof right"); Set extracted = extrPlus((ValueExpression) right, src, oracle, strType); - + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); result = result.add(extracted, (Identifier) left); result = result.closure(); - + return result.clear(); } else if (binaryOperator instanceof StringEquals) { @@ -232,14 +230,14 @@ public SubstringDomain assume( * Case both operands are identifiers */ if ((left instanceof Identifier) && (right instanceof Identifier)) { - + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); result = result.add(left, (Identifier) right); result = result.add(right, (Identifier) left); result = result.closure(); - + return result.clear(); } @@ -261,13 +259,13 @@ else if ((left instanceof Identifier) || (right instanceof Identifier)) { throw new SemanticException("instanceof right != ValueExpression.class"); Set add = extrPlus((ValueExpression) right, src, oracle, strType); - + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); result = result.add(add, (Identifier) left); result = result.closure(); - + return result.clear(); } @@ -351,7 +349,7 @@ public SubstringDomain forgetIdentifiersIf( } } } - + SubstringDomain result = mk(lattice, mkNewFunction(function, false)); for (Identifier id : ids) { @@ -449,7 +447,8 @@ private static List extr( ValueExpression expression) { List result = new ArrayList<>(); - if (expression instanceof BinaryExpression && ((BinaryExpression)expression).getOperator() instanceof StringConcat) { + if (expression instanceof BinaryExpression + && ((BinaryExpression) expression).getOperator() instanceof StringConcat) { BinaryExpression binaryExpression = (BinaryExpression) expression; ValueExpression left = (ValueExpression) binaryExpression.getLeft(); @@ -460,7 +459,6 @@ private static List extr( } else result.add(expression); - return result; } @@ -474,9 +472,10 @@ private Set extrPlus( ValueExpression expression, ProgramPoint pp, SemanticOracle oracle, - Type strType) throws SemanticException { + Type strType) + throws SemanticException { List extracted = extr(expression); - + /* * If there are more than 2 consecutive constants, merge them into a * single constant @@ -484,17 +483,18 @@ private Set extrPlus( List> sub_expressions = split(extracted, pp, oracle, strType); for (int i = 0; i < sub_expressions.size(); i++) { - List list = sub_expressions.get(i); - sub_expressions.set(i, mergeStringLiterals(list, strType)); + List list = sub_expressions.get(i); + sub_expressions.set(i, mergeStringLiterals(list, strType)); } Set result = new HashSet<>(); - + // Iterate sublists splitted from StringReplace expressions for (List list : sub_expressions) { // Iterate over the length of the expression for (int l = 1; l <= list.size(); l++) { - // Iterate from the start to the end according to the size of the + // Iterate from the start to the end according to the size of + // the // expression to create for (int i = 0; i <= (list.size() - l); i++) { List subList = list.subList(i, i + l); @@ -502,8 +502,8 @@ private Set extrPlus( if (subList.size() == 1 && subList.get(0) instanceof Constant) { /* - * Case the expression to ass is a single constant -> add - * its substrings + * Case the expression to ass is a single constant -> + * add its substrings */ Set substrings = getSubstrings((Constant) subList.get(0)); @@ -516,9 +516,9 @@ private Set extrPlus( } } else if (subList.get(0) instanceof Constant) { /* - * Case the first expression of the expression to add is a - * constant -> add an expression for each suffix of the - * constant + * Case the first expression of the expression to add is + * a constant -> add an expression for each suffix of + * the constant */ Set suffixes = getSuffix((Constant) subList.get(0)); @@ -529,9 +529,9 @@ private Set extrPlus( if (subList.get(subList.size() - 1) instanceof Constant) { /* - * Case the last expression of the expression to add - * is a constant -> add an expression for each - * prefix of the constant + * Case the last expression of the expression to + * add is a constant -> add an expression for + * each prefix of the constant */ Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); @@ -547,9 +547,9 @@ private Set extrPlus( } else if (subList.get(subList.size() - 1) instanceof Constant) { /* - * Case the last expression of the expression to add is a - * constant -> add an expression for each prefix of the - * constant + * Case the last expression of the expression to add is + * a constant -> add an expression for each prefix of + * the constant */ Set prefixes = getPrefix((Constant) subList.get(subList.size() - 1)); @@ -567,56 +567,70 @@ private Set extrPlus( } return new HashSet<>(result); } - - private List> split(List extracted, ProgramPoint pp, SemanticOracle oracle, Type strType) throws SemanticException{ + + private List> split( + List extracted, + ProgramPoint pp, + SemanticOracle oracle, + Type strType) + throws SemanticException { List> result = new ArrayList<>(); - + List temp = new ArrayList<>(); - - for(ValueExpression s : extracted) { + + for (ValueExpression s : extracted) { if (!(s instanceof Identifier || s instanceof Constant)) { // s in not Identifier or Constant -> eval s semantics - + if (s instanceof TernaryExpression) { TernaryExpression ternaryExpression = (TernaryExpression) s; - if (ternaryExpression.getLeft() instanceof Constant && ternaryExpression.getMiddle() instanceof Constant && ternaryExpression.getRight() instanceof Constant) { + if (ternaryExpression.getLeft() instanceof Constant + && ternaryExpression.getMiddle() instanceof Constant + && ternaryExpression.getRight() instanceof Constant) { Constant c1 = (Constant) ternaryExpression.getLeft(); Constant c2 = (Constant) ternaryExpression.getMiddle(); Constant c3 = (Constant) ternaryExpression.getRight(); - + if (ternaryExpression.getOperator() instanceof StringReplace) { - String s1 = c1.getValue() instanceof String ? (String) c1.getValue() : c1.getValue().toString(); - String s2 = c2.getValue() instanceof String ? (String) c2.getValue() : c2.getValue().toString(); - String s3 = c3.getValue() instanceof String ? (String) c3.getValue() : c3.getValue().toString(); - - // Special case: add the constant and do not split list + String s1 = c1.getValue() instanceof String ? (String) c1.getValue() + : c1.getValue().toString(); + String s2 = c2.getValue() instanceof String ? (String) c2.getValue() + : c2.getValue().toString(); + String s3 = c3.getValue() instanceof String ? (String) c3.getValue() + : c3.getValue().toString(); + + // Special case: add the constant and do not split + // list temp.add(new Constant(strType, s1.replace(s2, s3), SyntheticLocation.INSTANCE)); continue; } - if (ternaryExpression.getOperator() instanceof StringSubstring && c2.getValue() instanceof Integer && c3.getValue() instanceof Integer) { - String s1 = c1.getValue() instanceof String ? (String) c1.getValue() : c1.getValue().toString(); + if (ternaryExpression.getOperator() instanceof StringSubstring + && c2.getValue() instanceof Integer && c3.getValue() instanceof Integer) { + String s1 = c1.getValue() instanceof String ? (String) c1.getValue() + : c1.getValue().toString(); Integer i1 = (Integer) c2.getValue(); Integer i2 = (Integer) c3.getValue(); - - // Special case: add the constant and do not split list + + // Special case: add the constant and do not split + // list temp.add(new Constant(strType, s1.substring(i1, i2), SyntheticLocation.INSTANCE)); continue; } } } - + // Split list result.add(new ArrayList<>(temp)); temp.clear(); - + } else { // s instance of Identifier || s instance of Constant temp.add(s); } } - + result.add(temp); - + return result; } @@ -785,14 +799,14 @@ protected SubstringDomain add( return mk(lattice, newFunction); } - + protected SubstringDomain add( SymbolicExpression expr, Identifier id) throws SemanticException { Set expression = new HashSet<>(); expression.add(expr); - + return add(expression, id); } @@ -824,15 +838,17 @@ private SubstringDomain remove( return mk(lattice, newFunction); } - + /* * Returns a set without expressions containing id starting from source */ - private static ExpressionInverseSet removeFromSet(ExpressionInverseSet source, Identifier id){ + private static ExpressionInverseSet removeFromSet( + ExpressionInverseSet source, + Identifier id) { Set newSet = source.elements.stream() .filter(element -> !appears(id, element)) .collect(Collectors.toSet()); - + return newSet.isEmpty() ? new ExpressionInverseSet().top() : new ExpressionInverseSet(newSet); } From b9eb8c3cc7fdec488ddb73c11fd48b61db435f4c Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Sat, 22 Jun 2024 13:43:16 +0200 Subject: [PATCH 27/34] Apply spotless --- .../string/StringConstantPropagation.java | 3 +- .../string/SubstringDomainWithConstants.java | 3 - .../analysis/string/SubstringDomainTest.java | 71 +++++++++++-------- .../unive/lisa/cron/StringAnalysesTest.java | 2 - 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index 38da7f383..a29adf64e 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -17,7 +17,6 @@ import it.unive.lisa.symbolic.value.operator.binary.ComparisonNe; import it.unive.lisa.symbolic.value.operator.binary.StringConcat; import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; -import it.unive.lisa.symbolic.value.operator.ternary.StringSubstring; import it.unive.lisa.symbolic.value.operator.ternary.TernaryOperator; import it.unive.lisa.symbolic.value.operator.unary.UnaryOperator; import it.unive.lisa.util.representation.StringRepresentation; @@ -160,7 +159,7 @@ public StringConstantPropagation evalTernaryExpression( return new StringConstantPropagation(replaced); } - + return top(); } diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java index d43232f6d..5d0283b80 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java @@ -5,12 +5,9 @@ import it.unive.lisa.analysis.combination.ValueCartesianProduct; import it.unive.lisa.analysis.nonrelational.value.ValueEnvironment; import it.unive.lisa.program.cfg.ProgramPoint; -import it.unive.lisa.symbolic.SymbolicExpression; import it.unive.lisa.symbolic.value.Identifier; import it.unive.lisa.symbolic.value.ValueExpression; -import java.util.HashSet; import java.util.Map.Entry; -import java.util.Set; /** * The substring relational abstract domain (see {@link SubstringDomain}) diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 4d02cc182..00d00bf57 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -27,7 +27,6 @@ import it.unive.lisa.symbolic.value.operator.binary.StringStartsWith; import it.unive.lisa.symbolic.value.operator.ternary.StringReplace; import it.unive.lisa.symbolic.value.operator.ternary.StringSubstring; - import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -927,72 +926,82 @@ public void testLub5() throws SemanticException { assertEquals(lub, BOTTOM); } - + @Test public void testExtr1() throws SemanticException { - ValueExpression replaceYAC = new TernaryExpression(StringType.INSTANCE, y, a, c, StringReplace.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression replaceYAC = new TernaryExpression(StringType.INSTANCE, y, a, c, StringReplace.INSTANCE, + SyntheticLocation.INSTANCE); + ValueExpression ABConcatX = new BinaryExpression(StringType.INSTANCE, ab, x, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); ValueExpression BConcatX = new BinaryExpression(StringType.INSTANCE, b, x, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - - ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceYAC, ABConcatX, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceYAC, ABConcatX, + StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + SubstringDomain result = domainE.assign(z, assignExpr, null, null); - + assertTrue(result.getState(z).contains(ABConcatX)); assertTrue(result.getState(z).contains(BConcatX)); - + } - + @Test public void testExtr2() throws SemanticException { ValueExpression cb = new Constant(StringType.INSTANCE, "cb", SyntheticLocation.INSTANCE); - ValueExpression replaceCbCA = new TernaryExpression(StringType.INSTANCE, cb, c, a, StringReplace.INSTANCE, SyntheticLocation.INSTANCE); - - ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceCbCA, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression replaceCbCA = new TernaryExpression(StringType.INSTANCE, cb, c, a, StringReplace.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceCbCA, c, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); assertTrue(result.getState(x).contains(abc)); } - + @Test public void testExtr3() throws SemanticException { ValueExpression zero = new Constant(Int16Type.INSTANCE, 0, SyntheticLocation.INSTANCE); ValueExpression two = new Constant(Int16Type.INSTANCE, 2, SyntheticLocation.INSTANCE); - ValueExpression substringAbc02 = new TernaryExpression(StringType.INSTANCE, abc, zero, two, StringSubstring.INSTANCE, SyntheticLocation.INSTANCE); - - ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, substringAbc02, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression substringAbc02 = new TernaryExpression(StringType.INSTANCE, abc, zero, two, + StringSubstring.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, substringAbc02, c, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); - assertTrue(result.getState(x).contains(abc)); + assertTrue(result.getState(x).contains(abc)); } - + @Test public void testExtr4() throws SemanticException { - ValueExpression replaceXCA = new TernaryExpression(StringType.INSTANCE, x, c, a, StringReplace.INSTANCE, SyntheticLocation.INSTANCE); - - ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceXCA, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression replaceXCA = new TernaryExpression(StringType.INSTANCE, x, c, a, StringReplace.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceXCA, c, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); assertTrue(result.getState(x).contains(c)); } - + @Test public void testExtr5() throws SemanticException { ValueExpression zero = new Constant(Int16Type.INSTANCE, 0, SyntheticLocation.INSTANCE); ValueExpression two = new Constant(Int16Type.INSTANCE, 2, SyntheticLocation.INSTANCE); - ValueExpression substringY02 = new TernaryExpression(StringType.INSTANCE, y, zero, two, StringSubstring.INSTANCE, SyntheticLocation.INSTANCE); - - ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, substringY02, c, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression substringY02 = new TernaryExpression(StringType.INSTANCE, y, zero, two, + StringSubstring.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, substringY02, c, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); - assertTrue(result.getState(x).contains(c)); + assertTrue(result.getState(x).contains(c)); } } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index eeb2f0a67..37ad7e412 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -12,8 +12,6 @@ import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; -import it.unive.lisa.conf.LiSAConfiguration.GraphType; - import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { From a274a9ce6b9ed83eab1967b078aeeb95ac347f6a Mon Sep 17 00:00:00 2001 From: Michele Date: Tue, 25 Jun 2024 19:14:13 +0200 Subject: [PATCH 28/34] Precision improvement + tests --- .../string/strings-subs-constants.imp | 20 +++- .../string/subs-domain-constants/report.json | 18 +-- ...ngs.replace(strings__this,_untyped_s).json | 2 +- ...typed_strings.replace2(strings__this).json | 1 + ...typed_strings.replace3(strings__this).json | 1 + ...typed_strings.replace4(strings__this).json | 1 + .../string/StringConstantPropagation.java | 4 + .../lisa/analysis/string/SubstringDomain.java | 107 ++++++++++++------ .../string/SubstringDomainWithConstants.java | 27 ++++- .../analysis/string/SubstringDomainTest.java | 58 +++++++++- .../unive/lisa/cron/StringAnalysesTest.java | 2 + 11 files changed, 191 insertions(+), 50 deletions(-) create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace2(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace3(strings__this).json create mode 100644 lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace4(strings__this).json diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp b/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp index 127f88919..3d42ff8a5 100644 --- a/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp +++ b/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp @@ -1,12 +1,10 @@ class strings { constants(){ - def x = "ab"; def y = "a"; def z = "b"; def w = y + z; - } replace(s){ @@ -18,4 +16,22 @@ class strings { if (streq(s, k)) def i = 1 + 1; } + + replace2(){ + def y = "xyz"; + def x = "a" + strrep(y, "x", "z") + "c"; + } + + replace3(){ + def y = "xyz"; + def z = "w"; + def x = "ab" + strrep(z + y, "x", "yz") + "c"; + } + + replace4(){ + def k = "z"; + def x = "abc" + k; + def y = "abc"; + def z = "a" + strrep(y, "abc", "b") + "c"; + } } \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json index b3881975f..0626aad41 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/report.json @@ -1,17 +1,17 @@ { "warnings" : [ ], - "files" : [ "report.json", "untyped_strings.constants(strings__this).json", "untyped_strings.replace(strings__this,_untyped_s).json" ], + "files" : [ "report.json", "untyped_strings.constants(strings__this).json", "untyped_strings.replace(strings__this,_untyped_s).json", "untyped_strings.replace2(strings__this).json", "untyped_strings.replace3(strings__this).json", "untyped_strings.replace4(strings__this).json" ], "info" : { - "cfgs" : "2", - "duration" : "9ms", - "end" : "2024-06-22T12:58:22.543+02:00", - "expressions" : "29", - "files" : "2", + "cfgs" : "5", + "duration" : "16ms", + "end" : "2024-06-25T19:08:32.428+02:00", + "expressions" : "72", + "files" : "5", "globals" : "0", - "members" : "2", + "members" : "5", "programs" : "1", - "start" : "2024-06-22T12:58:22.534+02:00", - "statements" : "12", + "start" : "2024-06-25T19:08:32.412+02:00", + "statements" : "24", "units" : "1", "version" : "0.1b9", "warnings" : "0" diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json index 32570832f..10f139637 100644 --- a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace(strings__this,_untyped_s).json @@ -1 +1 @@ -{"name":"untyped strings::replace(strings* this, untyped s)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"aaaaa\""},{"id":1,"text":"x"},{"id":2,"text":"\"aaaaa\""},{"id":3,"subNodes":[4,5],"text":"y = \"bba\""},{"id":4,"text":"y"},{"id":5,"text":"\"bba\""},{"id":6,"subNodes":[7,8],"text":"k = +(\"bb\", \"a\")"},{"id":7,"text":"k"},{"id":8,"subNodes":[9,10],"text":"+(\"bb\", \"a\")"},{"id":9,"text":"\"bb\""},{"id":10,"text":"\"a\""},{"id":11,"subNodes":[12,13],"text":"z = replace(x, \"aa\", \"b\")"},{"id":12,"text":"z"},{"id":13,"subNodes":[14,15,16],"text":"replace(x, \"aa\", \"b\")"},{"id":14,"text":"x"},{"id":15,"text":"\"aa\""},{"id":16,"text":"\"b\""},{"id":17,"subNodes":[18,19],"text":"equals(s, k)"},{"id":18,"text":"s"},{"id":19,"text":"k"},{"id":20,"subNodes":[21,22],"text":"i = +(1, 1)"},{"id":21,"text":"i"},{"id":22,"subNodes":[23,24],"text":"+(1, 1)"},{"id":23,"text":"1"},{"id":24,"text":"1"},{"id":25,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":11,"kind":"SequentialEdge"},{"sourceId":11,"destId":17,"kind":"SequentialEdge"},{"sourceId":17,"destId":20,"kind":"TrueEdge"},{"sourceId":17,"destId":25,"kind":"FalseEdge"},{"sourceId":20,"destId":25,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":2,"description":{"expressions":["\"aaaaa\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":5,"description":{"expressions":["\"bba\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":6,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":7,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":8,"description":{"expressions":["\"bb\" strcat \"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":9,"description":{"expressions":["\"bb\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":10,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":11,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":12,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":13,"description":{"expressions":["x strreplace(\"aa\", \"b\")"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":15,"description":{"expressions":["\"aa\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":16,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":17,"description":{"expressions":["s strcmp k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":18,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":19,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":20,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"i":"#TOP#","k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":21,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":22,"description":{"expressions":["1 + 1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":23,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":24,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":25,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}}]} \ No newline at end of file +{"name":"untyped strings::replace(strings* this, untyped s)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"x = \"aaaaa\""},{"id":1,"text":"x"},{"id":2,"text":"\"aaaaa\""},{"id":3,"subNodes":[4,5],"text":"y = \"bba\""},{"id":4,"text":"y"},{"id":5,"text":"\"bba\""},{"id":6,"subNodes":[7,8],"text":"k = +(\"bb\", \"a\")"},{"id":7,"text":"k"},{"id":8,"subNodes":[9,10],"text":"+(\"bb\", \"a\")"},{"id":9,"text":"\"bb\""},{"id":10,"text":"\"a\""},{"id":11,"subNodes":[12,13],"text":"z = replace(x, \"aa\", \"b\")"},{"id":12,"text":"z"},{"id":13,"subNodes":[14,15,16],"text":"replace(x, \"aa\", \"b\")"},{"id":14,"text":"x"},{"id":15,"text":"\"aa\""},{"id":16,"text":"\"b\""},{"id":17,"subNodes":[18,19],"text":"equals(s, k)"},{"id":18,"text":"s"},{"id":19,"text":"k"},{"id":20,"subNodes":[21,22],"text":"i = +(1, 1)"},{"id":21,"text":"i"},{"id":22,"subNodes":[23,24],"text":"+(1, 1)"},{"id":23,"text":"1"},{"id":24,"text":"1"},{"id":25,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":11,"kind":"SequentialEdge"},{"sourceId":11,"destId":17,"kind":"SequentialEdge"},{"sourceId":17,"destId":20,"kind":"TrueEdge"},{"sourceId":17,"destId":25,"kind":"FalseEdge"},{"sourceId":20,"destId":25,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":1,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":2,"description":{"expressions":["\"aaaaa\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"]},"value":[{"s":"#TOP#"},"#TOP#"]}}},{"nodeId":3,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":4,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":5,"description":{"expressions":["\"bba\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"]},"value":[{"s":"#TOP#","x":"aaaaa"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""]}]}}},{"nodeId":6,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":7,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":8,"description":{"expressions":["\"bb\" strcat \"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":9,"description":{"expressions":["\"bb\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":10,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"s":"#TOP#","x":"aaaaa","y":"bba"},{"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\""]}]}}},{"nodeId":11,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":12,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":13,"description":{"expressions":["x strreplace(\"aa\", \"b\")"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":14,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":15,"description":{"expressions":["\"aa\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":16,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k"]}]}}},{"nodeId":17,"description":{"expressions":["s strcmp k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":18,"description":{"expressions":["s"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":19,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}},{"nodeId":20,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"i":["int32"],"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":21,"description":{"expressions":["i"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":22,"description":{"expressions":["1 + 1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":23,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":24,"description":{"expressions":["1"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","s","y","z"],"s":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","s","y"]}]}}},{"nodeId":25,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"k":["string"],"s":"#TOP#","this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"bba","s":"#TOP#","x":"aaaaa","y":"bba","z":"bba"},{"k":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","y","z"],"x":["\"a\"","\"aa\"","\"aaa\"","\"aaaa\"","\"aaaaa\""],"y":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","z"],"z":["\"a\"","\"b\"","\"ba\"","\"bb\"","\"bba\"","k","y"]}]}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace2(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace2(strings__this).json new file mode 100644 index 000000000..bd0abdc7a --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace2(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::replace2(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"y = \"xyz\""},{"id":1,"text":"y"},{"id":2,"text":"\"xyz\""},{"id":3,"subNodes":[4,5],"text":"x = +(+(\"a\", replace(y, \"x\", \"z\")), \"c\")"},{"id":4,"text":"x"},{"id":5,"subNodes":[6,12],"text":"+(+(\"a\", replace(y, \"x\", \"z\")), \"c\")"},{"id":6,"subNodes":[7,8],"text":"+(\"a\", replace(y, \"x\", \"z\"))"},{"id":7,"text":"\"a\""},{"id":8,"subNodes":[9,10,11],"text":"replace(y, \"x\", \"z\")"},{"id":9,"text":"y"},{"id":10,"text":"\"x\""},{"id":11,"text":"\"z\""},{"id":12,"text":"\"c\""},{"id":13,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":13,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":1,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":["#TOP#","#TOP#"]}}},{"nodeId":2,"description":{"expressions":["\"xyz\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":["#TOP#","#TOP#"]}}},{"nodeId":3,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"x":"azyzc","y":"xyz"},{"x":["\"a\"","\"az\"","\"azy\"","\"azyz\"","\"azyzc\"","\"c\"","\"y\"","\"yz\"","\"yzc\"","\"z\"","\"zc\"","\"zy\"","\"zyz\"","\"zyzc\""],"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":5,"description":{"expressions":["\"a\" strcat y strreplace(\"x\", \"z\") strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":6,"description":{"expressions":["\"a\" strcat y strreplace(\"x\", \"z\")"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":7,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":8,"description":{"expressions":["y strreplace(\"x\", \"z\")"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":10,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":11,"description":{"expressions":["\"z\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":12,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":13,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"x":"azyzc","y":"xyz"},{"x":["\"a\"","\"az\"","\"azy\"","\"azyz\"","\"azyzc\"","\"c\"","\"y\"","\"yz\"","\"yzc\"","\"z\"","\"zc\"","\"zy\"","\"zyz\"","\"zyzc\""],"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace3(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace3(strings__this).json new file mode 100644 index 000000000..729c21fd3 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace3(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::replace3(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"y = \"xyz\""},{"id":1,"text":"y"},{"id":2,"text":"\"xyz\""},{"id":3,"subNodes":[4,5],"text":"z = \"w\""},{"id":4,"text":"z"},{"id":5,"text":"\"w\""},{"id":6,"subNodes":[7,8],"text":"x = +(+(\"ab\", replace(+(z, y), \"x\", \"yz\")), \"c\")"},{"id":7,"text":"x"},{"id":8,"subNodes":[9,17],"text":"+(+(\"ab\", replace(+(z, y), \"x\", \"yz\")), \"c\")"},{"id":9,"subNodes":[10,11],"text":"+(\"ab\", replace(+(z, y), \"x\", \"yz\"))"},{"id":10,"text":"\"ab\""},{"id":11,"subNodes":[12,15,16],"text":"replace(+(z, y), \"x\", \"yz\")"},{"id":12,"subNodes":[13,14],"text":"+(z, y)"},{"id":13,"text":"z"},{"id":14,"text":"y"},{"id":15,"text":"\"x\""},{"id":16,"text":"\"yz\""},{"id":17,"text":"\"c\""},{"id":18,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":6,"kind":"SequentialEdge"},{"sourceId":6,"destId":18,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":1,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":["#TOP#","#TOP#"]}}},{"nodeId":2,"description":{"expressions":["\"xyz\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":["#TOP#","#TOP#"]}}},{"nodeId":3,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":4,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":5,"description":{"expressions":["\"w\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"]},"value":[{"y":"xyz"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""]}]}}},{"nodeId":6,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"x":"abwyzyzc","y":"xyz","z":"w"},{"x":["\"a\"","\"ab\"","\"abw\"","\"abwy\"","\"abwyz\"","\"abwyzy\"","\"abwyzyz\"","\"abwyzyzc\"","\"b\"","\"bw\"","\"bwy\"","\"bwyz\"","\"bwyzy\"","\"bwyzyz\"","\"bwyzyzc\"","\"c\"","\"w\"","\"wy\"","\"wyz\"","\"wyzy\"","\"wyzyz\"","\"wyzyzc\"","\"y\"","\"yz\"","\"yzc\"","\"yzy\"","\"yzyz\"","\"yzyzc\"","\"z\"","\"zc\"","\"zy\"","\"zyz\"","\"zyzc\""],"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":7,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":8,"description":{"expressions":["\"ab\" strcat z strcat y strreplace(\"x\", \"yz\") strcat \"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":9,"description":{"expressions":["\"ab\" strcat z strcat y strreplace(\"x\", \"yz\")"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":10,"description":{"expressions":["\"ab\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":11,"description":{"expressions":["z strcat y strreplace(\"x\", \"yz\")"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":12,"description":{"expressions":["z strcat y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":13,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":14,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":15,"description":{"expressions":["\"x\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":16,"description":{"expressions":["\"yz\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":17,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"this":["strings*"],"y":["string"],"z":["string"]},"value":[{"y":"xyz","z":"w"},{"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}},{"nodeId":18,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"x":"abwyzyzc","y":"xyz","z":"w"},{"x":["\"a\"","\"ab\"","\"abw\"","\"abwy\"","\"abwyz\"","\"abwyzy\"","\"abwyzyz\"","\"abwyzyzc\"","\"b\"","\"bw\"","\"bwy\"","\"bwyz\"","\"bwyzy\"","\"bwyzyz\"","\"bwyzyzc\"","\"c\"","\"w\"","\"wy\"","\"wyz\"","\"wyzy\"","\"wyzyz\"","\"wyzyzc\"","\"y\"","\"yz\"","\"yzc\"","\"yzy\"","\"yzyz\"","\"yzyzc\"","\"z\"","\"zc\"","\"zy\"","\"zyz\"","\"zyzc\""],"y":["\"x\"","\"xy\"","\"xyz\"","\"y\"","\"yz\"","\"z\""],"z":["\"w\""]}]}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace4(strings__this).json b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace4(strings__this).json new file mode 100644 index 000000000..c5b09de70 --- /dev/null +++ b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/untyped_strings.replace4(strings__this).json @@ -0,0 +1 @@ +{"name":"untyped strings::replace4(strings* this)","description":null,"nodes":[{"id":0,"subNodes":[1,2],"text":"k = \"z\""},{"id":1,"text":"k"},{"id":2,"text":"\"z\""},{"id":3,"subNodes":[4,5],"text":"x = +(\"abc\", k)"},{"id":4,"text":"x"},{"id":5,"subNodes":[6,7],"text":"+(\"abc\", k)"},{"id":6,"text":"\"abc\""},{"id":7,"text":"k"},{"id":8,"subNodes":[9,10],"text":"y = \"abc\""},{"id":9,"text":"y"},{"id":10,"text":"\"abc\""},{"id":11,"subNodes":[12,13],"text":"z = +(+(\"a\", replace(y, \"abc\", \"b\")), \"c\")"},{"id":12,"text":"z"},{"id":13,"subNodes":[14,20],"text":"+(+(\"a\", replace(y, \"abc\", \"b\")), \"c\")"},{"id":14,"subNodes":[15,16],"text":"+(\"a\", replace(y, \"abc\", \"b\"))"},{"id":15,"text":"\"a\""},{"id":16,"subNodes":[17,18,19],"text":"replace(y, \"abc\", \"b\")"},{"id":17,"text":"y"},{"id":18,"text":"\"abc\""},{"id":19,"text":"\"b\""},{"id":20,"text":"\"c\""},{"id":21,"text":"ret"}],"edges":[{"sourceId":0,"destId":3,"kind":"SequentialEdge"},{"sourceId":3,"destId":8,"kind":"SequentialEdge"},{"sourceId":8,"destId":11,"kind":"SequentialEdge"},{"sourceId":11,"destId":21,"kind":"SequentialEdge"}],"descriptions":[{"nodeId":0,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"]},"value":[{"k":"z"},{"k":["\"z\""]}]}}},{"nodeId":1,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":["#TOP#","#TOP#"]}}},{"nodeId":2,"description":{"expressions":["\"z\""],"state":{"heap":"monolith","type":{"this":["strings*"]},"value":["#TOP#","#TOP#"]}}},{"nodeId":3,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"]},"value":[{"k":"z","x":"abcz"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k"]}]}}},{"nodeId":4,"description":{"expressions":["x"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"]},"value":[{"k":"z"},{"k":["\"z\""]}]}}},{"nodeId":5,"description":{"expressions":["\"abc\" strcat k"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"]},"value":[{"k":"z"},{"k":["\"z\""]}]}}},{"nodeId":6,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"]},"value":[{"k":"z"},{"k":["\"z\""]}]}}},{"nodeId":7,"description":{"expressions":["k"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"]},"value":[{"k":"z"},{"k":["\"z\""]}]}}},{"nodeId":8,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":9,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"]},"value":[{"k":"z","x":"abcz"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k"]}]}}},{"nodeId":10,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"]},"value":[{"k":"z","x":"abcz"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k"]}]}}},{"nodeId":11,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"z","x":"abcz","y":"abc","z":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y","z"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\"","z"],"z":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\"","y"]}]}}},{"nodeId":12,"description":{"expressions":["z"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":13,"description":{"expressions":["\"a\" strcat y strreplace(\"abc\", \"b\") strcat \"c\""],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":14,"description":{"expressions":["\"a\" strcat y strreplace(\"abc\", \"b\")"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":15,"description":{"expressions":["\"a\""],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":16,"description":{"expressions":["y strreplace(\"abc\", \"b\")"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":17,"description":{"expressions":["y"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":18,"description":{"expressions":["\"abc\""],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":19,"description":{"expressions":["\"b\""],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":20,"description":{"expressions":["\"c\""],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"]},"value":[{"k":"z","x":"abcz","y":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\""]}]}}},{"nodeId":21,"description":{"expressions":["skip"],"state":{"heap":"monolith","type":{"k":["string"],"this":["strings*"],"x":["string"],"y":["string"],"z":["string"]},"value":[{"k":"z","x":"abcz","y":"abc","z":"abc"},{"k":["\"z\""],"x":["\"a\"","\"ab\"","\"abc\"","\"abc\" strcat k","\"abcz\"","\"b\"","\"bc\"","\"bc\" strcat k","\"bcz\"","\"c\"","\"c\" strcat k","\"cz\"","\"z\"","k","y","z"],"y":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\"","z"],"z":["\"a\"","\"ab\"","\"abc\"","\"b\"","\"bc\"","\"c\"","y"]}]}}}]} \ No newline at end of file diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index a29adf64e..c22a641df 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -239,4 +239,8 @@ else if (operator == ComparisonNe.INSTANCE) else return Satisfiability.UNKNOWN; } + + protected String getValue() { + return value; + } } diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index f85e5dba7..fb57b845d 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -580,43 +580,63 @@ private List> split( for (ValueExpression s : extracted) { if (!(s instanceof Identifier || s instanceof Constant)) { - // s in not Identifier or Constant -> eval s semantics - if (s instanceof TernaryExpression) { TernaryExpression ternaryExpression = (TernaryExpression) s; - if (ternaryExpression.getLeft() instanceof Constant - && ternaryExpression.getMiddle() instanceof Constant - && ternaryExpression.getRight() instanceof Constant) { - Constant c1 = (Constant) ternaryExpression.getLeft(); - Constant c2 = (Constant) ternaryExpression.getMiddle(); - Constant c3 = (Constant) ternaryExpression.getRight(); - - if (ternaryExpression.getOperator() instanceof StringReplace) { - String s1 = c1.getValue() instanceof String ? (String) c1.getValue() - : c1.getValue().toString(); - String s2 = c2.getValue() instanceof String ? (String) c2.getValue() - : c2.getValue().toString(); - String s3 = c3.getValue() instanceof String ? (String) c3.getValue() - : c3.getValue().toString(); - - // Special case: add the constant and do not split - // list - temp.add(new Constant(strType, s1.replace(s2, s3), SyntheticLocation.INSTANCE)); - continue; - } - if (ternaryExpression.getOperator() instanceof StringSubstring - && c2.getValue() instanceof Integer && c3.getValue() instanceof Integer) { - String s1 = c1.getValue() instanceof String ? (String) c1.getValue() - : c1.getValue().toString(); - Integer i1 = (Integer) c2.getValue(); - Integer i2 = (Integer) c3.getValue(); - - // Special case: add the constant and do not split - // list - temp.add(new Constant(strType, s1.substring(i1, i2), SyntheticLocation.INSTANCE)); - continue; - } + + // strrep(c1, c2, c3) where c1 or c2 or c3 can be a concatenation of constants + if (ternaryExpression.getOperator() instanceof StringReplace && ternaryExpression.getLeft() instanceof ValueExpression && ternaryExpression.getMiddle() instanceof ValueExpression && ternaryExpression.getRight() instanceof ValueExpression && hasOnlyConstants((ValueExpression)ternaryExpression.getLeft()) && hasOnlyConstants((ValueExpression)ternaryExpression.getMiddle()) && hasOnlyConstants((ValueExpression)ternaryExpression.getRight())) { + // left, middle, right are only constants or concatenation of constants + + List left = extr((ValueExpression) ternaryExpression.getLeft()); + left = mergeStringLiterals(left, strType); + if(left.size() != 1 && !(left.get(0) instanceof Constant)) + throw new SemanticException("unexpected"); + + Constant leftConstant = (Constant) left.get(0); + + List middle = extr((ValueExpression) ternaryExpression.getMiddle()); + middle = mergeStringLiterals(middle, strType); + if(middle.size() != 1 && !(middle.get(0) instanceof Constant)) + throw new SemanticException("unexpected"); + + Constant middleConstant = (Constant) middle.get(0); + + List right = extr((ValueExpression) ternaryExpression.getRight()); + right = mergeStringLiterals(right, strType); + if(right.size() != 1 && !(right.get(0) instanceof Constant)) + throw new SemanticException("unexpected"); + + Constant rightConstant = (Constant) right.get(0); + + String s1 = leftConstant.getValue() instanceof String ? (String) leftConstant.getValue() + : leftConstant.getValue().toString(); + String s2 = middleConstant.getValue() instanceof String ? (String) middleConstant.getValue() + : middleConstant.getValue().toString(); + String s3 = rightConstant.getValue() instanceof String ? (String) rightConstant.getValue() + : rightConstant.getValue().toString(); + + temp.add(new Constant(strType, s1.replace(s2, s3), SyntheticLocation.INSTANCE)); + continue; } + + // strsub(s1, i1, i2) where s1 can be a concatenation of constants + if (ternaryExpression.getOperator() instanceof StringSubstring && ternaryExpression.getLeft() instanceof ValueExpression && ternaryExpression.getMiddle() instanceof Constant && ternaryExpression.getRight() instanceof Constant && hasOnlyConstants((ValueExpression)ternaryExpression.getLeft()) ) { + List left = extr((ValueExpression) ternaryExpression.getLeft()); + left = mergeStringLiterals(left, strType); + if(left.size() != 1 && !(left.get(0) instanceof Constant)) + throw new SemanticException("unexpected"); + + Constant leftConstant = (Constant) left.get(0); + + String s1 = leftConstant.getValue() instanceof String ? (String) leftConstant.getValue() + : leftConstant.getValue().toString(); + Integer i1 = (Integer) ((Constant)ternaryExpression.getMiddle()).getValue(); + Integer i2 = (Integer) ((Constant)ternaryExpression.getRight()).getValue(); + + temp.add(new Constant(strType, s1.substring(i1, i2), SyntheticLocation.INSTANCE)); + continue; + } + } // Split list @@ -633,6 +653,25 @@ private List> split( return result; } + + /* + * + * Returns true iff the parameter is a Constant or a concatenation of Constant values + */ + private boolean hasOnlyConstants(ValueExpression expr) { + if (expr instanceof Constant) + return true; + + if (expr instanceof BinaryExpression && ((BinaryExpression)expr).getOperator() instanceof StringConcat) { + BinaryExpression be = (BinaryExpression) expr; + if(!(be.getLeft() instanceof ValueExpression && be.getRight() instanceof ValueExpression)) + return false; + + return hasOnlyConstants((ValueExpression) be.getLeft()) && hasOnlyConstants((ValueExpression) be.getRight()); + } + + return false; + } /* * Returns a list with no more than one consecutive constant where if {@code diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java index 5d0283b80..f2b7e47cc 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java @@ -4,9 +4,15 @@ import it.unive.lisa.analysis.SemanticOracle; import it.unive.lisa.analysis.combination.ValueCartesianProduct; import it.unive.lisa.analysis.nonrelational.value.ValueEnvironment; +import it.unive.lisa.program.SyntheticLocation; import it.unive.lisa.program.cfg.ProgramPoint; +import it.unive.lisa.symbolic.value.BinaryExpression; +import it.unive.lisa.symbolic.value.Constant; import it.unive.lisa.symbolic.value.Identifier; import it.unive.lisa.symbolic.value.ValueExpression; +import it.unive.lisa.symbolic.value.operator.binary.StringEquals; +import it.unive.lisa.type.Type; + import java.util.Map.Entry; /** @@ -51,21 +57,36 @@ public SubstringDomainWithConstants assign( ProgramPoint pp, SemanticOracle oracle) throws SemanticException { + + // expresson must be a string expression + if (oracle != null && pp != null && oracle.getRuntimeTypesOf(expression, pp, oracle).stream() + .allMatch(t -> !t.isStringType() && !t.isUntyped())) + return this; ValueEnvironment a = this.left.assign(id, expression, pp, oracle); SubstringDomain b = this.right.assign(id, expression, pp, oracle); - StringConstantPropagation compare = a.getState(id); + StringConstantPropagation constantValue = a.getState(id); - if (!compare.isTop() && !compare.isBottom()) { + if (!constantValue.isTop() && !constantValue.isBottom()) { for (Entry elem : a) { if (elem.getKey().equals(id)) continue; - if (elem.getValue().equals(compare)) { + if (elem.getValue().equals(constantValue)) { b = b.add(elem.getKey(), id).add(id, elem.getKey()).closure(); } } + + Type strType = pp.getProgram().getTypes().getStringType(); + Type boolType = pp.getProgram().getTypes().getBooleanType(); + + + String stringConstantValue = constantValue.getValue(); + Constant constant = new Constant(strType, stringConstantValue, SyntheticLocation.INSTANCE); + ValueExpression newExpression = new BinaryExpression(boolType, id, constant, StringEquals.INSTANCE, + SyntheticLocation.INSTANCE); + b = b.assume(newExpression, pp, pp, oracle); } return mk(a, b); diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index 00d00bf57..e0fce2f63 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -944,7 +944,6 @@ public void testExtr1() throws SemanticException { assertTrue(result.getState(z).contains(ABConcatX)); assertTrue(result.getState(z).contains(BConcatX)); - } @Test @@ -1004,4 +1003,61 @@ public void testExtr5() throws SemanticException { assertTrue(result.getState(x).contains(c)); } + + @Test + public void testExtr6() throws SemanticException { + Constant AB = new Constant(StringType.INSTANCE, "ab", SyntheticLocation.INSTANCE); + Constant CD = new Constant(StringType.INSTANCE, "cd", SyntheticLocation.INSTANCE); + ValueExpression ABConcatCD = new BinaryExpression(StringType.INSTANCE, AB, CD, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression one = new Constant(Int16Type.INSTANCE, 1, SyntheticLocation.INSTANCE); + ValueExpression three = new Constant(Int16Type.INSTANCE, 3, SyntheticLocation.INSTANCE); + ValueExpression substringABCD13 = new TernaryExpression(StringType.INSTANCE, ABConcatCD, one, three, + StringSubstring.INSTANCE, SyntheticLocation.INSTANCE); + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, substringABCD13, c, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); + + + Constant BCC = new Constant(StringType.INSTANCE, "bcc", SyntheticLocation.INSTANCE); + + assertTrue(result.getState(x).contains(BCC)); + } + + @Test + public void testExtr7() throws SemanticException { + Constant AB = new Constant(StringType.INSTANCE, "ab", SyntheticLocation.INSTANCE); + ValueExpression ABConcatY = new BinaryExpression(StringType.INSTANCE, AB, y, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression one = new Constant(Int16Type.INSTANCE, 1, SyntheticLocation.INSTANCE); + ValueExpression three = new Constant(Int16Type.INSTANCE, 3, SyntheticLocation.INSTANCE); + ValueExpression assignExpr = new TernaryExpression(StringType.INSTANCE, ABConcatY, one, three, + StringSubstring.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); + + assertTrue(result.isBottom()); + } + + @Test + public void testExtr8() throws SemanticException { + ValueExpression replaceABAC = new TernaryExpression(StringType.INSTANCE, ab, a, c, StringReplace.INSTANCE, + SyntheticLocation.INSTANCE); + + ValueExpression ABConcatX = new BinaryExpression(StringType.INSTANCE, ab, x, StringConcat.INSTANCE, + SyntheticLocation.INSTANCE); + + + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceABAC, ABConcatX, + StringConcat.INSTANCE, SyntheticLocation.INSTANCE); + + SubstringDomain result = domainE.assign(z, assignExpr, null, null); + + Constant CBAB = new Constant(StringType.INSTANCE, "cbab", SyntheticLocation.INSTANCE); + assertTrue(result.getState(z).contains(CBAB)); + } } diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 37ad7e412..eeb2f0a67 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -12,6 +12,8 @@ import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; +import it.unive.lisa.conf.LiSAConfiguration.GraphType; + import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { From 8ed6e639e5e35be538bb689567da441c24bc4c97 Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Tue, 25 Jun 2024 19:27:48 +0200 Subject: [PATCH 29/34] Spotless apply --- .../lisa/analysis/string/SubstringDomain.java | 83 +++++++++++-------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index fb57b845d..7fa5a9d67 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -582,61 +582,74 @@ private List> split( if (!(s instanceof Identifier || s instanceof Constant)) { if (s instanceof TernaryExpression) { TernaryExpression ternaryExpression = (TernaryExpression) s; - - // strrep(c1, c2, c3) where c1 or c2 or c3 can be a concatenation of constants - if (ternaryExpression.getOperator() instanceof StringReplace && ternaryExpression.getLeft() instanceof ValueExpression && ternaryExpression.getMiddle() instanceof ValueExpression && ternaryExpression.getRight() instanceof ValueExpression && hasOnlyConstants((ValueExpression)ternaryExpression.getLeft()) && hasOnlyConstants((ValueExpression)ternaryExpression.getMiddle()) && hasOnlyConstants((ValueExpression)ternaryExpression.getRight())) { - // left, middle, right are only constants or concatenation of constants - + + // strrep(c1, c2, c3) where c1 or c2 or c3 can be a + // concatenation of constants + if (ternaryExpression.getOperator() instanceof StringReplace + && ternaryExpression.getLeft() instanceof ValueExpression + && ternaryExpression.getMiddle() instanceof ValueExpression + && ternaryExpression.getRight() instanceof ValueExpression + && hasOnlyConstants((ValueExpression) ternaryExpression.getLeft()) + && hasOnlyConstants((ValueExpression) ternaryExpression.getMiddle()) + && hasOnlyConstants((ValueExpression) ternaryExpression.getRight())) { + // left, middle, right are only constants or + // concatenation of constants + List left = extr((ValueExpression) ternaryExpression.getLeft()); left = mergeStringLiterals(left, strType); - if(left.size() != 1 && !(left.get(0) instanceof Constant)) + if (left.size() != 1 && !(left.get(0) instanceof Constant)) throw new SemanticException("unexpected"); - + Constant leftConstant = (Constant) left.get(0); - + List middle = extr((ValueExpression) ternaryExpression.getMiddle()); middle = mergeStringLiterals(middle, strType); - if(middle.size() != 1 && !(middle.get(0) instanceof Constant)) + if (middle.size() != 1 && !(middle.get(0) instanceof Constant)) throw new SemanticException("unexpected"); - + Constant middleConstant = (Constant) middle.get(0); - + List right = extr((ValueExpression) ternaryExpression.getRight()); right = mergeStringLiterals(right, strType); - if(right.size() != 1 && !(right.get(0) instanceof Constant)) + if (right.size() != 1 && !(right.get(0) instanceof Constant)) throw new SemanticException("unexpected"); - + Constant rightConstant = (Constant) right.get(0); - + String s1 = leftConstant.getValue() instanceof String ? (String) leftConstant.getValue() : leftConstant.getValue().toString(); String s2 = middleConstant.getValue() instanceof String ? (String) middleConstant.getValue() : middleConstant.getValue().toString(); String s3 = rightConstant.getValue() instanceof String ? (String) rightConstant.getValue() : rightConstant.getValue().toString(); - + temp.add(new Constant(strType, s1.replace(s2, s3), SyntheticLocation.INSTANCE)); continue; } - // strsub(s1, i1, i2) where s1 can be a concatenation of constants - if (ternaryExpression.getOperator() instanceof StringSubstring && ternaryExpression.getLeft() instanceof ValueExpression && ternaryExpression.getMiddle() instanceof Constant && ternaryExpression.getRight() instanceof Constant && hasOnlyConstants((ValueExpression)ternaryExpression.getLeft()) ) { + // strsub(s1, i1, i2) where s1 can be a concatenation of + // constants + if (ternaryExpression.getOperator() instanceof StringSubstring + && ternaryExpression.getLeft() instanceof ValueExpression + && ternaryExpression.getMiddle() instanceof Constant + && ternaryExpression.getRight() instanceof Constant + && hasOnlyConstants((ValueExpression) ternaryExpression.getLeft())) { List left = extr((ValueExpression) ternaryExpression.getLeft()); left = mergeStringLiterals(left, strType); - if(left.size() != 1 && !(left.get(0) instanceof Constant)) + if (left.size() != 1 && !(left.get(0) instanceof Constant)) throw new SemanticException("unexpected"); - + Constant leftConstant = (Constant) left.get(0); - + String s1 = leftConstant.getValue() instanceof String ? (String) leftConstant.getValue() : leftConstant.getValue().toString(); - Integer i1 = (Integer) ((Constant)ternaryExpression.getMiddle()).getValue(); - Integer i2 = (Integer) ((Constant)ternaryExpression.getRight()).getValue(); - + Integer i1 = (Integer) ((Constant) ternaryExpression.getMiddle()).getValue(); + Integer i2 = (Integer) ((Constant) ternaryExpression.getRight()).getValue(); + temp.add(new Constant(strType, s1.substring(i1, i2), SyntheticLocation.INSTANCE)); continue; } - + } // Split list @@ -653,23 +666,25 @@ private List> split( return result; } - + /* - * - * Returns true iff the parameter is a Constant or a concatenation of Constant values + * Returns true iff the parameter is a Constant or a concatenation of + * Constant values */ - private boolean hasOnlyConstants(ValueExpression expr) { + private boolean hasOnlyConstants( + ValueExpression expr) { if (expr instanceof Constant) return true; - - if (expr instanceof BinaryExpression && ((BinaryExpression)expr).getOperator() instanceof StringConcat) { + + if (expr instanceof BinaryExpression && ((BinaryExpression) expr).getOperator() instanceof StringConcat) { BinaryExpression be = (BinaryExpression) expr; - if(!(be.getLeft() instanceof ValueExpression && be.getRight() instanceof ValueExpression)) + if (!(be.getLeft() instanceof ValueExpression && be.getRight() instanceof ValueExpression)) return false; - - return hasOnlyConstants((ValueExpression) be.getLeft()) && hasOnlyConstants((ValueExpression) be.getRight()); + + return hasOnlyConstants((ValueExpression) be.getLeft()) + && hasOnlyConstants((ValueExpression) be.getRight()); } - + return false; } From 23653e2a3922ee81165eaac513976a14665745bb Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Tue, 9 Jul 2024 16:08:44 +0200 Subject: [PATCH 30/34] Apply spotless --- .../string/StringConstantPropagation.java | 2 +- .../string/SubstringDomainWithConstants.java | 4 +--- .../lisa/analysis/string/SubstringDomainTest.java | 15 +++++++-------- .../it/unive/lisa/cron/StringAnalysesTest.java | 2 -- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index c22a641df..439834d51 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -239,7 +239,7 @@ else if (operator == ComparisonNe.INSTANCE) else return Satisfiability.UNKNOWN; } - + protected String getValue() { return value; } diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java index f2b7e47cc..885dc3420 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomainWithConstants.java @@ -12,7 +12,6 @@ import it.unive.lisa.symbolic.value.ValueExpression; import it.unive.lisa.symbolic.value.operator.binary.StringEquals; import it.unive.lisa.type.Type; - import java.util.Map.Entry; /** @@ -57,7 +56,7 @@ public SubstringDomainWithConstants assign( ProgramPoint pp, SemanticOracle oracle) throws SemanticException { - + // expresson must be a string expression if (oracle != null && pp != null && oracle.getRuntimeTypesOf(expression, pp, oracle).stream() .allMatch(t -> !t.isStringType() && !t.isUntyped())) @@ -81,7 +80,6 @@ public SubstringDomainWithConstants assign( Type strType = pp.getProgram().getTypes().getStringType(); Type boolType = pp.getProgram().getTypes().getBooleanType(); - String stringConstantValue = constantValue.getValue(); Constant constant = new Constant(strType, stringConstantValue, SyntheticLocation.INSTANCE); ValueExpression newExpression = new BinaryExpression(boolType, id, constant, StringEquals.INSTANCE, diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java index e0fce2f63..0a8cd1c02 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/analysis/string/SubstringDomainTest.java @@ -1003,36 +1003,36 @@ public void testExtr5() throws SemanticException { assertTrue(result.getState(x).contains(c)); } - + @Test public void testExtr6() throws SemanticException { Constant AB = new Constant(StringType.INSTANCE, "ab", SyntheticLocation.INSTANCE); Constant CD = new Constant(StringType.INSTANCE, "cd", SyntheticLocation.INSTANCE); ValueExpression ABConcatCD = new BinaryExpression(StringType.INSTANCE, AB, CD, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression one = new Constant(Int16Type.INSTANCE, 1, SyntheticLocation.INSTANCE); ValueExpression three = new Constant(Int16Type.INSTANCE, 3, SyntheticLocation.INSTANCE); ValueExpression substringABCD13 = new TernaryExpression(StringType.INSTANCE, ABConcatCD, one, three, StringSubstring.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, substringABCD13, c, StringConcat.INSTANCE, + ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, substringABCD13, c, + StringConcat.INSTANCE, SyntheticLocation.INSTANCE); SubstringDomain result = new SubstringDomain().assign(x, assignExpr, null, null); - Constant BCC = new Constant(StringType.INSTANCE, "bcc", SyntheticLocation.INSTANCE); assertTrue(result.getState(x).contains(BCC)); } - + @Test public void testExtr7() throws SemanticException { Constant AB = new Constant(StringType.INSTANCE, "ab", SyntheticLocation.INSTANCE); ValueExpression ABConcatY = new BinaryExpression(StringType.INSTANCE, AB, y, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - + ValueExpression one = new Constant(Int16Type.INSTANCE, 1, SyntheticLocation.INSTANCE); ValueExpression three = new Constant(Int16Type.INSTANCE, 3, SyntheticLocation.INSTANCE); ValueExpression assignExpr = new TernaryExpression(StringType.INSTANCE, ABConcatY, one, three, @@ -1042,7 +1042,7 @@ public void testExtr7() throws SemanticException { assertTrue(result.isBottom()); } - + @Test public void testExtr8() throws SemanticException { ValueExpression replaceABAC = new TernaryExpression(StringType.INSTANCE, ab, a, c, StringReplace.INSTANCE, @@ -1051,7 +1051,6 @@ public void testExtr8() throws SemanticException { ValueExpression ABConcatX = new BinaryExpression(StringType.INSTANCE, ab, x, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); - ValueExpression assignExpr = new BinaryExpression(StringType.INSTANCE, replaceABAC, ABConcatX, StringConcat.INSTANCE, SyntheticLocation.INSTANCE); diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index eeb2f0a67..37ad7e412 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -12,8 +12,6 @@ import it.unive.lisa.analysis.string.bricks.Bricks; import it.unive.lisa.analysis.string.fsa.FSA; import it.unive.lisa.analysis.string.tarsis.Tarsis; -import it.unive.lisa.conf.LiSAConfiguration.GraphType; - import org.junit.Test; public class StringAnalysesTest extends AnalysisTestExecutor { From d4597766a2306d8ba24dcc27c9f068a9ac7bcffa Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Tue, 9 Jul 2024 16:45:20 +0200 Subject: [PATCH 31/34] Javadoc --- .../analysis/string/StringConstantPropagation.java | 10 +++++++++- .../unive/lisa/analysis/string/SubstringDomain.java | 11 +++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index 439834d51..55612be3a 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -240,7 +240,15 @@ else if (operator == ComparisonNe.INSTANCE) return Satisfiability.UNKNOWN; } - protected String getValue() { + /** + * Returns the abstract value of the domain + * + * @return The string representing the constant value + */ + protected String getValue() throws SemanticException { + if (isTop() || isBottom()) + throw new SemanticException("The abstract domain is top or bottom; can't get the constant value"); + return value; } } diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index 7fa5a9d67..df3aa0f7b 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -854,6 +854,17 @@ protected SubstringDomain add( return mk(lattice, newFunction); } + /** + * Adds a single expression ({@code expr}) for {@code id} to the this + * abstract value. + * + * @param expr the symbolic expression + * @param id the identifier + * + * @return a new abstract value with the added expression + * + * @throws SemanticException if an error occurs during the computation + */ protected SubstringDomain add( SymbolicExpression expr, Identifier id) From 31301ff4c39be9dbd5aa791501655c71a0817d30 Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Tue, 9 Jul 2024 16:59:00 +0200 Subject: [PATCH 32/34] Javadoc --- .../lisa/analysis/string/StringConstantPropagation.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java index 55612be3a..2f5f9dfd3 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/StringConstantPropagation.java @@ -241,9 +241,12 @@ else if (operator == ComparisonNe.INSTANCE) } /** - * Returns the abstract value of the domain + * Returns the abstract value of the domain. * - * @return The string representing the constant value + * @return the string representing the constant value + * + * @throws SemanticException if the method is called on a top or bottom + * element */ protected String getValue() throws SemanticException { if (isTop() || isBottom()) From b70576a9e50eca22c37aac8cd83fdbcb3f04ce99 Mon Sep 17 00:00:00 2001 From: Michele Martelli Date: Thu, 11 Jul 2024 00:41:23 +0200 Subject: [PATCH 33/34] Test refactoring --- .../{ => subs-domain-constants}/strings-subs-constants.imp | 0 .../imp-testcases/string/{ => subs-domain}/strings-subs.imp | 0 .../src/test/java/it/unive/lisa/cron/StringAnalysesTest.java | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename lisa/lisa-analyses/imp-testcases/string/{ => subs-domain-constants}/strings-subs-constants.imp (100%) rename lisa/lisa-analyses/imp-testcases/string/{ => subs-domain}/strings-subs.imp (100%) diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp b/lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/strings-subs-constants.imp similarity index 100% rename from lisa/lisa-analyses/imp-testcases/string/strings-subs-constants.imp rename to lisa/lisa-analyses/imp-testcases/string/subs-domain-constants/strings-subs-constants.imp diff --git a/lisa/lisa-analyses/imp-testcases/string/strings-subs.imp b/lisa/lisa-analyses/imp-testcases/string/subs-domain/strings-subs.imp similarity index 100% rename from lisa/lisa-analyses/imp-testcases/string/strings-subs.imp rename to lisa/lisa-analyses/imp-testcases/string/subs-domain/strings-subs.imp diff --git a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java index 37ad7e412..b6e1b536d 100644 --- a/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java +++ b/lisa/lisa-analyses/src/test/java/it/unive/lisa/cron/StringAnalysesTest.java @@ -117,7 +117,7 @@ public void testSubstringDomain() { DefaultConfiguration.defaultHeapDomain(), new SubstringDomain(), DefaultConfiguration.defaultTypeDomain()); - conf.testDir = "string"; + conf.testDir = "string/subs-domain"; conf.testSubDir = "subs-domain"; conf.programFile = "strings-subs.imp"; // conf.analysisGraphs = GraphType.DOT; @@ -133,7 +133,7 @@ public void testSubstringDomainWithConstants() { DefaultConfiguration.defaultHeapDomain(), new SubstringDomainWithConstants(), DefaultConfiguration.defaultTypeDomain()); - conf.testDir = "string"; + conf.testDir = "string/subs-domain-constants"; conf.testSubDir = "subs-domain-constants"; conf.programFile = "strings-subs-constants.imp"; // conf.analysisGraphs = GraphType.DOT; From fa84f2dfb3b11a200e66c2c4199dc75a68ebfbcf Mon Sep 17 00:00:00 2001 From: VincenzoArceri Date: Fri, 12 Jul 2024 09:48:34 +0200 Subject: [PATCH 34/34] Minor changes --- .../lisa/analysis/string/SubstringDomain.java | 31 +++---------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java index df3aa0f7b..190ccaf5a 100644 --- a/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java +++ b/lisa/lisa-analyses/src/main/java/it/unive/lisa/analysis/string/SubstringDomain.java @@ -147,17 +147,12 @@ public SubstringDomain assign( strType = expression.getStaticType(); Set expressions = extrPlus(expression, pp, oracle, strType); - SubstringDomain result = mk(lattice, mkNewFunction(function, false)); result = result.remove(expressions, id); - result = result.add(expressions, id); - result = result.interasg(id, expression); - result = result.closure(id); - return result.clear(); } @@ -216,40 +211,26 @@ public SubstringDomain assume( throw new SemanticException("instanceof right"); Set extracted = extrPlus((ValueExpression) right, src, oracle, strType); - SubstringDomain result = mk(lattice, mkNewFunction(function, false)); result = result.add(extracted, (Identifier) left); - result = result.closure(); - return result.clear(); } else if (binaryOperator instanceof StringEquals) { - /* - * Case both operands are identifiers - */ - if ((left instanceof Identifier) && (right instanceof Identifier)) { + // case both operands are identifiers + if ((left instanceof Identifier) && (right instanceof Identifier)) { SubstringDomain result = mk(lattice, mkNewFunction(function, false)); - result = result.add(left, (Identifier) right); result = result.add(right, (Identifier) left); - result = result.closure(); - return result.clear(); } - - /* - * Case where only one is an identifier - */ + // case where only one is an identifier else if ((left instanceof Identifier) || (right instanceof Identifier)) { - if (right instanceof Identifier) { - /* - * Make left the identifier - */ + // make left the identifier SymbolicExpression temp = left; left = right; right = temp; @@ -263,9 +244,7 @@ else if ((left instanceof Identifier) || (right instanceof Identifier)) { SubstringDomain result = mk(lattice, mkNewFunction(function, false)); result = result.add(add, (Identifier) left); - result = result.closure(); - return result.clear(); } @@ -277,7 +256,6 @@ else if ((left instanceof Identifier) || (right instanceof Identifier)) { ValueExpression rightValueExpression = (ValueExpression) right; ValueExpression leftValueExpression = (ValueExpression) left; - SubstringDomain leftDomain = assume(leftValueExpression, src, dest, oracle); SubstringDomain rightDomain = assume(rightValueExpression, src, dest, oracle); @@ -323,7 +301,6 @@ public SubstringDomain forgetIdentifier( // != // null newFunction.remove(id); - newFunction.replaceAll(( key, value) -> removeFromSet(value, id));