For the following Texinfo file,

  \input texinfo
  @setfilename foo.info

  @ifinfo
  @node Top, concept index, (dir), (dir)
  @top

  Some text here.

  @cindex foo-concept
  @findex foo-function

  @defindex xx
  @synindex cp xx
  @synindex fn xx

  Some more text here.

  @cindex bar-concept
  @findex bar-function

  @menu
  * concept index::               
  * function index::              
  * xx index::                    
  @end menu

  @node concept index, function index, Top, Top
  @chapter concept index

  @printindex cp

  @node function index, xx index, concept index, Top
  @chapter function index

  @printindex fn

  @node xx index,  , function index, Top
  @chapter xx index

  @printindex xx

  @bye

TeX creates three indices with the contents

  concept index
    foo-concept

  function index
    foo-function

  xx index 
    bar-concept
    bar-function

but makeinfo version 1.55 creates three indices all with the same
contents:

  concept index
    bar-concept
    bar-function

  function index
    bar-concept
    bar-function

  xx index 
    bar-concept
    bar-function


Here is a patch that will cause makeinfo to behave more like
TeX/texinfo.tex.

Fri Feb 11 18:53:49 1994  John Eaton  (jwe@schoch.che.utexas.edu)

	* makeinfo.c (INDEX_ALIST): Use two indices, read_index and
	write_index, instead of just one.
	(find_index_offset): If a match is found, return index to the
	current INDEX_ALIST struct, not the index pointing to the list of
	index entries.
	(translate_index): Return read_index from the matching
	INDEX_ALIST.
	(undefindex): Delete the list of index elements pointed to by
	read_index from the INDEX_ALIST that matches name.
	(defindex): Initialize read_index and write_index.
	(index_add_arg): Add entries to the list pointed to by write_index
	from the INDEX_ALIST matching name.
	(index_append): Delete unused function.
	(cm_synindex): Don't merge indcies, just make the write_index for
	redirectee the same as the write_index for redirector.

*** makeinfo.c.orig	Sat May 22 18:29:46 1993
--- makeinfo.c	Fri Feb 11 19:02:48 1994
*************** typedef struct index_elt
*** 6452,6465 ****
    int defining_line;		/* Line number where this entry was written. */
  } INDEX_ELT;
  
! /* A list of short-names for each index, and the index to that index in our
!    index array, the_indices.  In addition, for each index, it is remembered
!    whether that index is a code index or not.  Code indices have @code{}
!    inserted around the first word when they are printed with printindex. */
  typedef struct
  {
    char *name;
!   int index;
    int code;
  } INDEX_ALIST;
  
--- 6452,6491 ----
    int defining_line;		/* Line number where this entry was written. */
  } INDEX_ELT;
  
! /* A list of short-names for each index.
! 
!    There are two indices into the the_indices array.
! 
!    * read_index is the index that points to the list of index
!      entries that we will find if we ask for the list of entries for
!      this name.
! 
!    * write_index is the index that points to the list of index entries
!      that we will add new entries to.
! 
!    Initially, read_index and write index are the same, but the
!    @syncodeindex and @synindex commands can change the list we add
!    entries to.
! 
!    For example, after the commands
! 
!      @cindex foo
!      @defindex xx
!      @synindex cp xx
!      @cindex bar
! 
!    the cp index will contain the entry `foo', and the new xx
!    index will contain the entry `bar'.  This is consistent with the
!    way texinfo.tex handles the same situation.
! 
!    In addition, for each index, it is remembered whether that index is
!    a code index or not.  Code indices have @code{} inserted around the
!    first word when they are printed with printindex. */
  typedef struct
  {
    char *name;
!   int read_index;   /* index entries for `name' */
!   int write_index;  /* store index entries here, @synindex can change it */
    int code;
  } INDEX_ALIST;
  
*************** find_index_offset (name)
*** 6523,6529 ****
    for (i = 0; i < defined_indices; i++)
      if (name_index_alist[i] &&
  	strcmp (name, name_index_alist[i]->name) == 0)
!       return (name_index_alist[i]->index);
    return (-1);
  }
  
--- 6549,6556 ----
    for (i = 0; i < defined_indices; i++)
      if (name_index_alist[i] &&
  	strcmp (name, name_index_alist[i]->name) == 0)
!       return i;
! 
    return (-1);
  }
  
*************** translate_index (name)
*** 6548,6554 ****
    INDEX_ALIST *which = find_index (name);
  
    if (which)
!     return (which->index);
    else
      return (-1);
  }
--- 6575,6581 ----
    INDEX_ALIST *which = find_index (name);
  
    if (which)
!     return (which->read_index);
    else
      return (-1);
  }
*************** free_index (index)
*** 6580,6586 ****
      }
  }
  
! /* Flush an index by name. */
  undefindex (name)
       char *name;
  {
--- 6607,6614 ----
      }
  }
  
! /* Flush an index by name.  This will delete the list of entries that
!    would be written by a @printindex command for this index. */
  undefindex (name)
       char *name;
  {
*************** undefindex (name)
*** 6590,6596 ****
    if (which < 0)
      return (which);
  
!   i = name_index_alist[which]->index;
  
  
    free_index (the_indices[i]);
--- 6618,6624 ----
    if (which < 0)
      return (which);
  
!   i = name_index_alist[which]->read_index;
  
  
    free_index (the_indices[i]);
*************** defindex (name, code)
*** 6638,6644 ****
    /* We have a slot.  Start assigning. */
    name_index_alist[slot] = (INDEX_ALIST *) xmalloc (sizeof (INDEX_ALIST));
    name_index_alist[slot]->name = savestring (name);
!   name_index_alist[slot]->index = slot;
    name_index_alist[slot]->code = code;
  
    the_indices[slot] = (INDEX_ELT *) NULL;
--- 6666,6673 ----
    /* We have a slot.  Start assigning. */
    name_index_alist[slot] = (INDEX_ALIST *) xmalloc (sizeof (INDEX_ALIST));
    name_index_alist[slot]->name = savestring (name);
!   name_index_alist[slot]->read_index = slot;
!   name_index_alist[slot]->write_index = slot;
    name_index_alist[slot]->code = code;
  
    the_indices[slot] = (INDEX_ELT *) NULL;
*************** index_add_arg (name)
*** 6654,6660 ****
  
    tem = find_index (name);
  
!   which = tem ? tem->index : -1;
  
    get_rest_of_line (&index_entry);
    ignore_blank_line ();
--- 6683,6689 ----
  
    tem = find_index (name);
  
!   which = tem ? tem->write_index : -1;
  
    get_rest_of_line (&index_entry);
    ignore_blank_line ();
*************** gen_defindex (code)
*** 6721,6742 ****
      }
  }
  
- /* Append LIST2 to LIST1.  Return the head of the list. */
- INDEX_ELT *
- index_append (head, tail)
-      INDEX_ELT *head, *tail;
- {
-   register INDEX_ELT *t_head = head;
- 
-   if (!t_head)
-     return (tail);
- 
-   while (t_head->next)
-     t_head = t_head->next;
-   t_head->next = tail;
-   return (head);
- }
- 
  /* Expects 2 args, on the same line.  Both are index abbreviations.
     Make the first one be a synonym for the second one, i.e. make the
     first one have the same index as the second one. */
--- 6750,6755 ----
*************** cm_synindex ()
*** 6759,6780 ****
      }
    else
      {
!       /* I think that we should let the user make indices synonymous to
!          each other without any lossage of info.  This means that one can
!          say @synindex cp dt anywhere in the file, and things that used to
!          be in cp will go into dt. */
!       INDEX_ELT *i1 = the_indices[redirectee], *i2 = the_indices[redirector];
! 
!       if (i1 || i2)
! 	{
! 	  if (i1)
! 	    the_indices[redirectee] = index_append (i1, i2);
! 	  else
! 	    the_indices[redirectee] = index_append (i2, i1);
! 	}
! 
!       name_index_alist[redirectee]->index =
! 	name_index_alist[redirector]->index;
      }
  }
  
--- 6772,6779 ----
      }
    else
      {
!       name_index_alist[redirectee]->write_index =
! 	name_index_alist[redirector]->write_index;
      }
  }
  
