g++ -frepo bug in 1.1b

Brian R. Murphy brm@bikini.stanford.edu
Tue Oct 13 15:59:00 GMT 1998


Hi.

A bug appears to have been introduced in egcs-1.1b which did not
exist in egcs-1.0.3a, in that multiple C++ files with dependant
template instantiations of depth greater than 2 do not link
successfully with -frepo.

I say "appears" because this is so intertwined with linker output that
I am not confident that it is unrelated to my test platform.  However,
others have reported this problem on various systems with our exported
SUIF code, which makes more extensive use of templates than most code.

Apparently -frepo does a maximum of 2 "Recompiling" steps before
giving up and leaving undefined template instantiation symbols in the
linked file.

I have simplified and included a smallish test case showing the bug
below.  I understand the -frepo stuff so little that I am hesitant to
simplify it further.  

Anyway, I would appreciate it if someone could let me know if this is
fixed or there is a patch for it at some point so we can upgrade our
egcs compiler to a newer, faster one that still works on our code.
Thanks. 

					-Brian

This example links & runs with old g++:
    bikini% g++ -v
    Reading specs from /usr/lib/gcc-lib/i586-linux/egcs-2.90.29/specs
    gcc version egcs-2.90.29 980515 (egcs-1.0.3 release)
    bikini%                   
But fails to link after 2 "Recompiling" steps with egcs-1.1
    bikini% eg++ -v
    Reading specs from
       /usr/local/ultra/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.91.57/specs
    gcc version egcs-2.91.57 19980901 (egcs-1.1 release)]
[ fyi, my system: I686, Redhat 5.1 Linux ]

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1998-10-13 09:21 PDT by <brm@bikini>.
# Source directory was `/corsica/c7/brm/egcs-bug'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    333 -rw-r--r-- Makefile
#    492 -rw-r--r-- file1.h
#    492 -rw-r--r-- file2.h
#    505 -rw-r--r-- file1.cc
#    610 -rw-r--r-- file2.cc
#    120 -rw-r--r-- file3.cc
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh26951; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'Makefile' '(file already exists)'
else
  $echo 'x -' extracting 'Makefile' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
CXX = g++
CXXFLAGS = -g -pedantic -Wchar-subscripts -Wcomment -Wformat -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wreorder -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -frepo -fno-exceptions -DINLINE_ALL_TEMPLATES
X
all:	prog
X
prog:	file1.o file2.o file3.o
X	$(CXX) -o prog file1.o file2.o file3.o -lm
SHAR_EOF
  $shar_touch -am 1013085198 'Makefile' &&
  chmod 0644 'Makefile' ||
  $echo 'restore of' 'Makefile' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'Makefile:' 'MD5 check failed'
b4c4ecc023ab16271732ee04727b3057  Makefile
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
    test 333 -eq "$shar_count" ||
    $echo 'Makefile:' 'original size' '333,' 'current size' "$shar_count!"
  fi
fi
# ============= file1.h ==============
if test -f 'file1.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'file1.h' '(file already exists)'
else
  $echo 'x -' extracting 'file1.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'file1.h' &&
#ifndef FILE1_H
#define FILE1_H
X
template <class t> class foo2;
template <class t> class foo4;
X
template <class t> class foo1 {
X    int i;
public:
X    virtual int op1(t *);
X    foo1(int i0) : i(i0) {};
X    virtual ~foo1() {};
};
X
template <class t> class foo3 {
X    int i;
public:
X    virtual int op3(t *);
X    foo3(int i0) : i(i0) {};
X    virtual ~foo3() {};
};
X
#ifdef INLINE_ALL_TEMPLATES
#define DOING_TEMPLATE_INLINING
X
#include "file1.cc"
X
#undef DOING_TEMPLATE_INLINING
#endif
X
#endif
SHAR_EOF
  $shar_touch -am 1013085398 'file1.h' &&
  chmod 0644 'file1.h' ||
  $echo 'restore of' 'file1.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'file1.h:' 'MD5 check failed'
1c3c1a6661f92084b60eb8b490c8c4da  file1.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'file1.h'`"
    test 492 -eq "$shar_count" ||
    $echo 'file1.h:' 'original size' '492,' 'current size' "$shar_count!"
  fi
fi
# ============= file2.h ==============
if test -f 'file2.h' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'file2.h' '(file already exists)'
else
  $echo 'x -' extracting 'file2.h' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'file2.h' &&
#ifndef FILE2_H
#define FILE2_H
X
template <class t> class foo1;
template <class t> class foo3;
X
template <class t> class foo2 {
X    int i;
public:
X    virtual int op2(t *);
X    foo2(int i0) : i(i0) {};
X    virtual ~foo2() {};
};
X
template <class t> class foo4 {
X    int i;
public:
X    virtual int op4(t *);
X    foo4(int i0) : i(i0) {};
X    virtual ~foo4() {};
};
X
#ifdef INLINE_ALL_TEMPLATES
#define DOING_TEMPLATE_INLINING
X
#include "file2.cc"
X
#undef DOING_TEMPLATE_INLINING
#endif
X
#endif
SHAR_EOF
  $shar_touch -am 1013085398 'file2.h' &&
  chmod 0644 'file2.h' ||
  $echo 'restore of' 'file2.h' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'file2.h:' 'MD5 check failed'
d2e6cf838a6ec5a1570998e2a6e46c7c  file2.h
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'file2.h'`"
    test 492 -eq "$shar_count" ||
    $echo 'file2.h:' 'original size' '492,' 'current size' "$shar_count!"
  fi
fi
# ============= file1.cc ==============
if test -f 'file1.cc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'file1.cc' '(file already exists)'
else
  $echo 'x -' extracting 'file1.cc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'file1.cc' &&
#ifndef DOING_TEMPLATE_INLINING
X
#define _MODULE_ "file1"
X
#pragma implementation "file1.h"
X
#include "file1.h"
#include "file2.h"
X
#endif
X
#if ((!defined(INLINE_ALL_TEMPLATES)) || defined(DOING_TEMPLATE_INLINING))
X
template <class t>
int foo1<t>::op1(t *t_in) {
X    foo2<t> tmp(0);
X    return tmp.op2(t_in);
};
X
template <class t>
int foo3<t>::op3(t *t_in) {
X    foo4<t> tmp(0);
X    return tmp.op4(t_in);
};
X
#endif /* ((!defined(INLINE_ALL_TEMPLATES)) ||
X           defined(DOING_TEMPLATE_INLINING)) */
SHAR_EOF
  $shar_touch -am 1013085398 'file1.cc' &&
  chmod 0644 'file1.cc' ||
  $echo 'restore of' 'file1.cc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'file1.cc:' 'MD5 check failed'
f94826c0d3afa66fca472cbb461b7fcf  file1.cc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'file1.cc'`"
    test 505 -eq "$shar_count" ||
    $echo 'file1.cc:' 'original size' '505,' 'current size' "$shar_count!"
  fi
fi
# ============= file2.cc ==============
if test -f 'file2.cc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'file2.cc' '(file already exists)'
else
  $echo 'x -' extracting 'file2.cc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'file2.cc' &&
#ifndef DOING_TEMPLATE_INLINING
X
#define _MODULE_ "file2"
X
#pragma implementation "file2.h"
X
#include "file1.h"
#include "file2.h"
X
#endif
X
#if ((!defined(INLINE_ALL_TEMPLATES)) || defined(DOING_TEMPLATE_INLINING))
X
template <class t>
int foo2<t>::op2(t *t_in) {
X    foo3<t> tmp(0);
X    return tmp.op3(t_in);
};
X
template <class t>
int foo4<t>::op4(t *t_in) {
X    return i;
};
X
#endif /* ((!defined(INLINE_ALL_TEMPLATES)) ||
X           defined(DOING_TEMPLATE_INLINING)) */
X
#ifndef DOING_TEMPLATE_INLINING
X
static foo1<double> bogon(3.14);
X
int reveal()
{
X    double x=4.0;
X    return bogon.op1(&x);
}
X
#endif
SHAR_EOF
  $shar_touch -am 1013085398 'file2.cc' &&
  chmod 0644 'file2.cc' ||
  $echo 'restore of' 'file2.cc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'file2.cc:' 'MD5 check failed'
6131da20a5745dd67d82c45ea3d467fa  file2.cc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'file2.cc'`"
    test 610 -eq "$shar_count" ||
    $echo 'file2.cc:' 'original size' '610,' 'current size' "$shar_count!"
  fi
fi
# ============= file3.cc ==============
if test -f 'file3.cc' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'file3.cc' '(file already exists)'
else
  $echo 'x -' extracting 'file3.cc' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'file3.cc' &&
#include "file1.h"
#include "file2.h"
#include <stdio.h>
X
extern int reveal();
X
main()
{
X    printf("%d\n",reveal());
}
SHAR_EOF
  $shar_touch -am 1013085398 'file3.cc' &&
  chmod 0644 'file3.cc' ||
  $echo 'restore of' 'file3.cc' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'file3.cc:' 'MD5 check failed'
fc6992c7d8a0effb8c2094e724bc8c96  file3.cc
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'file3.cc'`"
    test 120 -eq "$shar_count" ||
    $echo 'file3.cc:' 'original size' '120,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh26951
exit 0



More information about the Gcc-bugs mailing list