[llvm-bugs] [Bug 28930] New: Two classes with same name cause a runtime error

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Aug 10 15:33:30 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=28930

            Bug ID: 28930
           Summary: Two classes with same name cause a runtime error
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: krasin at google.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

Created attachment 16933
  --> https://llvm.org/bugs/attachment.cgi?id=16933&action=edit
hello.cc

This issue is a minimized and somewhat modified case that we hit in the
official Chrome.

Consider two C++ files:

hello.cc:
==========================================

#include <stdio.h>

class Foo {
 public:
  virtual void Do() {
    printf("A: do\n");
  }
};

void* CreateA() {
  Foo* foo = new Foo();
  printf("CreateA: %p\n", foo);
  return foo;
}

void* CreateB();
void UseB(void* obj);

int main(void) {
  void *b = CreateB();
  UseB(b);

  void *a = CreateA();

====================================


b.cc
====================================

#include <stdio.h>

class Foo {
 public:
  virtual void Do() {
    printf("B: do\n");
  }

  virtual void Do2() {
    printf("B: do2\n");
  }
};

void* CreateB() {
  Foo* obj = new Foo();
  printf("CreateB: %p\n", obj);
  return obj;
}

void UseB(void *obj) {
  printf("UseB(%p), begin\n", obj);
  Foo* foo = reinterpret_cast<Foo*>(obj);
  foo->Do();
  foo->Do2();
  printf("UseB(%p), end\n", obj);
}

====================================


As we can see, class Foo is defined in two translation units, but the uses are
isolated. Still, there's a name collision in the global namespace, so a linker
is in its right to throw an error about that, or it could rename the types to
avoid the collision. Let's compile and run:

$ clang++ -o hello hello.cc b.cc && ./hello
CreateB: 0x143a010
UseB(0x143a010), begin
A: do
Segmentation fault (core dumped)

Nice! Instead of creating Foo defined in b.cc, CreateB instantiated the Foo
defined in hello.cc, and then UseB caused a segfault while trying to access the
second virtual method, because Foo defined in hello.cc has just one.

It's not good that we were able to compile a malformed program and the compiler
didn't object. At the same time, it's probably hard to blame Clang here, as it
does not see the whole program, and the linker does not know about LLVM.

Let's try with LTO:

$ clang++ -o hello hello.cc b.cc -flto -fuse-ld=lld && ./hello
CreateB: 0x1c4e010
UseB(0x1c4e010), begin
A: do
Segmentation fault (core dumped)

Same thing, but here we actually have an ability to detect a problem and
complain or rename the type and avoid the collision.

It does not feel okay to pretend that everything is fine with the program.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160810/4d395b87/attachment.html>


More information about the llvm-bugs mailing list