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

            Bug ID: 66316
           Summary: Usage of wrong template function for classes in
                    different modules but having the same name
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: trufanovan at gmail dot com
  Target Milestone: ---

gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13) 
Full gcc -v output is here: http://pastebin.com/apZhYVUU

gcc is used via latest QtCreator. The problem is reproducible in debug build
mode only. Unfortunately, I don't know which gcc parameters Qt toolchain is
using with debug builds.

Additional parameters specified in my project file: -std=c++11 (may be
irrelevant - didn't check)

Original problem description:
https://github.com/JohnLangford/vowpal_wabbit/issues/655

Description:

Application has two .cpp modules. Let's say 1.cpp and 2.cpp.
In each module there is a definition of struct N. Name N is the same for both.
So we have two different structure declarations with the same name N. Compiler
gives ok for such naming as they are not exposed from their modules and used
internally in them. No namespaces are used.

And structures have different number of fields. One has 1 field and another is
6 fields long.

There is also a template function in a header file 3.h which is used in both (
1.cpp and 2.cpp) for objects allocation. It's:

template<class T> 
T* calloc_or_die()
{
  void* data = calloc(1, sizeof(T));
  if (data == nullptr) throw std::exception();
  return (T*)data;
}

Its usage:
 N& data& = *calloc_or_die<N>(); // same usage for both modules

Both cpp files call this function each for its own structure N.

The problem is in following:

In debug builds compiler might use calloc_or_die<N> implementation of one
struct to allocate memory for another. As they have different number of fields
the sizeof(T) will be different. So you might allocate 8 bites (1 field struct)
but access it via pointer to struct with size 48 bites (6 field struct). In
this case if you once write something to fields #2-#6 the app will eventually
randomly crashes with SEGFAULT at some free() function call. free() may be
called even not for these classes. It just some memory corruption flag that
raised after accessing unallocated memory block or something like that.

Valgrind used with -fmudflap flag is able to detect line where memory
corruption happens. Thus I was able to debug this.

I believe that compiler mistakenly links to a wrong implementation of
calloc_or_die<N>. The problem was workarounded by simple renaming struct N
declaration in one of modules to M.

Reply via email to