On Thu, Nov 22, 2012 at 6:45 AM, H.J. Lu <hjl.to...@gmail.com> wrote: > Hi, > > libasan should come first before any language-specific > adjustment/addition. Otherwise, we got > > g++ -fsanitize=address -static-libasan ... > > /usr/local/bin/ld: error: > /export/build/gnu/gcc-asan/build-x86_64-linux/prev-x86_64-unknown-linux-gnu/libsanitizer/asan/.libs/libasan.a(asan_new_delete.o): > multiple definition of 'operator delete(void*)' > /usr/local/bin/ld: > /export/build/gnu/gcc-asan/build-x86_64-linux/prev-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.a(del_op.o): > previous definition here > > This patch adds prepend_lang_specific_driver to prepend command line before > language-specific adjustment/addition of flags. OK to install? > > Thanks. > > > H.J. > --- > 2012-11-22 H.J. Lu <hongjiu...@intel.com> > > PR driver/55374 > * gcc.c (prepend_lang_specific_driver): New function. > (process_command): Use it. > > diff --git a/gcc/gcc.c b/gcc/gcc.c > index 0f8bcea..41474aa 100644 > --- a/gcc/gcc.c > +++ b/gcc/gcc.c > @@ -3604,6 +3604,80 @@ set_option_handlers (struct cl_option_handlers > *handlers) > handlers->handlers[2].mask = CL_TARGET; > } > > +/* Prepend command line before language-specific adjustment/addition of > + flags. */ > + > +void > +prepend_lang_specific_driver (struct cl_decoded_option **in_decoded_options, > + unsigned int *in_decoded_options_count, > + int *in_added_libraries) > +{ > + unsigned int i, argc; > + > + /* The new argument list will be contained in this. */ > + struct cl_decoded_option *new_decoded_options; > + > + /* The argument list. */ > + struct cl_decoded_option *decoded_options; > + > + bool add_libasan = false; > + bool static_libasan = false; > + > + argc = *in_decoded_options_count; > + decoded_options = *in_decoded_options; > + > + for (i = 1; i < argc; i++) > + switch (decoded_options[i].opt_index) > + { > + case OPT_fsanitize_address: > + add_libasan = true; > + break; > + case OPT_static_libasan: > + static_libasan = true; > + break; > + } > + > + if (add_libasan) > + { > + /* Add -lasan before language-specific adjustment/addition. */ > + unsigned int added_argc; > + > + added_argc = 1; > +#ifdef HAVE_LD_STATIC_DYNAMIC > + if (static_libasan) > + added_argc += 2; > +#endif > + > + new_decoded_options = XNEWVEC (struct cl_decoded_option, > + argc + added_argc); > + > + i = 0; > + do > + { > + new_decoded_options[i] = decoded_options[i]; > + i++; > + } > + while (i < argc); > + > +#ifdef HAVE_LD_STATIC_DYNAMIC > + if (static_libasan) > + generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER, > + &new_decoded_options[i++]); > +#endif > + generate_option (OPT_l, "asan", 1, CL_DRIVER, > + &new_decoded_options[i++]); > +#ifdef HAVE_LD_STATIC_DYNAMIC > + if (static_libasan) > + generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER, > + &new_decoded_options[i++]); > +#endif > + > + *in_decoded_options_count = i; > + *in_decoded_options = new_decoded_options; > + *in_added_libraries = 1; > + } > +} > + > /* Create the vector `switches' and its contents. > Store its length in `n_switches'. */ > > @@ -3695,6 +3769,11 @@ process_command (unsigned int decoded_options_count, > or an automatically created GCC_EXEC_PREFIX from > decoded_options[0].arg. */ > > + /* Prepend command line before language-specific adjustment/addition of > + flags. */ > + prepend_lang_specific_driver (&decoded_options, &decoded_options_count, > + &added_libraries); > + > /* Do language-specific adjustment/addition of flags. */ > lang_specific_driver (&decoded_options, &decoded_options_count, > &added_libraries);
PING. A simple testcase: [hjl@gnu-6 gcc]$ cat /tmp/bad.cc #include <new> int main () { int *buf = new int(30); buf[30]=1; return 0; } [hjl@gnu-6 gcc]$ ./release/usr/gcc-4.8.0/bin/g++ -fsanitize=address /tmp/bad.cc -static-libasan -static-libstdc++ /export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libasan.a(asan_new_delete.o): In function `operator new(unsigned long)': /export/gnu/import/git/gcc/libsanitizer/asan/asan_new_delete.cc:41: multiple definition of `operator new(unsigned long)' /export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libstdc++.a(new_op.o):/export/gnu/import/git/gcc/libstdc++-v3/libsupc++/new_op.cc:45: first defined here /export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libasan.a(asan_new_delete.o): In function `operator delete(void*)': /export/gnu/import/git/gcc/libsanitizer/asan/asan_new_delete.cc:54: multiple definition of `operator delete(void*)' /export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libstdc++.a(del_op.o):/export/gnu/import/git/gcc/libstdc++-v3/libsupc++/del_op.cc:46: first defined here collect2: error: ld returned 1 exit status [hjl@gnu-6 gcc]$ [rep[hjl@gnu-6 gcc]$ cat /tmp/bad.cc #include <new> int main () { int *buf = new int(30); buf[30]=1; return 0; } [hjl@gnu-6 gcc]$ ./release/usr/gcc-4.8.0/bin/g++ -fsanitize=address /tmp/bad.cc -static-libasan -static-libstdc++ /export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libasan.a(asan_new_delete.o): In function `operator new(unsigned long)': /export/gnu/import/git/gcc/libsanitizer/asan/asan_new_delete.cc:41: multiple definition of `operator new(unsigned long)' /export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libstdc++.a(new_op.o):/export/gnu/import/git/gcc/libstdc++-v3/libsupc++/new_op.cc:45: first defined here /export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libasan.a(asan_new_delete.o): In function `operator delete(void*)': /export/gnu/import/git/gcc/libsanitizer/asan/asan_new_delete.cc:54: multiple definition of `operator delete(void*)' /export/build/gnu/gcc/release/usr/gcc-4.8.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/libstdc++.a(del_op.o):/export/gnu/import/git/gcc/libstdc++-v3/libsupc++/del_op.cc:46: first defined here collect2: error: ld returned 1 exit status [hjl@gnu-6 gcc]$ -- H.J.