Beispiel #1
0
void RDAnalyzer::transfer_assignment(SgAssignOp* node, Label& lab, RDLattice& element) {
    // update analysis information
    // this is only correct for RERS12-C programs
    // 1) remove all pairs with lhs-variableid
    // 2) add (lab,lhs.varid)
    
    // (for programs with pointers we require a set here)
#if 1
  // TODO: USEDEF FUNCTIONS HERE (ACTIVATE)
  VariableIdSet lhsVarIds=AnalysisAbstractionLayer::defVariablesInExpression(node,_variableIdMapping);  
#else
    VariableIdSet lhsVarIds=determineLValueVariableIdSet(SgNodeHelper::getLhs(node));
#endif
  if(lhsVarIds.size()>1) {
      // since multiple memory locations may be modified, we cannot know which one will be updated and can only add information
      for(VariableIdMapping::VariableIdSet::iterator i=lhsVarIds.begin();i!=lhsVarIds.end();++i) {
        element.insertPair(lab,*i);
      }
    } else if(lhsVarIds.size()==1) {
      // one unique memory location (variable). We can remove all pairs with this variable
      VariableId var=*lhsVarIds.begin();
      element.eraseAllPairsWithVariableId(var);
      element.insertPair(lab,var);
    }
}
Beispiel #2
0
// TODO: refactor in separate functions
RDLattice RDAnalyzer::transfer(Label lab, RDLattice element) {
  if(element.isBot())
	element.setEmptySet();
  SgNode* node=_labeler->getNode(lab);
  //cout<<"Analyzing:"<<node->class_name()<<endl;

  ///////////////////////////////////////////
  // remove undeclared variable at function exit
  if(_labeler->isFunctionExitLabel(lab)) {
	if(SgFunctionDefinition* funDef=isSgFunctionDefinition(_labeler->getNode(lab))) {
	  // 1) determine all local variables (including formal parameters) of function
	  // 2) delete all local variables from state
	  // 2a) remove variable from state
	  
	  // ad 1)
	  set<SgVariableDeclaration*> varDecls=SgNodeHelper::localVariableDeclarationsOfFunction(funDef);
	  // ad 2)
	  VariableIdMapping::VariableIdSet localVars=_variableIdMapping.determineVariableIdsOfVariableDeclarations(varDecls);
	  SgInitializedNamePtrList& formalParamInitNames=SgNodeHelper::getFunctionDefinitionFormalParameterList(funDef);
	  VariableIdMapping::VariableIdSet formalParams=_variableIdMapping.determineVariableIdsOfSgInitializedNames(formalParamInitNames);
	  VariableIdMapping::VariableIdSet vars=localVars+formalParams;
	  for(VariableIdMapping::VariableIdSet::iterator i=vars.begin();i!=vars.end();++i) {
		VariableId varId=*i;
		element.eraseAllPairsWithVariableId(varId);
	  }
	  return element;
	}
  }
  ///////////////////////////////////////////
  
  if(isSgExprStatement(node))
	node=SgNodeHelper::getExprStmtChild(node);

  if(SgAssignOp* assignOp=isSgAssignOp(node)) {
	transfer_assignment(assignOp,lab,element);
  }
#if 0
  cout << "RDAnalyzer: called transfer function. result: ";
  element.toStream(cout,&_variableIdMapping);
  cout<<endl;
#endif
  return element;
}
Beispiel #3
0
void checkTypes() {
  VariableIdMapping variableIdMapping;
  PState s1;
  cout << "RUNNING CHECKS:"<<endl;
  {
    // check temporary variables (create and delete)
    VariableId var_tmp=variableIdMapping.createUniqueTemporaryVariableId("tmp");
    variableIdMapping.deleteUniqueTemporaryVariableId(var_tmp);
  }

  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR BOOLLATTICE TYPE:"<<endl;
    AType::BoolLattice a;
    a=true;
    check("a=true => isTrue",a.isTrue());
    AType::BoolLattice b;
    b=false;
    check("b=false => isFalse",b.isFalse());
    AType::BoolLattice c=a||b;
    check("c=a||b => c isTrue ",c.isTrue());
    AType::Top e;
    AType::BoolLattice d;
    d=e;
    check("Top e; d=e => d isTop",d.isTop());
    c=c||d;
    check("c=c||d: true",c.isTrue());
    AType::BoolLattice f=AType::Bot();
    d=AType::Bot();
    check("d=bot: bot",d.isBot());
    check("f=bot: bot",f.isBot());
    a=d&&f;
    check("a=d&&f => a isBot",a.isBot());
    f=false;
    check("f=false => f isFalse",f.isFalse());
    a=d&&f;
    check("a=d&&f: a isFalse (we define it this way)",a.isFalse());
  }

  {
    cout << "RUNNING CHECKS FOR CONSTINT LATTICE TYPE:"<<endl;
    AType::ConstIntLattice a;
    a=true;
    check("a=true => isTrue",a.isTrue());
    check("a=true => !isFalse",!a.isFalse());
    AType::ConstIntLattice b;
    b=false;
    check("b=false => isFalse",b.isFalse());
    check("b=false => !isTrue",!b.isTrue());
    AType::ConstIntLattice c=a.operatorOr(b);
    check("c=a.operatorOr(b): ",c.isTrue());
    AType::Top e;
    AType::ConstIntLattice d;
    d=e;
    check("Top e; d=e; d isTop ",d.isTop());
    c=c.operatorOr(d);
    check("c=c.operatorOr(d) => c isTrue ",c.isTrue());
    AType::ConstIntLattice f=AType::Bot();
    d=AType::Bot();
    
    a=d.operatorAnd(f);
    check("d=bot;f=bot;a=d.operatorAnd(f); => a isBot",a.isBot());
    f=false;
    a=d.operatorAnd(f);
    check("f=false; a=d.operatorAnd(f); => a isFalse",a.isFalse());
    a=5;
    check("a=5; a.isTrue()==true",a.isTrue()==true);
    check("a=5; a.isFalse()==false",a.isFalse()==false);

    a=0;
    check("a=0; a.isTrue()==false",a.isTrue()==false);
    check("a=0; a.isFalse())==true",a.isFalse()==true);
  }

  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR CONSTRAINT TYPE:"<<endl;
    VariableId var_x=variableIdMapping.createUniqueTemporaryVariableId("x");
    VariableId var_y=variableIdMapping.createUniqueTemporaryVariableId("y");
    cout << "P1"<<endl;
    Constraint c1(Constraint::EQ_VAR_CONST,var_x,1);
    cout << "P2"<<endl;
    Constraint c2(Constraint::NEQ_VAR_CONST,var_y,2);
    cout << "P3"<<endl;
    Constraint c3=DISEQUALITYCONSTRAINT;
    cout << "P4"<<endl;
    Constraint c4=Constraint(Constraint::EQ_VAR_CONST,var_y,2);
    cout << "P5"<<endl;
    ConstraintSet cs;
    cout << "P6"<<endl;
    cs.addConstraint(c1);
    cout << "P7"<<endl;
    cout << "CS1:"<<cs.toString()<<endl;
    cs.addConstraint(c2);
    cout << "CS2:"<<cs.toString()<<endl;
    check("inserted 2 different constraints, size of constraint set == 3",cs.size()==2);
    check("c1:constraintExists(EQ_VAR_CONST,x,1) == true",cs.constraintExists(Constraint::EQ_VAR_CONST,var_x,1));
    check("c1:constraintExists(NEQ_VAR_CONST,x,1) == false",!cs.constraintExists(Constraint::NEQ_VAR_CONST,var_x,1));
    check("c2:constraintExists(NEQ_VAR_CONST,y,2) == true",cs.constraintExists(Constraint::NEQ_VAR_CONST,var_y,2));
    check("c3:isDisequality==false",cs.disequalityExists()==false);
    cout << "CS3:"<<cs.toString()<<endl;
    cs.addConstraint(c4);
    cout << "CS4:"<<cs.toString()<<endl;
    cout << "P8"<<endl;
    //cout << "CS:"<<cs.toString()<<endl;
    check("insert y==2; => disequalityExists() == true",cs.disequalityExists());
    cout << "P9"<<endl;
    cs.addConstraint(c3);
    check("added disequality => disequalityExists() == true",cs.disequalityExists());
    check("Disequality exists <=> size()==1",cs.size()==1);
    check("c1!=c2",c1!=c2);
    check("c1!=c3",c1!=c3);
    check("c2!=c3",c2!=c3);

    {
      // check for equalities 
      {
        Constraint c1(Constraint::EQ_VAR_CONST,var_x,1);
        Constraint c2=Constraint(Constraint::EQ_VAR_CONST,var_y,2);
        ConstraintSet cs1;
        cs1.addConstraint(c1);
        cs1.addConstraint(c2);
        Constraint c5(Constraint::EQ_VAR_VAR,var_x,var_y);
        cs1.addConstraint(c5);
        check("cs1.disequalityExists()==true",cs1.disequalityExists());
      }
      {
        Constraint c1(Constraint::NEQ_VAR_CONST,var_x,1);
        Constraint c2=Constraint(Constraint::NEQ_VAR_CONST,var_x,2);
        Constraint c3=Constraint(Constraint::NEQ_VAR_CONST,var_y,3);
        ConstraintSet cs1;
        cs1.addConstraint(c1);
        cs1.addConstraint(c2);
        cs1.addConstraint(c3);
        Constraint c5(Constraint::EQ_VAR_VAR,var_x,var_y);
        cs1.addConstraint(c5);
        check("c5:constraintExists(EQ_VAR_VAR,x,y) == true",cs1.constraintExists(Constraint(Constraint::EQ_VAR_VAR,var_x,var_y)));    

        check("c1:constraintExists(EQ_VAR_CONST,x,1) == false",cs1.constraintExists(Constraint::EQ_VAR_CONST,var_x,1)==false);
        check("c1:constraintExists(NEQ_VAR_CONST,x,1) == true",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_x,1)==true);
        check("c1:constraintExists(EQ_VAR_CONST,y,2) == false",cs1.constraintExists(Constraint::EQ_VAR_CONST,var_y,2)==false);
        check("c1:constraintExists(NEQ_VAR_CONST,y,2) == true",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_y,2)==true);
        cs1.removeAllConstraintsOfVar(var_x);
        cs1.removeAllConstraintsOfVar(var_y);
        cs1.removeAllConstraintsOfVar(var_x);
      }
    }
    ConstraintSet cs1;
    cs1.addConstraint(c1);
    ConstraintSet cs2;
    cs2.addConstraint(c2);
    check("cs1!=cs2)",cs1!=cs2);

    {
      Constraint c1(Constraint::NEQ_VAR_CONST,var_y,1);
      Constraint c2(Constraint::NEQ_VAR_CONST,var_y,3);
      Constraint c3(Constraint::NEQ_VAR_CONST,var_y,5);
      Constraint c4a(Constraint::EQ_VAR_CONST,var_y,6);
      Constraint c4b(Constraint::EQ_VAR_CONST,var_y,3);
      ConstraintSet cs1;
      ConstraintSet cs2;
      PState s;
      cs1.addConstraint(c1);
      cs1.addConstraint(c2);
      cs1.addConstraint(c3);
      cs2.addConstraint(c1);
      cs2.addConstraint(c3);
      check("cs1!=cs2",cs1!=cs2);
      check("!(cs1==cs2)",!(cs1==cs2));
      check("!(cs1<cs2)",!(cs1<cs2));
      check("cs1>cs2",(cs2<cs1));
      EStateSet es;
      EState es1=EState(1,&s,&cs1);
      es.processNewOrExisting(es1);
      EState es2=EState(1,&s,&cs2);
      es.processNewOrExisting(es2);
      check("es.size()==2",es.size()==2);
      {
      Constraint c5(Constraint::EQ_VAR_CONST,var_y,10);
      cs1.addConstraint(c5);
      check("constraintExists(NEQ_VAR_CONST,y,1) == false",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_y,1)==false);
      check("constraintExists(NEQ_VAR_CONST,y,3) == false",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_y,3)==false);
      check("constraintExists(NEQ_VAR_CONST,y,5) == false",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_y,5)==false);
      check("cs1.size()==1",cs1.size()==1);
      }
    }
  }
  {  
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR CONSTINTLATTICE (formerly CPPCAPSULE):"<<endl;
    AType::ConstIntLattice cint1(1);
    check("cint1 == 1",cint1.getIntValue()==1);
    AType::ConstIntLattice cint2=AType::Top();
    AType::ConstIntLattice cint3;
    cint3=AType::Top();
    check("cint2 isTop",cint2.isTop());
    check("cint3 isTop",cint3.isTop());
    check("!(cint1 == cint3)",!(cint1==cint3)); // strictly weak ordering test
    check("cint2 == cint3",cint2==cint3); // strictly weak ordering test
  }
  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR PSTATE AND PSTATESET:"<<endl;
    VariableIdMapping variableIdMapping;
    EState es1;
    EState es2;
    PState s0;
    PState s1;
    PState s2;
    PState s3;
    PState s5;
    AValue valtop=AType::Top();
    AValue val1=500;
    AValue val2=501;
    PStateSet pstateSet;
    VariableId x=variableIdMapping.createUniqueTemporaryVariableId("x");
    VariableId y=variableIdMapping.createUniqueTemporaryVariableId("y");
    check("var x not in pstate1",s1.varExists(x)==false);
    check("var y not in pstate2",s2.varExists(y)==false);
    s1[x]=val1;
    s2[y]=val2;
    s3[x]=val2;
    s5[x]=valtop;
    s5[y]=valtop;
    check("var x exists in pstate s1",s1.varExists(x)==true);
    check("var x==500",((s1[x].operatorEq(val1)).isTrue())==true);
    check("var y exists in pstate s2",s2.varExists(y)==true);
    check("var y==501",((s2[y].operatorEq(val2)).isTrue())==true);
    //check("s0 < s1",(s0<s1)==true);
    //check("s0 < s2",(s0<s2)==true);
    check("!(s1 == s2)",(s1==s2)==false);
    check("s1<s2 xor s2<s1)",(s1<s2)^(s2<s1));
    check("var x in pstate s3",s3.varExists(x)==true);
    check("s3[x]==501",((s3[x].operatorEq(val2)).isTrue())==true);
    check("!(s1==s2)",(!(s1==s2))==true);
    check("!(s1==s3)",(!(s1==s3))==true);
    check("!(s2==s3)",(!(s2==s3))==true);
    PState s4=s1;
    check("s1==s4",(s1==s4)==true);

    s1[x]=val2;
    check("s1.size()==1",s1.size()==1);

    pstateSet.process(s0);
    check("empty pstate s0 inserted in pstateSet => size of pstateSet == 1",pstateSet.size()==1);
    pstateSet.process(s1);
    check("s1 inserted in pstateSet => size of pstateSet == 2",pstateSet.size()==2);
    pstateSet.process(s1);
    check("s1 reinserted in pstateSet => size remains the same",pstateSet.size()==2);
    pstateSet.process(s2);
    check("s2 inserted => size of pstateSet == 3",pstateSet.size()==3);

    const PState* pstateptr0=pstateSet.processNewOrExisting(s0); // version 1
    check("obtain pointer to s0 from pstateSet and check !=0",pstateptr0!=0);
    check("check pointer refers indeed to s0 (operator==)",(*pstateptr0)==s0);
    const PState* pstateptr1=pstateSet.processNewOrExisting(s1); // version 1
    check("obtain pointer to s1 from pstateSet and check !=0",pstateptr1!=0);
    const PState* pstateptr2=pstateSet.processNewOrExisting(s2); // version 1
    check("obtain pointer to s2 from pstateSet and check !=0",pstateptr2!=0);
    check("check pstate.exists(s0)",pstateSet.exists(s0));
    check("check pstate.exists(s1)",pstateSet.exists(s1));
    check("check pstate.exists(s2)",pstateSet.exists(s2));
    check("check !pstate.exists(s5) [s5 does not exist]",!pstateSet.exists(s5));
    check("constint-strictWeak-equality-1",strictWeakOrderingIsEqual(val1,val2)==false);
    check("constint-strictWeak-smaller-1",strictWeakOrderingIsSmaller(val1,val2)==true);

    s4[x]=valtop;
    check("created s4; inserted x=top; s4[x].isTop",s4[x].isTop());    
    pstateSet.processNewOrExisting(s4);
    check("inserted s4 => size of pstateSet == 4",pstateSet.size()==4);    
    const PState* pstateptr4=pstateSet.processNewOrExisting(s4); // version 1
    check("obtain pointer to s4 from pstateSet and check !=0",pstateptr4!=0);

#if 1
    EStateSet eStateSet;
    EState es3;
    ConstraintSetMaintainer csm;

    ConstraintSet cs1;
    cs1.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,x,1));
    const ConstraintSet* cs1ptr=csm.processNewOrExisting(cs1);
    es1=EState(1,pstateptr1,cs1ptr);
    
    ConstraintSet cs2;
    cs2.addConstraint(Constraint(Constraint::EQ_VAR_CONST,x,1));
    const ConstraintSet* cs2ptr=csm.processNewOrExisting(cs2);
    es2=EState(1,pstateptr1,cs2ptr);

    ConstraintSet cs3;
    cs3.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,x,1));
    const ConstraintSet* cs3ptr=csm.processNewOrExisting(cs3);
    es3=EState(3,pstateptr4,cs3ptr);

    check("check es1 does not exist in eStateSet",eStateSet.exists(es1)==0);
    check("check es2 does not exist in eStateSet",eStateSet.exists(es2)==0);
    check("check es3 does not exist in eStateSet",eStateSet.exists(es3)==0);

    check("es1!=es2",es1!=es2);
    check("es2!=es3",es1!=es3);
    check("es1!=es3",es2!=es3);
#ifdef ESTATE_MAINTAINER_LIST
    nocheck("es1<es2",es2<es1);
    nocheck("!(es2<es1)",!(es1<es2));
#endif
#ifdef ESTATE_MAINTAINER_SET
    check("es1<es2",es1<es2);
    check("!(es2<es1)",!(es2<es1));
#endif

    check("!(es1==es2)",!(es1==es2));

#ifdef ESTATE_MAINTAINER_LIST
    nocheck("es1<es3",es1<es3);
    nocheck("es2<es3",es2<es3);
#endif
#ifdef ESTATE_MAINTAINER_SET
    check("es1<es3",es1<es3);
    check("es2<es3",es2<es3);
#endif

    check("es2==es2",es2==es2);
    check("=> eStateSet.size() == 0",eStateSet.size() == 0);

    check("es1 does not exist in eStateSet",!eStateSet.exists(es2));
    eStateSet.processNewOrExisting(es1);
    const EState* estateptr1=eStateSet.processNewOrExisting(es1);
    check("add es1 and obtain pointer to es1 from eStateSet and check !=0",estateptr1!=0);
    check("es1 exists in eStateSet",eStateSet.exists(es1));
    check("=> eStateSet.size() == 1",eStateSet.size() == 1);

    check("es2 does not exist in eStateSet",!eStateSet.exists(es2));
    eStateSet.processNewOrExisting(es2);
    const EState* estateptr2=eStateSet.processNewOrExisting(es2);
    check("add es2 and obtain pointer to es2 from eStateSet and check !=0",estateptr2!=0);
    check("es2 exists in eStateSet",eStateSet.exists(es2));
    check("=> eStateSet.size() == 2",eStateSet.size() == 2);

    check("es3 does not exist in eStateSet",!eStateSet.exists(es3));
    eStateSet.processNewOrExisting(es3);
    const EState* estateptr3=eStateSet.processNewOrExisting(es3);
    check("add es3 and obtain pointer to es3 from eStateSet and check !=0",estateptr3!=0);
    check("es3 exists in eStateSet",eStateSet.exists(es3));
    check("=> eStateSet.size() == 3",eStateSet.size() == 3);
    checkLargeSets();
#endif
 }
#if 0
  // MS: TODO: rewrite the following test to new check format
  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR COMBINED TYPES:"<<endl;
    EState es1;
    EState es2;
    cout << "EState created. "<<endl;
    cout << "empty EState: "<<es1.toString()<<endl;
    es1.setLabel(1);
    VariableId var_x=variableIdMapping.createUniqueTemporaryVariableId("x");
    es1.constraints.addConstraint(Constraint(Constraint::EQ_VAR_CONST,var_x,1));
    es2.setLabel(1);
    es2.constraints.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,var_x,1));
    cout << "empty EState with label and constraint es1: "<<es1.toString()<<endl;
    cout << "empty EState with label and constraint es2: "<<es2.toString()<<endl;
    PState s;
    es1.setPState(&s);
    es2.setPState(&s);
    cout << "empty EState with label, empty pstate, and constraint es1: "<<es1.toString()<<endl;
    cout << "empty EState with label, empty pstate, and constraint es2: "<<es2.toString()<<endl;
    bool testres=(es1==es2);
    if(testres)
      cout << "es1==es2: "<<testres<< "(not as expected: FAIL)"<<endl;
    else
      cout << "es1==es2: "<<testres<< "(as expected: PASS)"<<endl;
  }
#endif

  // check stream operators
  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR INPUT/OUTPUT STREAM OPs"<<endl;

    stringstream ss2;
    ss2<<"test1";
    check("Parse: Testing test2 on test1.",!SPRAY::Parse::checkWord("test2",ss2));
    //cout << "Remaing stream: "<<ss2.str()<<endl;
    stringstream ss3;
    ss3<<"test1";
    check("Parse: Testing test1 on test1.",SPRAY::Parse::checkWord("test1",ss3));
    //cout << "Remaing stream: "<<ss3.str()<<endl;

    CodeThorn::AType::ConstIntLattice x;
    stringstream ss4;
    ss4<<"top";
    x.fromStream(ss4);
    check("ConstIntLattice: streaminput: top",x.toString()=="top");
    stringstream ss5;
    ss5<<"12";
    x.fromStream(ss5);
    check("ConstIntLattice: streaminput: 12",x.toString()=="12");
    stringstream ss6;
    ss6<<"15top16";
    ss6>>x;
    check("ConstIntLattice: streaminput: 15",x.toString()=="15");
    ss6>>x;
    check("ConstIntLattice: streaminput: top",x.toString()=="top");
    ss6>>x;
    check("ConstIntLattice: streaminput: 16",x.toString()=="16");

    {
      PState ps;
      stringstream ss1;
      string pstateString="{}";
      ss1<<pstateString;
      ps.fromStream(ss1);
      string checkString=(string("stream input PState: ")+pstateString);
      bool checkresult=(ps.toString()==pstateString);
      check(checkString,checkresult);
      if(checkresult==false) {
        cout << "Error: input stream result: "<<ps.toString()<<endl;
      }
    }
    {
      PState ps;
      stringstream ss0;
      string pstateString="{(V0,5),(V1,top),(V2,bot)}";
      ss0<<pstateString;
      ss0>>ps;
      string checkString=(string("stream input PState: ")+pstateString);
      bool checkresult=(ps.toString()==pstateString);
      check(checkString,checkresult);
      if(checkresult==false) {
        cout << "pstateString :"<<pstateString<<":"<<endl;
        cout << "ps.toString():"<<ps.toString()<<":"<<endl;
      }
    }
    {
      stringstream ss;
      string s="aaabbb";
      ss<<s;
      string parseString="aaa";
      SPRAY::Parse::parseString(parseString,ss); // throws exception if it fails
      char next;
      ss>>next;
      check(string("Parsing: ")+parseString+" from:"+s+" Next:"+next,true);      
    }
    {
      Constraint cs;
      stringstream ss;
      stringstream ssout;
      string cstring="V1==V2";
      ss<<cstring;
      cs.fromStream(ss);
      cs.toStream(ssout);
      check("Stream I/O constraint: "+cstring,ssout.str()==cstring);
    }
    {
      Constraint cs;
      stringstream ss;
      stringstream ssout;
      string cstring="V3!=4";
      ss<<cstring;
      cs.fromStream(ss);
      cs.toStream(ssout);
      check("Stream I/O constraint: "+cstring,ssout.str()==cstring);
    }
    {
      Constraint cs;
      cs=DISEQUALITYCONSTRAINT;
      stringstream ss;
      stringstream ssout;
      string cstring=cs.toString();
      ss<<cstring;
      cs.fromStream(ss);
      cs.toStream(ssout);
      check("Stream I/O DEQ constraint: "+cstring,ssout.str()==cstring);
    }
#ifndef EXCLUDE_RDANALYSIS
    {
      RDLattice a;
      VariableId var1;
      var1.setIdCode(1);
      VariableId var2;
      var2.setIdCode(2);
      a.insertPair(1,var1);
      RDLattice b;
      b.insertPair(1,var1);
      b.insertPair(2,var2);
      //a.toStream(cout);cout<<endl;
      //b.toStream(cout);cout<<endl;
      check("a ApproximatedBy b",a.approximatedBy(b)==true);
      check("not (b ApproximatedBy a)",b.approximatedBy(a)==false);
    }
#endif
  } // end of stream operator checks
}