[LLVMbugs] [Bug 11803] New: Disregarding [except.handle]/p1 (catching incomplete types) leads to incorrect dynamic_cast

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Thu Jan 19 10:19:29 PST 2012


http://llvm.org/bugs/show_bug.cgi?id=11803

             Bug #: 11803
           Summary: Disregarding [except.handle]/p1 (catching incomplete
                    types) leads to incorrect dynamic_cast
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: C++
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: hhinnant at apple.com
                CC: dgregor at apple.com, llvmbugs at cs.uiuc.edu
    Classification: Unclassified


Consider this code:

#include <cassert>

struct A;

void foo();

int main()
{
   try
   {
       foo();
   }
   catch (A& a)
   {
   }
   catch (...)
   {
   }
}

struct B {virtual ~B() {}};

struct A : B {};

void foo()
{
   A a;
   B* bp = &a;
   assert(dynamic_cast<A*>(bp) != 0);
}

This asserts.  But if you comment out the catch (A&) frame:

//     catch (A& a)
//     {
//     }

It runs correctly.


The issue:  When clang sees the catch(A&) (and A is incomplete at this point)
it lays down the wrong kind of type_info:  a __class_type_info.  And that never
gets corrected.  So when it comes time to do the dynamic_cast, later when A is
complete, the dynamic_cast malfunctions because the type_info for A should be a
__si_class_type_info.  Without the correct type_info, the dynamic_cast
malfunctions.

15.3 [except.handle]/p1 says that the original program is ill-formed (and clang
does give a warning about it):

<quote>
1 The exception-declaration in a handler describes the type(s) of exceptions
that can cause that handler to be entered. The exception-declaration shall not
denote an incomplete type, an abstract class type, or an rvalue reference type.
The exception-declaration shall not denote a pointer or reference to an
incomplete type, other than void*, const void*, volatile void*, or const
volatile void*.
</quote>

The reason clang has this behavior is because of:

http://llvm.org/bugs/show_bug.cgi?id=6527

The Itanium ABI says this about emitting type_info's for incomplete class
types:

<quote>
This RTTI class may also be used for incomplete class types when referenced by
a pointer RTTI, in which case it must be prevented from preempting the RTTI for
the complete class type, for instance by emitting it as a static object
(without external linkage).
</quote>

It appears that clang doesn't emit the incomplete type_info type as a static.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list