[LLVMbugs] [Bug 10027] New: Assertion failure when calling ElaboratedTypeLoc::getTypePtr()

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Thu May 26 13:46:42 PDT 2011


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

           Summary: Assertion failure when calling
                    ElaboratedTypeLoc::getTypePtr()
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: matthewbg at google.com
                CC: llvmbugs at cs.uiuc.edu, dgregor at apple.com


Consider the following source file:
namespace S { typedef int T; }
const S::T x = 5;

A RecursiveASTVisitor with the following method will assert while visiting the
declaration of 'x':
  bool VisitVarDecl(VarDecl* decl) {
    const TypeLoc type_loc = decl->getTypeSourceInfo()->getTypeLoc();
    if (const ElaboratedTypeLoc* etype_loc =
        dyn_cast<ElaboratedTypeLoc>(&type_loc)) {
      etype_loc->getTypePtr();
    }
    return true;
  }

Here's the relevant part of the stack trace:
#6  0x0000000001626027 in __assert_fail (
    assertion=0x16791a8 "isa<X>(Val) && \"cast<Ty>() argument of incompatible
type!\"",
    file=0x1679170 "include/llvm/Support/Casting.h", line=202,
    function=0x167b960 "typename llvm::cast_retty<To, From>::ret_type
llvm::cast(const Y&) [with X = clang::ElaboratedType, Y = const clang::Type*]")
#7  0x0000000000b1ddb5 in llvm::cast<clang::ElaboratedType, clang::Type const*>
    (Val=@0x7fffffffc678)
    at include/llvm/Support/Casting.h:202
#8  0x0000000000b1c106 in clang::ConcreteTypeLoc<clang::UnqualTypeLoc,
clang::ElaboratedTypeLoc, clang::ElaboratedType,
clang::ElaboratedLocInfo>::getTypePtr (
    this=0x7fffffffc6b0)
    at tools/clang/include/clang/AST/TypeLoc.h:311
#9  0x0000000000af84f5 in BugReproVisitor::VisitVarDecl (this=0x7ffff6bbfe20,
    decl=0x7ffff7f5e450) at repro.cc:22

Here's ElaboratedTypeLoc's getTypePtr(); TypeClass is ElaboratedType and Base
is UnqualTypeLoc:
  const TypeClass *getTypePtr() const {
    return cast<TypeClass>(Base::getTypePtr());
  }

The problem is that UnqualTypeLoc::getTypePtr() is returning a bogus address,
in this case 0x7ffff6c0cfc1 -- note the set low bit, that is, the type that was
stored in the TypeSourceInfo is actually a QualType with a const qualifier.
Oops. Tracing the source of this bit, apparently we build the VarDecl's
TypeSourceInfo from a QualType to which we explicitly add qualifiers (in
ConvertDeclSpecToType()).

There are a couple of hacks that could fix the immediate problem, such as
changing ElaboratedTypeLoc to inherit from QualifiedTypeLoc instead of
UnqualTypeLoc. However, QualifiedTypeLoc does not appear to have gotten much
traction in the codebase, and the TypeLoc type hierarchy has some strange
behavior (see e.g. UnqualTypeLoc::classof(const TypeLoc*)). Maybe it's time to
rip out UnqualTypeLoc and QualifiedTypeLoc, and just deal in QualTypes
everywhere.

-- 
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