Skip to content

Commit ad56283

Browse files
committed
Collapsed messages of integer overflow and underflow
1 parent b29faf6 commit ad56283

File tree

1 file changed

+55
-37
lines changed

1 file changed

+55
-37
lines changed

go-lisa/src/main/java/it/unive/golisa/checker/NumericalOverflowOfVariablesChecker.java

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -63,32 +63,38 @@ public void afterExecution(
6363
CheckToolWithAnalysisResults<SimpleAbstractState<PointBasedHeap, ValueEnvironment<Interval>, TypeEnvironment<InferredTypes>>> tool) {
6464
// TODO: add a smart way to trigger warnings
6565
for(IssueInfo issue : detectedIssues) {
66-
tool.warnOn(issue.getStatement(), getWarningMessage(issue.getIssue()));
66+
tool.warnOn(issue.getStatement(), getWarningMessage(issue.getIssues()));
6767
}
6868
}
6969

70-
private String getWarningMessage(NumericalIssue numericalIssue) {
70+
private String getWarningMessage(Set<NumericalIssue> numericalIssues) {
7171

7272
String res ="";
73-
switch(numericalIssue) {
74-
case OVERFLOW:
75-
res = "an integer overflow occurs";
76-
break;
77-
case MAY_OVERFLOW:
78-
res = "an integer overflow may occur";
79-
break;
80-
case UNDERFLOW:
81-
res = "an integer underflow occurs";
82-
break;
83-
case MAY_UNDERFLOW:
84-
res = "an integer underflow may occur";
85-
break;
86-
default:
87-
new IllegalArgumentException("Message for the numerical issue "+ numericalIssue +" not implemented yet!");
88-
73+
int i = 0;
74+
for(NumericalIssue ni : numericalIssues) {
75+
if(i > 0)
76+
res += " and ";
77+
switch(ni) {
78+
case OVERFLOW:
79+
res += "an integer overflow occurs";
80+
break;
81+
case MAY_OVERFLOW:
82+
res += "an integer overflow may occur";
83+
break;
84+
case UNDERFLOW:
85+
res += "an integer underflow occurs";
86+
break;
87+
case MAY_UNDERFLOW:
88+
res += "an integer underflow may occur";
89+
break;
90+
default:
91+
new IllegalArgumentException("Message for the numerical issue "+ ni +" not implemented yet!");
92+
93+
}
94+
i++;
8995
}
9096

91-
return "Detected numerical issue: " + res;
97+
return "Detected numerical issues: " + res;
9298
}
9399

94100
@Override
@@ -188,27 +194,36 @@ private void checkVariableRef(CheckToolWithAnalysisResults<SimpleAbstractState<P
188194
if(!intervalAbstractValue.isBottom()) {
189195
IntInterval interval = intervalAbstractValue.interval;
190196

191-
checkOverflow(tool, node, interval, numericalTypes);
192-
checkUnderflow(tool,node, interval, numericalTypes);
197+
NumericalIssue overflow = checkOverflow(tool, node, interval, numericalTypes);
198+
NumericalIssue underflow = checkUnderflow(tool,node, interval, numericalTypes);
199+
200+
if(overflow != null || underflow != null) {
201+
IssueInfo info = new IssueInfo(node, new HashSet<>());
202+
if(overflow != null)
203+
info.getIssues().add(overflow);
204+
if(underflow != null)
205+
info.getIssues().add(underflow);
206+
detectedIssues.add(info);
207+
}
193208
}
194209
}
195210

196211

197212
}
198213

199-
private void checkOverflow(
214+
private NumericalIssue checkOverflow(
200215
CheckToolWithAnalysisResults<SimpleAbstractState<PointBasedHeap, ValueEnvironment<Interval>, TypeEnvironment<InferredTypes>>> tool,
201216
Statement node, IntInterval interval, Set<Type> numericalTypes) {
202217
Type[] arrayTypes = numericalTypes.toArray(new Type[] {});
203218
if(!numericalTypes.isEmpty())
204219
if(numericalTypes.size() == 1) {
205220
if(isOverflow(interval, arrayTypes[0]))
206-
detectedIssues.add(new IssueInfo(node, NumericalIssue.OVERFLOW));
221+
return NumericalIssue.OVERFLOW;
207222
} else {
208223
if(isOverflow(interval, getWorstCaseTypeForOverflow(numericalTypes)))
209-
detectedIssues.add(new IssueInfo(node, NumericalIssue.MAY_OVERFLOW));
224+
return NumericalIssue.MAY_OVERFLOW;
210225
}
211-
226+
return null;
212227
}
213228

214229
private Type getWorstCaseTypeForOverflow(Set<Type> numericTypes) {
@@ -231,18 +246,20 @@ private boolean isOverflow(IntInterval interval, Type vType) {
231246

232247
}
233248

234-
private void checkUnderflow(
249+
private NumericalIssue checkUnderflow(
235250
CheckToolWithAnalysisResults<SimpleAbstractState<PointBasedHeap, ValueEnvironment<Interval>, TypeEnvironment<InferredTypes>>> tool,
236251
Statement node, IntInterval interval, Set<Type> numericalTypes) {
237252
Type[] arrayTypes = numericalTypes.toArray(new Type[] {});
238-
if(!numericalTypes.isEmpty())
253+
if(!numericalTypes.isEmpty()) {
239254
if(numericalTypes.size() == 1) {
240255
if(isUnderflow(interval, arrayTypes[0]))
241-
detectedIssues.add(new IssueInfo(node, NumericalIssue.UNDERFLOW));
256+
return NumericalIssue.UNDERFLOW;
242257
} else {
243258
if(isUnderflow(interval, getWorstCaseTypeForUnderflow(numericalTypes)))
244-
detectedIssues.add(new IssueInfo(node, NumericalIssue.MAY_UNDERFLOW));
245-
}
259+
return NumericalIssue.MAY_UNDERFLOW;
260+
}
261+
}
262+
return null;
246263
}
247264

248265
private Type getWorstCaseTypeForUnderflow(Set<Type> numericTypes) {
@@ -355,27 +372,28 @@ class IssueInfo {
355372

356373

357374
private final Statement statement;
358-
private final NumericalIssue issue;
375+
private final Set<NumericalIssue> issues;
359376

360-
public IssueInfo(Statement statement, NumericalIssue issue) {
377+
public IssueInfo(Statement statement, Set<NumericalIssue> issues) {
361378
this.statement = statement;
362-
this.issue = issue;
379+
this.issues = issues;
363380
}
364381

365382
public Statement getStatement() {
366383
return statement;
367384
}
368385

369-
public NumericalIssue getIssue() {
370-
return issue;
386+
public Set<NumericalIssue> getIssues() {
387+
return issues;
371388
}
372389

390+
373391
@Override
374392
public int hashCode() {
375393
final int prime = 31;
376394
int result = 1;
377395
result = prime * result + getEnclosingInstance().hashCode();
378-
result = prime * result + Objects.hash(issue, statement);
396+
result = prime * result + Objects.hash(issues, statement);
379397
return result;
380398
}
381399

@@ -390,7 +408,7 @@ public boolean equals(Object obj) {
390408
IssueInfo other = (IssueInfo) obj;
391409
if (!getEnclosingInstance().equals(other.getEnclosingInstance()))
392410
return false;
393-
return issue == other.issue && Objects.equals(statement, other.statement);
411+
return Objects.equals(issues, other.issues) && Objects.equals(statement, other.statement);
394412
}
395413

396414
private NumericalOverflowOfVariablesChecker getEnclosingInstance() {

0 commit comments

Comments
 (0)