Example #1
0
boolean findEOPD_impl(bitset currentEopdVertices, bitset currentEopdFaces, int eopdExtension, bitset remainingFaces, EDGE *lastExtendedEdge){
    //first check whether this is a covering eOPD
    if(IS_NOT_EMPTY(INTERSECTION(currentEopdFaces, remainingFaces))){
        printFaceTupleFaces(currentEopdFaces);
        return TRUE;
    }
    
    //otherwise try extending the eOPD
    EDGE *extension = lastExtendedEdge->next;
    
    if(INTERSECTION(currentEopdVertices, neighbourhood[extension->next->end]) ==
            extension->vertices){
            //face to the right of extension is addable
            if(findEOPD_impl(UNION(currentEopdVertices, faceSets[extension->rightface]),
                    UNION(currentEopdFaces, SINGLETON(extension->rightface)),
                    eopdExtension, remainingFaces, extension)){
                return TRUE;
            }
    }
    
    extension = lastExtendedEdge->inverse->prev->inverse;
    
    if(INTERSECTION(currentEopdVertices, neighbourhood[extension->next->end]) ==
            extension->vertices){
            //face to the right of extension is addable
            if(findEOPD_impl(UNION(currentEopdVertices, faceSets[extension->rightface]),
                    UNION(currentEopdFaces, SINGLETON(extension->rightface)),
                    eopdExtension, remainingFaces, extension)){
                return TRUE;
            }
    }
    
    return FALSE;
}
Example #2
0
File: p.c Project: DavidToca/acm
static void solve()
{
	int i, j, k, a, b;

	for (i = 0; i < n; i++) {
		for (k = (i << 7), j = 0; j < m; j++, k++) {
			pred[k] = k;
			count[k] = 1;
		}
	}

	for (i = 0; i < n; i++) {
		for (j = 0; j < m; j++) {
			if (map[i][j] != 'W')
				continue;

			k = (i << 7) + j;

			for (a = k; pred[a] != a; a = pred[a]);
			pred[k] = a;

#define UNION(by, bx) { \
        k = ((by) << 7) + (bx); \
        for (b = k; pred[b] != b; b = pred[b]); \
	pred[k] = b; \
	if (a != b) { \
		if (count[a] > count[b]) { \
			count[a] += count[b]; \
			pred[b] = a; \
		} else { \
			count[b] += count[a]; \
			a = pred[a] = b; \
		} \
	} \
}

			if (i > 0) {
				if (j > 0 && map[i - 1][j - 1] == 'W')
					UNION(i - 1, j - 1);

				if (map[i - 1][j] == 'W')
					UNION(i - 1, j);

				if ((j + 1) < m && map[i - 1][j + 1] == 'W')
					UNION(i - 1, j + 1);
			}

			if (j > 0 && map[i][j - 1] == 'W') {
				UNION(i, j - 1);
			}
		}
	}
}
Example #3
0
File: eopd.c Project: nvcleemp/eopd
boolean findEOPD(bitset tuple){
    int i, j;
    //first we check the stored OPD's
    for(i = 0; i < eopdCount; i++){
        bitset intersectionOpd = INTERSECTION(tuple, opdFaces[i]);
        bitset intersectionExtensions = INTERSECTION(tuple, extensionFaces[i]);
        if((IS_NOT_EMPTY(intersectionOpd) && IS_NOT_EMPTY(intersectionExtensions)) ||
                (HAS_MORE_THAN_ONE_ELEMENT(intersectionOpd))){
            numberOfTuplesCoveredByStoredOpd++;
            return TRUE;
        }
    }
    
    //then we try to find a new eOPD
    for(i = 0; i < nf; i++){
        if(CONTAINS(tuple, i)){
            //try to find a eOPD with face i as extension
            bitset remainingFaces = MINUS(tuple, i);
            //we use each edge once as a possible shared edge 
            EDGE *sharedEdge = facestart[i];
            for(j = 0; j < 3; j++){
                //construct initial eopd
                int neighbouringFace = sharedEdge->inverse->rightface;
                bitset currentEopdVertices = faceSets[neighbouringFace];
                bitset currentEopdFaces = UNION(SINGLETON(i), SINGLETON(neighbouringFace));
                if(findEOPD_impl(currentEopdVertices, currentEopdFaces, i, remainingFaces, sharedEdge->inverse)){
                    return TRUE;
                }
                sharedEdge = sharedEdge->next->inverse;
            }
        }
    }
    return FALSE;
}
Example #4
0
int
main()
{
	int i;

	char s[10];
	int x, y;

	scanf("%d", &t);
	while (t--)
	{
		scanf("%d%d", &n, &m);
		for (i = 1; i <= n; i++)
		{
			f[i] = -1;
			r[i] = 1;
		}
		while (m--)
		{
			scanf("%s%d%d", s, &x, &y);
			if (s[0] == 'A')
			{
				if (FIND(x) == FIND(y))
				{
					if (r[x] == r[y]) printf("In the same gang.\n");
					else printf("In different gangs.\n");
				}
				else printf("Not sure yet.\n");
			}
			if (s[0] == 'D') UNION(x, y);
		}
	}

	return 0;
}
Example #5
0
      void operator()(const PRIMITIVES& _in, PRIMITIVES& _out)
      {
        typedef typename PRIMITIVES::value_type primitive_type;
        std::list<primitive_type> _input;
        for (auto& p : _in ) _input.push_back(p);

      for (auto i = _input.begin(); i != _input.end(); ++i)
      {
        auto j = i;
        ++j;
        for (; j != _input.end(); ++j)
        {
          if (!intersects(i->bounds(),j->bounds())) continue;

          PRIMITIVES _newPrimitives;
          UNION()(*i,*j,_newPrimitives);
          if (_newPrimitives.size() == 1)
          {
            _newPrimitives.back().update();
            *i = _newPrimitives.back();
            _input.erase(j);
            j = i;
          }
        }
      }
      _out.insert(_out.end(),_input.begin(),_input.end());
    }
Example #6
0
int
main()
{
	int i, j, x, y, ans;

	scanf("%d", &t);
	for (i = 1; i <= t; i++)
	{
		scanf("%d %d", &n, &m);
		for (j = 1; j <= n; j++)
		{
			f[j] = -1;
			r[j] = 1;
		}
		ans = 0;
		while (m--)
		{
			scanf("%d %d", &x, &y);
			if (FIND(x) == FIND(y))
			{
				if (r[x] == r[y]) ans = 1;
			}
			else UNION(x, y);
		}
		printf("Scenario #%d:\n", i);
		if (ans) printf("Suspicious bugs found!\n\n");
		else printf("No suspicious bugs found!\n\n");
	}

	return 0;
}
Example #7
0
void kruskal()
{
	NODE *u, *v;
	SET *uSet, *vSet;
	for( ADJ_LIST *header = adjListBeg; header != NULL; header = header->down)
	{
		u = header->node;
		makeSet(u);
	}
	sortEdges();
	for( int i = 0; i < edgeCount; i++ )
	{
		uSet = findSet(edgeList[i].node1);
		vSet = findSet(edgeList[i].node2);
		if( uSet != vSet )
		{
			cout << "Taking edge : " << edgeList[i].node1->id << "--" << edgeList[i].node2->id << ":" << edgeList[i].weight << endl;
			UNION(uSet, vSet);
			changeEdgeColor(&edgeList[i], GREEN);
			sleep(1);
			changeNodeColor(edgeList[i].node1, GREEN);
			usleep(500000);
			changeNodeColor(edgeList[i].node2, GREEN);
			sleep(1);
		}
	}
}
Example #8
0
int
main()
{
	int i, d, x, y, ans;

	scanf("%d %d", &n, &k);
	for (i = 1; i <= n; i++)
	{
		f[i] = -1;
		r[i] = 0;
	}
	ans = 0;
	for (i = 0; i < k; i++)
	{
		scanf("%d %d %d", &d, &x, &y);
		if (x > n || y > n || d == 2 && x == y)
		{
			ans++;
			continue;
		}
		ans += UNION(x, y, d);
	}
	printf("%d\n", ans);

	return 0;
}
Example #9
0
static void
check_bool2_init (enum tree_code code, tree exp0, tree exp1,
		  words before, words when_false, words when_true)
{
  word buf[2*4];
  words tmp = num_current_words <= 2 ? buf
    : ALLOC_WORDS (4 * num_current_words);
  words when_false_0 = tmp;
  words when_false_1 = tmp+num_current_words;
  words when_true_0 = tmp+2*num_current_words;
  words when_true_1 = tmp+3*num_current_words;
  check_bool_init (exp0, before, when_false_0, when_true_0);
  INTERSECT (before, when_false_0, when_true_0);
  check_bool_init (exp1, before, when_false_1, when_true_1);

  INTERSECT (before, when_false_1, when_true_1);

  if (code == EQ_EXPR)
    {
      /* Now set:
       * when_true = (when_false_1 INTERSECTION when_true_1)
       *   UNION (when_true_0 INTERSECTION when_false_1)
       *   UNION (when_false_0 INTERSECTION when_true_1);
       * using when_false and before as temporary working areas.  */
      INTERSECT (when_true, when_true_0, when_false_1);
      INTERSECT (when_false, when_true_0, when_false_1);
      UNION (when_true, when_true, when_false);
      UNION (when_true, when_true, before);

      /* Now set:
       * when_false = (when_false_1 INTERSECTION when_true_1)
       *   UNION (when_true_0 INTERSECTION when_true_1)
       *   UNION (when_false_0 INTERSECTION when_false_1);
       * using before as a temporary working area.  */
      INTERSECT (when_false, when_true_0, when_true_1);
      UNION (when_false, when_false, before);
      INTERSECT (before, when_false_0, when_false_1);
      UNION (when_false, when_false, before);
    }
  else if (code == BIT_AND_EXPR || code == TRUTH_AND_EXPR)
    {
      UNION (when_true, when_true_0, when_true_1);
      INTERSECT (when_false, when_false_0, when_false_1);
      UNION (when_false, when_false, before);
    }
  else /* if (code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) */
    {
      UNION (when_false, when_false_0, when_false_1);
      INTERSECT (when_true, when_true_0, when_true_1);
      UNION (when_true, when_true, before);
    }

  if (tmp != buf)
    FREE_WORDS (tmp);
}
Example #10
0
File: eopd.c Project: nvcleemp/eopd
boolean findUncoveredFaceTuple_impl(bitset tuple, bitset tupleVertices, int position, int size){
    if(size + (nf - position) < 4){
        //this tuple can't be completed to a 4-tuple
        return FALSE;
    }
    if(size < 3){
        //just extend and continue
        int i;
        for(i = position; i < nf - 3 + size; i++){
            if(IS_EMPTY(INTERSECTION(tupleVertices, faceSets[i]))){
                if(findUncoveredFaceTuple_impl(UNION(tuple, SINGLETON(i)),
                    UNION(tupleVertices, faceSets[i]), i+1, size+1)){
                    return TRUE;
                }
            }
        }
    } else if(size == 3){
        //search for eOPD and if none found: go to 4-tuple
        numberOfChecked3Tuples++;
        if(findEOPD(tuple)){
            return FALSE;
        }
        //no eOPD found: extending tuple
        int i;
        for(i = position; i < nf; i++){
            if(IS_EMPTY(INTERSECTION(tupleVertices, faceSets[i]))){
                if(findUncoveredFaceTuple_impl(UNION(tuple, SINGLETON(i)),
                    UNION(tupleVertices, faceSets[i]), i+1, size+1)){
                    return TRUE;
                }
            }
        }
    } else {// size == 4
        numberOfChecked4Tuples++;
        //search for eOPD
        return !findEOPD(tuple);
    }
    //if we get here then all tuples extending the current tuple were covered
    return FALSE;
}
Example #11
0
File: eopd.c Project: nvcleemp/eopd
void constructInitialEopds(){
    int i;
    
    greedyExtendOpdAndStore(faceSets[0], SINGLETON(0));
    
    bitset coveredFaces = UNION(opdFaces[eopdCount-1], extensionFaces[eopdCount-1]);
    
    for(i = nf -1; i > 0; i--){
        if(!CONTAINS(coveredFaces, i)){
            greedyExtendOpdAndStore(faceSets[i], SINGLETON(i));
            ADD_ALL(coveredFaces, opdFaces[eopdCount-1]);
            ADD_ALL(coveredFaces, extensionFaces[eopdCount-1]);
        }
    }
}
Example #12
0
boolean findEOPD(bitset tuple){
    int i, j;
    
    for(i = 0; i < nf; i++){
        if(CONTAINS(tuple, i)){
            //try to find a eOPD with face i as extension
            bitset remainingFaces = MINUS(tuple, i);
            //we use each edge once as a possible shared edge 
            EDGE *sharedEdge = facestart[i];
            for(j = 0; j < 3; j++){
                //construct initial eopd
                int neighbouringFace = sharedEdge->inverse->rightface;
                bitset currentEopdVertices = faceSets[neighbouringFace];
                bitset currentEopdFaces = UNION(SINGLETON(i), SINGLETON(neighbouringFace));
                if(findEOPD_impl(currentEopdVertices, currentEopdFaces, i, remainingFaces, sharedEdge->inverse)){
                    return TRUE;
                }
                sharedEdge = sharedEdge->next->inverse;
            }
        }
    }
    return FALSE;
}
Example #13
0
Clusters *Merge_Segments(Segmentation *segs, Overlaps *ovl)
{ Clusters *clust;
  int      *fathers, *sets, *which;
  int       nsegs, nsets;
  int       j, k;

  nsegs = ovl->totsegs;

  which   = (int *) Guarded_Malloc(sizeof(int)*(2*nsegs+1),Program_Name());
  sets    = which + nsegs;
  fathers = (int *) Guarded_Malloc(sizeof(int)*nsegs,Program_Name());

  for (k = 0; k < nsegs; k++)
    fathers[k] = -1;

  for (k = 0; k < nsegs; k++)
    for (j = ovl->alist[k]; j < ovl->alist[k+1]; j++)
      UNION(fathers,k,ovl->heads[j]);

  nsets = 0;
  for (k = 0; k < nsegs; k++)
    if (fathers[k] < 0)
      { nsets += 1;
        fathers[k] = -nsets;
      }
    else
      fathers[k] = FIND(fathers,k);

  for (k = 0; k < nsegs; k++)
    if (fathers[k] > 0)
      fathers[k] = fathers[fathers[k]];

  for (k = 0; k < nsegs; k++)
    fathers[k] = -(fathers[k]+1);

  for (k = 0; k <= nsets; k++)
    sets[k] = 0;
  for (k = 0; k < nsegs; k++)
    sets[fathers[k]+1] += 1;
  for (k = 2; k <= nsets; k++)
    sets[k] += sets[k-1];
  for (k = 0; k < nsegs; k++)
    { which[sets[fathers[k]]] = k;
      sets[fathers[k]] += 1;
    }
  for (k = nsegs; k > 0; k--)
    sets[k] = sets[k-1];
  sets[0] = 0;

  free(fathers);

  clust = (Clusters *) Guarded_Malloc(sizeof(Clusters),Program_Name());
  clust->inum   = nsets;
  clust->ilist  = sets;
  clust->item   = which;

#ifdef VERBOSE
  printf("\nClusters:\n");
  for (k = 0; k < nsets; k++)
    { printf("  Set %3d:",k);
      for (j = sets[k]; j < sets[k+1]; j++)
        { int c = ovl->chans[which[j]];
          printf(" %c%d",Letter[c],(which[j]-segs[c].base)+1);
        }
      printf("\n");
      fflush(stdout);
    }
  fflush(stdout);
#endif

  return (clust);
}
Example #14
0
void decodePlanarCode(unsigned short* code) {
    /* complexity of method to determine inverse isn't that good, but will have to satisfy for now
     */
    int i, j, codePosition;
    int edgeCounter = 0;
    EDGE *inverse;

    nv = code[0];
    codePosition = 1;

    for (i = 0; i < nv; i++) {
        degree[i] = 0;
        neighbourhood[i] = SINGLETON(code[codePosition] - 1);
        firstedge[i] = edges + edgeCounter;
        edges[edgeCounter].start = i;
        edges[edgeCounter].end = code[codePosition] - 1;
        edges[edgeCounter].vertices = UNION(SINGLETON(i), SINGLETON(code[codePosition] - 1));
        edges[edgeCounter].next = edges + edgeCounter + 1;
        if (code[codePosition] - 1 < i) {
            inverse = edgeMatrix[code[codePosition] - 1][i];
            edges[edgeCounter].inverse = inverse;
            inverse->inverse = edges + edgeCounter;
        } else {
            edgeMatrix[i][code[codePosition] - 1] = edges + edgeCounter;
            edges[edgeCounter].inverse = NULL;
        }
        edgeCounter++;
        codePosition++;
        for (j = 1; code[codePosition]; j++, codePosition++) {
            if (j == MAXVAL) {
                fprintf(stderr, "MAXVAL too small: %d\n", MAXVAL);
                exit(0);
            }
            ADD(neighbourhood[i], code[codePosition] - 1);
            edges[edgeCounter].start = i;
            edges[edgeCounter].end = code[codePosition] - 1;
            edges[edgeCounter].vertices = UNION(SINGLETON(i), SINGLETON(code[codePosition] - 1));
            edges[edgeCounter].prev = edges + edgeCounter - 1;
            edges[edgeCounter].next = edges + edgeCounter + 1;
            if (code[codePosition] - 1 < i) {
                inverse = edgeMatrix[code[codePosition] - 1][i];
                edges[edgeCounter].inverse = inverse;
                inverse->inverse = edges + edgeCounter;
            } else {
                edgeMatrix[i][code[codePosition] - 1] = edges + edgeCounter;
                edges[edgeCounter].inverse = NULL;
            }
            edgeCounter++;
        }
        firstedge[i]->prev = edges + edgeCounter - 1;
        edges[edgeCounter - 1].next = firstedge[i];
        degree[i] = j;

        codePosition++; /* read the closing 0 */
    }

    ne = edgeCounter;

    makeDual();

    // nv - ne/2 + nf = 2
}
Example #15
0
static void
check_init (tree exp, words before)
{
  tree tmp;
 again:
  switch (TREE_CODE (exp))
    {
    case VAR_DECL:
    case PARM_DECL:
      if (! FIELD_STATIC (exp) && DECL_NAME (exp) != NULL_TREE
	  && DECL_NAME (exp) != this_identifier_node)
	{
	  int index = DECL_BIT_INDEX (exp);
	  /* We don't want to report and mark as non-initialized class
	     initialization flags. */
	  if (! LOCAL_CLASS_INITIALIZATION_FLAG_P (exp)
	      && index >= 0 && ! ASSIGNED_P (before, index))
	    {
	      parse_error_context 
		(wfl, "Variable %qs may not have been initialized",
		 IDENTIFIER_POINTER (DECL_NAME (exp)));
	      /* Suppress further errors. */
	      DECL_BIT_INDEX (exp) = -2;
	    }
	}
      break;

    case COMPONENT_REF:
      check_init (TREE_OPERAND (exp, 0), before);
      if ((tmp = get_variable_decl (exp)) != NULL_TREE)
	{
	  int index = DECL_BIT_INDEX (tmp);
	  if (index >= 0 && ! ASSIGNED_P (before, index))
	    {
	      parse_error_context 
		(wfl, "variable %qs may not have been initialized",
		 IDENTIFIER_POINTER (DECL_NAME (tmp)));
	      /* Suppress further errors. */
	      DECL_BIT_INDEX (tmp) = -2;
	    }
	}
      break;
      
    case MODIFY_EXPR:
      tmp = TREE_OPERAND (exp, 0);
      /* We're interested in variable declaration and parameter
         declaration when they're declared with the `final' modifier. */
      if ((tmp = get_variable_decl (tmp)) != NULL_TREE)
	{
	  int index;
	  check_init (TREE_OPERAND (exp, 1), before);
	  check_final_reassigned (tmp, before);
	  index = DECL_BIT_INDEX (tmp);
	  if (index >= 0)
	    {
	      SET_ASSIGNED (before, index);
	      CLEAR_UNASSIGNED (before, index);
	    }
	  /* Minor optimization.  See comment for start_current_locals.
	     If we're optimizing for class initialization, we keep
	     this information to check whether the variable is
	     definitely assigned when once we checked the whole
	     function. */
	  if (! STATIC_CLASS_INIT_OPT_P () /* FIXME */
	      && ! DECL_FINAL (tmp)
	      && index >= start_current_locals
	      && index == num_current_locals - 1)
	    {
	      num_current_locals--;
	      DECL_BIT_INDEX (tmp) = -1;
	    }
	 break;
       }
      else if (TREE_CODE (tmp = TREE_OPERAND (exp, 0)) == COMPONENT_REF)
	{
	  tree decl;
	  check_init (tmp, before);
	  check_init (TREE_OPERAND (exp, 1), before);
	  decl = TREE_OPERAND (tmp, 1);
	  if (DECL_FINAL (decl))
	    final_assign_error (DECL_NAME (decl));
	  break;
	}
      else if (TREE_CODE (tmp) == COMPONENT_REF && IS_ARRAY_LENGTH_ACCESS (tmp))
	{
	  /* We can't emit a more specific message here, because when
	     compiling to bytecodes we don't get here. */
	  final_assign_error (length_identifier_node);
	}
     else
       goto binop;
    case BLOCK:
      if (BLOCK_EXPR_BODY (exp))
	{
	  tree decl = BLOCK_EXPR_DECLS (exp);
	  int words_needed;
	  word* tmp;
	  int i;
	  int save_start_current_locals = start_current_locals;
	  int save_num_current_words = num_current_words;
	  start_current_locals = num_current_locals;
	  for (;  decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	    {
	      DECL_BIT_INDEX (decl) = num_current_locals++;
	    }
	  words_needed = WORDS_NEEDED (2 * num_current_locals);
	  if (words_needed > num_current_words)
	    {
	      tmp = ALLOC_WORDS (words_needed);
	      COPY (tmp, before);
	      num_current_words = words_needed;
	    }
	  else
	    tmp = before;
	  for (i = start_current_locals;  i < num_current_locals;  i++)
	    {
	      CLEAR_ASSIGNED (tmp, i);
	      SET_UNASSIGNED (tmp, i);
	    }
	  check_init (BLOCK_EXPR_BODY (exp), tmp);

	  /* Re-set DECL_BIT_INDEX since it is also DECL_POINTER_ALIAS_SET. */
	  for (decl = BLOCK_EXPR_DECLS (exp);
	       decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	    {
	      if (LOCAL_CLASS_INITIALIZATION_FLAG_P (decl))
		{
		  int index = DECL_BIT_INDEX (decl);
		  tree fndecl = DECL_CONTEXT (decl);
		  if (fndecl && METHOD_STATIC (fndecl)
		      && (DECL_INITIAL (decl) == boolean_true_node
			  || (index >= 0 && ASSIGNED_P (tmp, index))))
		    *(htab_find_slot 
		      (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
		       DECL_FUNCTION_INIT_TEST_CLASS (decl), INSERT)) =
		      DECL_FUNCTION_INIT_TEST_CLASS (decl);
		}
	      DECL_BIT_INDEX (decl) = -1;
	    }

	  num_current_locals = start_current_locals;
	  start_current_locals = save_start_current_locals;
	  if (tmp != before)
	    {
	      num_current_words = save_num_current_words;
	      COPY (before, tmp);
	      FREE_WORDS (tmp);
	    }
	}
      break;
    case LOOP_EXPR:
      {
	/* The JLS 2nd edition discusses a complication determining
	   definite unassignment of loop statements.  They define a
	   "hypothetical" analysis model.  We do something much
	   simpler: We just disallow assignments inside loops to final
	   variables declared outside the loop.  This means we may
	   disallow some contrived assignments that the JLS allows, but I
	   can't see how anything except a very contrived testcase (a
	   do-while whose condition is false?) would care. */

	struct alternatives alt;
	int save_loop_current_locals = loop_current_locals;
	int save_start_current_locals = start_current_locals;
	loop_current_locals = num_current_locals;
	start_current_locals = num_current_locals;
	BEGIN_ALTERNATIVES (before, alt);
	alt.block = exp;
	check_init (TREE_OPERAND (exp, 0), before);
	END_ALTERNATIVES (before, alt);
	loop_current_locals = save_loop_current_locals;
	start_current_locals = save_start_current_locals;
	return;
      }
    case EXIT_EXPR:
      {
	struct alternatives *alt = alternatives;
	DECLARE_BUFFERS(when_true, 2);
	words when_false = when_true + num_current_words;
#ifdef ENABLE_JC1_CHECKING
	if (TREE_CODE (alt->block) != LOOP_EXPR)
	  abort ();
#endif
	check_bool_init (TREE_OPERAND (exp, 0), before, when_false, when_true);
	done_alternative (when_true, alt);
	COPY (before, when_false);
	RELEASE_BUFFERS(when_true);
	return;
      }
    case LABELED_BLOCK_EXPR:
      {
	struct alternatives alt;
	BEGIN_ALTERNATIVES (before, alt);
	alt.block = exp;
	if (LABELED_BLOCK_BODY (exp))
	  check_init (LABELED_BLOCK_BODY (exp), before);
	done_alternative (before, &alt);
	END_ALTERNATIVES (before, alt);
	return;
      }
    case EXIT_BLOCK_EXPR:
      {
	tree block = TREE_OPERAND (exp, 0);
	struct alternatives *alt = alternatives;
	while (alt->block != block)
	  alt = alt->outer;
	done_alternative (before, alt);
	SET_ALL (before);
	return;
      }
    case SWITCH_EXPR:
      {
	struct alternatives alt;
	word buf[2];
	check_init (TREE_OPERAND (exp, 0), before);
	BEGIN_ALTERNATIVES (before, alt);
	alt.saved = ALLOC_BUFFER(buf, num_current_words);
	COPY (alt.saved, before);
	alt.block = exp;
	check_init (TREE_OPERAND (exp, 1), before);
	done_alternative (before, &alt);
	if (! SWITCH_HAS_DEFAULT (exp))
	  done_alternative (alt.saved, &alt);
	FREE_BUFFER(alt.saved, buf);
	END_ALTERNATIVES (before, alt);
	return;
      }
    case CASE_EXPR:
    case DEFAULT_EXPR:
      {
	int i;
	struct alternatives *alt = alternatives;
	while (TREE_CODE (alt->block) != SWITCH_EXPR)
	  alt = alt->outer;
	COPYN (before, alt->saved, WORDS_NEEDED (2 * alt->num_locals));
	for (i = alt->num_locals;  i < num_current_locals;  i++)
	  CLEAR_ASSIGNED (before, i);
	break;
      }

    case TRY_EXPR:
      {
	tree try_clause = TREE_OPERAND (exp, 0);
	tree clause = TREE_OPERAND (exp, 1);
	word buf[2*2];
	words tmp = (num_current_words <= 2 ? buf
		    : ALLOC_WORDS (2 * num_current_words));
	words save = tmp + num_current_words;
	struct alternatives alt;
	BEGIN_ALTERNATIVES (before, alt);
	COPY (save, before);
	COPY (tmp, save);
	check_init (try_clause, tmp);
	done_alternative (tmp, &alt);
	for ( ; clause != NULL_TREE;  clause = TREE_CHAIN (clause))
	  {
	    tree catch_clause = TREE_OPERAND (clause, 0);
	    COPY (tmp, save);
	    check_init (catch_clause, tmp);
	    done_alternative (tmp, &alt);
	  }
	if (tmp != buf)
	  {
	    FREE_WORDS (tmp);
	  }
	END_ALTERNATIVES (before, alt);
      }
    return;

    case TRY_FINALLY_EXPR:
      {
	DECLARE_BUFFERS(tmp, 1);
	COPY (tmp, before);
	check_init (TREE_OPERAND (exp, 0), before);
	check_init (TREE_OPERAND (exp, 1), tmp);
	UNION (before, before, tmp);
	RELEASE_BUFFERS(tmp);
      }
      return;

    case RETURN_EXPR:
    case THROW_EXPR:
      if (TREE_OPERAND (exp, 0))
	check_init (TREE_OPERAND (exp, 0), before);
      goto never_continues;

    case ERROR_MARK:
    never_continues:
      SET_ALL (before);
      return;
      
    case COND_EXPR:
    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
      {
	DECLARE_BUFFERS(when_true, 2);
	words when_false = when_true + num_current_words;
	check_bool_init (exp, before, when_false, when_true);
	INTERSECT (before, when_false, when_true);
	RELEASE_BUFFERS(when_true);
      }
      break;

    case NOP_EXPR:
      if (IS_EMPTY_STMT (exp))
	break;
      /* ... else fall through ... */
    case UNARY_PLUS_EXPR:
    case NEGATE_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
    case TRUTH_NOT_EXPR:
    case BIT_NOT_EXPR:
    case CONVERT_EXPR:
    case BIT_FIELD_REF:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
    case INDIRECT_REF:
    case ADDR_EXPR:
    case NON_LVALUE_EXPR:
    case INSTANCEOF_EXPR:
    case FIX_CEIL_EXPR:
    case FIX_FLOOR_EXPR:
    case FIX_ROUND_EXPR:
    case ABS_EXPR:
      /* Avoid needless recursion. */
      exp = TREE_OPERAND (exp, 0);
      goto again;

    case PREDECREMENT_EXPR:
    case PREINCREMENT_EXPR:
    case POSTDECREMENT_EXPR:
    case POSTINCREMENT_EXPR:
      tmp = get_variable_decl (TREE_OPERAND (exp, 0));
      if (tmp != NULL_TREE && DECL_FINAL (tmp))
	final_assign_error (DECL_NAME (tmp));      

      /* Avoid needless recursion.  */
      exp = TREE_OPERAND (exp, 0);
      goto again;

    case SAVE_EXPR:
      if (IS_INIT_CHECKED (exp))
	return;
      IS_INIT_CHECKED (exp) = 1;
      exp = TREE_OPERAND (exp, 0);
      goto again;

    case COMPOUND_EXPR:
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case TRUNC_MOD_EXPR:
    case RDIV_EXPR:
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case URSHIFT_EXPR:
    case BIT_AND_EXPR:
    case BIT_XOR_EXPR:
    case BIT_IOR_EXPR:
    case EQ_EXPR: 
    case NE_EXPR:
    case GT_EXPR:
    case GE_EXPR:
    case LT_EXPR:
    case LE_EXPR:
    case MAX_EXPR:
    case MIN_EXPR:
    case ARRAY_REF:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case EXACT_DIV_EXPR:
    case UNLT_EXPR:
    case UNLE_EXPR:
    case UNGT_EXPR:
    case UNGE_EXPR:
    case UNEQ_EXPR:
    case LTGT_EXPR:
    binop:
      check_init (TREE_OPERAND (exp, 0), before);
      /* Avoid needless recursion, especially for COMPOUND_EXPR. */
      exp = TREE_OPERAND (exp, 1);
      goto again;

    case RESULT_DECL:
    case FUNCTION_DECL:
    case INTEGER_CST:
    case REAL_CST:
    case STRING_CST:
    case JAVA_EXC_OBJ_EXPR:
      break;

    case NEW_CLASS_EXPR:
    case CALL_EXPR:
      {
	tree func = TREE_OPERAND (exp, 0);
	tree x = TREE_OPERAND (exp, 1);
	if (TREE_CODE (func) == ADDR_EXPR)
	  func = TREE_OPERAND (func, 0);
	check_init (func, before);

	for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
	  check_init (TREE_VALUE (x), before);
	if (func == throw_node)
	  goto never_continues;
      }
      break;

    case NEW_ARRAY_INIT:
      {
	tree x = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
	for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
	  check_init (TREE_VALUE (x), before);
      }
      break;

    case EXPR_WITH_FILE_LOCATION:
      {
	location_t saved_location = input_location;
	tree saved_wfl = wfl;
	tree body = EXPR_WFL_NODE (exp);
	if (IS_EMPTY_STMT (body))
	  break;
	wfl = exp;
#ifdef USE_MAPPED_LOCATION
	input_location = EXPR_LOCATION (exp);
#else
	input_filename = EXPR_WFL_FILENAME (exp);
	input_line = EXPR_WFL_LINENO (exp);
#endif
	check_init (body, before);
	input_location = saved_location;
	wfl = saved_wfl;
      }
      break;
      
    default:
      internal_error
	("internal error in check-init: tree code not implemented: %s",
	 tree_code_name [(int) TREE_CODE (exp)]);
    }
}