This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[RFA:] New test for bug in --gc-sections: selective6


I'm trying to prepare a presentation, where a paragraph mentions the
benefits of --gc-sections et al.  (Clouded by the fact that it only works
with -static, bummer...)

I wrote some example code to show, where it seems I catch myself lying
about what --gc-sections really does, when used together with the
corresponding GCC option, -fvtable-gc.

Here's a test, selective6, based on selective5 (4.cc), in which functions
to-be-dropped cause a .vtable_entry mark to be emitted, but where it sem
that mark is not in turn garbage-collected, as I believe it should: B::foo
is there, as well as drop1 and drop2 for some reason, perhaps another bug.

Right now I don't know whether it is fixable or if there's a built-in
limitation.  I hope to give it a try.

The test fails with assembly output from reasonably-current gcc CVS
i686-pc-linux-gnulibc1 20000923 (and much earlier too), but works for the
other test-cases in selective.exp, and the assembly code looks right,
modulo an unrelated but harmless extra "*" from label mishandling of
'__asm__ ("_start")'.  BTW; that's a bad assumption about the start-label
for a target.  Right now I'm not looking into fixing it, though.

Ok to commit?

2000-09-24  Hans-Peter Nilsson  <hp@bitrange.com>

	* ld-selective/5.cc: New test.
	* ld-selective/selective.exp: Run it as xfailed.

Index: selective.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-selective/selective.exp,v
retrieving revision 1.7
diff -p -c -r1.7 selective.exp
*** selective.exp	2000/09/05 04:07:46	1.7
--- selective.exp	2000/09/24 19:48:47
*************** set test2 "selective2"
*** 32,37 ****
--- 32,38 ----
  set test3 "selective3"
  set test4 "selective4"
  set test5 "selective5"
+ set test6 "selective6"
  
  set cflags "-w -O2 -ffunction-sections -fdata-sections"
  set cxxflags "-fvtable-gc -fno-exceptions -fno-rtti"
*************** if { [which $CXX] == 0 } {
*** 43,48 ****
--- 44,50 ----
      untested $test3
      untested $test4
      untested $test5
+     untested $test6
      return
  }
  
*************** if ![ld_simple_link $ld tmpdir/4.x "$ldf
*** 191,193 ****
--- 193,242 ----
  	}
      }
  }
+ 
+ if { ![ld_compile "$CC $cflags $cxxflags" $srcdir/$subdir/5.cc tmpdir/5.o]} {
+     unresolved $test6
+     return
+ }
+ 
+ # Exposes a bug, currently.  FIXME: Fix it.
+ # FIXME: Break out the nesting to a function that takes two lists, one
+ # with expected present symbols, one with expected absent symbols, and
+ # iterates over nm output.  Use that function in all tests here.
+ 
+ setup_xfail "*-*-*"
+ 
+ if ![ld_simple_link $ld tmpdir/5.x "$ldflags tmpdir/5.o"] {
+     fail $test6
+ } else {
+     if ![ld_nm $nm tmpdir/5.x] {
+ 	unresolved $test6
+     } else {
+ 	if {[info exists nm_output(foo__1B)]} {
+             send_log "foo__1B == $nm_output(foo__1B)\n"
+             verbose "foo__1B == $nm_output(foo__1B)"
+ 	    fail $test6
+ 	} else {
+ 	    if {[info exists nm_output(foo__1A)]} {
+ 	        send_log "foo__1A == $nm_output(foo__1A)\n"
+ 		verbose "foo__1A == $nm_output(foo__1A)"
+ 		fail $test6
+ 	    } else {
+ 		if {[info exists nm_output(dropme1__Fv)]} {
+ 		    send_log "dropme1__Fv == $nm_output(dropme1__Fv)\n"
+ 		    verbose "dropme1__Fv == $nm_output(dropme1__Fv)"
+ 		    fail $test6
+ 		} else {
+ 		    if {[info exists nm_output(dropme2__Fv)]} {
+ 			send_log "dropme2__Fv == $nm_output(dropme2__Fv)\n"
+ 			verbose "dropme2__Fv == $nm_output(dropme2__Fv)"
+ 			fail $test6
+ 		    } else {
+ 			pass $test6
+ 		    }
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
*** /dev/null	Tue Jan  1 05:00:00 1980
--- 5.cc	Sun Sep 24 21:02:51 2000
***************
*** 0 ****
--- 1,32 ----
+ struct A
+ {
+   virtual void foo();
+   virtual void bar();
+ };
+ 
+ void A::foo() { }			// loose
+ void A::bar() { }			// keep
+ 
+ struct B : public A
+ {
+   virtual void foo();
+ };
+ 
+ void B::foo() { }			// loose
+ 
+ void _start() __asm__("_start");	// keep
+ 
+ A a;					// keep
+ B b;
+ A *getme() { return &a; }		// keep
+ 
+ extern B* dropme2();
+ void dropme1() { dropme2()->foo(); }	// loose
+ B *dropme2() { return &b; }		// loose
+ 
+ void _start()
+ {
+   getme()->bar();
+ }
+ 
+ extern "C" void __main() { }

brgds, H-P


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]