int tao_consistency_check(taoNodeRoot * root, std::ostream * msg)
  {
    if (root->getID() != -1) {
      if (msg) {
	*msg << "jspace::tao_consistency_check(): root has ID " << root->getID() << " instead of -1\n";
      }
      return 1;
    }
    id_counter_t id_counter;
    for (taoDNode * node(root->getDChild()); 0 != node; node = node->getDSibling()) {
      tao_collect_ids(node, id_counter);
    }
    int expected_id(0);
    for (id_counter_t::const_iterator idc(id_counter.begin()); idc != id_counter.end(); ++idc, ++expected_id) {
      if (idc->first != expected_id) {
	if (msg) {
	  *msg << "jspace::tao_consistency_check(): ID gap, expected "
	       << expected_id << " but encountered " << idc->first << "\n";
	}
	return 2;
      }
      if (1 != idc->second) {
	if (msg) {
	  *msg << "jspace::tao_consistency_check(): duplicate ID " << idc->first << "\n";
	}
	return 3;
      }
    }
    return 0;
  }
int test22(int *q, int *x) {
  idc(q);
	if (x)
		;
	int *p = q;
	return *p;
}
int test02(int *p, int *x) {
  if (p)
    ;
  idc(p);
	if (x)
		;
  return *p; // expected-warning {{Dereference of null pointer}}
}
int test23(int *q, int *x) {
  idc(q);
	if (x)
		;
	int *p = q;
  if (!p)
    ;
	return *p; // False negative
}
 static void tao_collect_ids(taoDNode * node, id_counter_t & id_counter)
 {
   int const id(node->getID());
   id_counter_t::iterator idc(id_counter.find(id));
   if (id_counter.end() == idc) {
     id_counter.insert(std::make_pair(id, 1));
   }
   else {
     ++idc->second;
   }
   for (taoDNode * child(node->getDChild()); 0 != child; child = child->getDSibling()) {
     tao_collect_ids(child, id_counter);
   }
 }
int test13(int *q) {
	int *p = q;
	idc(p);
	return *p;
}
int test12(int *q) {
	int *p = q;
	idc(q);
	return *p;
}
int test04(int *p) {
  if (p)
    ;
  idc(p);
  return deref04(p);
}
int test03(int *p, int *x) {
	idc(p);
	if (p)
		;
	return *p; // False negative
}
void test(int *p1, int *p2) {
  idc(p1);
	Foo f(p1);
}
void idcTrackConstraintThroughSymbolicRegionAndParens(int **x) {
  idc(*x);
  // FIXME: Should not warn.
  *(*x) = 7; // expected-warning{{Dereference of null pointer}}
}
void idcTrackZeroValueThroughUnaryPointerOperatorsWithArrayField(struct S2 *s) {
  idc(s);
  *(&(s->a[0])) = 7; // no-warning
}
void idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S *s) {
  idc(s);
  int *x = &(s->f1);
  *x = 7; // no-warning
}
void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset2(struct S *s) {
  idc(s);
  int *x = &(s->f2) - 1;
  // FIXME: Should not warn.
  *x = 7; // expected-warning{{Dereference of null pointer}}
}
void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset1(struct S *s) {
  idc(s);
  int *x = &(s->f2);
  *x = 7; // no-warning
}
void idcTrackZeroValueThroughUnaryPointerOperators(struct S *s) {
  idc(s);
  *(&(s->f1)) = 7; // no-warning
}
 B testidc(B *x) {
   idc(x);
   return *x; // no-warning
 }
void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S *s) {
  idc(s);
  int *x = &*&((++s)->f1);
  *x = 7; // no-warning
}