package tracematches; import java.util.*; public aspect FailSafeEnum { pointcut vector_update() : call(* Vector.add*(..)) || call(* Vector.clear()) || call(* Vector.insertElementAt(..)) || call(* Vector.remove*(..)) || call(* Vector.retainAll(..)) || call(* Vector.set*(..)); tracematch(Vector ds, Enumeration e) { sym create_enum after returning(e) : (call(* Vector+.elements()) && target(ds)) || (call(Enumeration+.new(..)) && args(ds)); sym call_next before : call(Object Enumeration.nextElement()) && target(e); sym update_source after : vector_update() && target(ds); create_enum call_next* update_source+ call_next { if(System.getProperty("TMTEST_ACTIVE")!=null) { throw new ConcurrentModificationException(); } } } public static void main(String[] args) { //need flow information Vector c1 = new Vector(); //safe c1.add(""); //safe for (Enumeration iter = c1.elements(); iter.hasMoreElements();) { //do something iter.nextElement(); } Vector c2 = new Vector(); //safe c2.add(""); //unsafe Enumeration iterator = c2.elements(); iterator.nextElement(); c2.add(""); iterator.nextElement(); } }