https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62204

--- Comment #1 from David Koes <koes at cmu dot edu> ---
Okay, I figured this out.  It is a use after free error. Line numbers are for
4.8.4. The root cause was that I had these two lines in different header files:

typedef long int128_t __attribute__((mode(TI))) __attribute__((aligned(8)));
typedef long int128_t __attribute__((mode(TI)));

The declaration with the alignment was processed by handle_aligned_attribute in
c-common.c:7446 where the type was copied and the declartion was set to the
type's name:
      tree tt = TREE_TYPE (decl);
      *type = build_variant_type_copy (*type);
      DECL_ORIGINAL_TYPE (decl) = tt;
      TYPE_NAME (*type) = decl;
      TREE_USED (*type) = TREE_USED (decl);
      TREE_TYPE (decl) = *type;

Later, in duplicate_decls (decl.c) the aligned declaration is newdecl and the
unaligned declaration is olddecl and newdecl is ultimately freed and clobbered,
but the pointer set in handle_aligned_attribute is still around.  The memory is
eventually reallocated and the data overwritten.  Later, when instantiating
templates, this tree pointer (now pointing to something that isn't a tree) is
accessed and the compiler crashes.

It's easy enough for me to fix my code to prevent the crash, but I generally
think that no code should make the compiler crash.

I'm not sure what the standard says (especially since this involves
__attribute__), but it seems like declaring the same type with different
alignments should probably be an error.

If this is not an error, then duplicate_decls either shouldn't merge these two
types, or should correct the tree to not refer to the stale pointer.

Reply via email to