[cfe-dev] Should a "typeinfo" variable be "linkonce_odr constant" or just "constant"

Richard Smith richard at metafoo.co.uk
Wed Aug 13 15:58:05 PDT 2014

On Tue, Aug 5, 2014 at 7:06 AM, Kostya Serebryany <kcc at google.com> wrote:

> Hello Clang folks,
> I have a question about typeinfo variables:
> % cat a1.cc
> struct AAA {
>  public:
>   virtual ~ AAA ();
> };
> AAA::~AAA() { }
> void foo () { throw AAA (); }
> % clang++ a1.cc -S -o - -emit-llvm    | grep '_ZTI3AAA.=.[^{]*' -o
> _ZTI3AAA = constant
> % clang++ a1.cc -S -o - -emit-llvm  -fno-rtti  | grep '_ZTI3AAA.=.[^{]*'
> -o
> _ZTI3AAA = linkonce_odr constant
> As you can see, depending on the compilation mode (-fno-rtti) the
> definition of _ZTI3AAA
> (typeinfo for AAA) is different.  Is that expected?

Yes, I think so: if we have a key function, we can emit the type_info as a
strong symbol with that key function, because we know there will only be
one such translation unit in the program. (We could emit the _ZTI3AAA
symbol as strong in both cases in the above program, but in the second case
we're explicitly not required to provide a definition for other TUs, so we
reduce the linkage to linkonce_odr).

This difference causes problem for AddressSanitizer, if one part of the
> code is built with
> -fno-rtti and another part w/o -fno-rtti.
> asan instruments global constants but can not instrument linkonce_odr
> variables,
> as a result we mix an instrumented and a non-instrumented global in the
> same binary.

Per the LangRef, it seems that it's permissible to have both a linkonce_odr
definition and an external definition of the same entity in the same
program, so this seems like an ASan issue. We could work around it by
reducing the linkage to linkonce_odr in the -frtti case (the global will
not be discarded because it's used by the vtable). That is apparently what
GCC does. But ASan will presumably still have problems with this:

__attribute__((weak)) int n = 1;

int n = 2;


I don't fully understand the problem here. It seems that:
  1) weak linkage globals don't get instrumented
  2) instrumented globals get 8 byte alignment
  3) you're seeing a global with both a weak definition and a non-weak
  4) the assert fails because you believe the variable is instrumented, but
it doesn't have 8 byte alignment
If so, I wonder why you're seeing the weak definition rather than the
strong, 8-byte-aligned instrumented definition that you should see?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140813/ed70ae08/attachment.html>

More information about the cfe-dev mailing list