@@ -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