forked from OSchip/llvm-project
[TypeSystem] Fix inspection of Objective-C object types
ptr_refs exposed a problem in ClangASTContext's implementation: it uses an accessor to downcast a QualType to an ObjCObjectPointerType, but the accessor is not fully general. getAs() is the safer way to go. I've added a test case that uses ptr_refs in a way that would crash before the fix. <rdar://problem/31363513> llvm-svn: 303110
This commit is contained in:
parent
8b96c7e9b5
commit
732a6f432e
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
OBJC_SOURCES := main.m
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -0,0 +1,50 @@
|
|||
"""
|
||||
Test the ptr_refs tool on Darwin with Objective-C
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import lldb
|
||||
from lldbsuite.test.decorators import *
|
||||
from lldbsuite.test.lldbtest import *
|
||||
from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
class TestPtrRefsObjC(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
@skipUnlessDarwin
|
||||
def test_ptr_refs(self):
|
||||
"""Test the ptr_refs tool on Darwin with Objective-C"""
|
||||
self.build()
|
||||
exe_name = 'a.out'
|
||||
exe = os.path.join(os.getcwd(), exe_name)
|
||||
|
||||
target = self.dbg.CreateTarget(exe)
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
|
||||
main_file_spec = lldb.SBFileSpec('main.m')
|
||||
breakpoint = target.BreakpointCreateBySourceRegex(
|
||||
'break', main_file_spec)
|
||||
self.assertTrue(breakpoint and
|
||||
breakpoint.GetNumLocations() == 1,
|
||||
VALID_BREAKPOINT)
|
||||
|
||||
process = target.LaunchSimple(
|
||||
None, None, self.get_process_working_directory())
|
||||
self.assertTrue(process, PROCESS_IS_VALID)
|
||||
|
||||
# Frame #0 should be on self.line1 and the break condition should hold.
|
||||
thread = lldbutil.get_stopped_thread(
|
||||
process, lldb.eStopReasonBreakpoint)
|
||||
self.assertTrue(
|
||||
thread.IsValid(),
|
||||
"There should be a thread stopped due to breakpoint condition")
|
||||
|
||||
frame = thread.GetFrameAtIndex(0)
|
||||
|
||||
self.dbg.HandleCommand("script import lldb.macosx.heap")
|
||||
self.expect("ptr_refs self", substrs=["malloc", "stack"])
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
//===-- main.c --------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MyClass : NSObject {
|
||||
};
|
||||
-(void)test;
|
||||
@end
|
||||
|
||||
@implementation MyClass
|
||||
-(void)test {
|
||||
printf("%p\n", self); // break here
|
||||
}
|
||||
@end
|
||||
|
||||
@interface MyOwner : NSObject {
|
||||
@public id ownedThing; // should be id, to test <rdar://problem/31363513>
|
||||
};
|
||||
@end
|
||||
|
||||
@implementation MyOwner
|
||||
@end
|
||||
|
||||
int main (int argc, char const *argv[]) {
|
||||
@autoreleasepool {
|
||||
MyOwner *owner = [[MyOwner alloc] init];
|
||||
owner->ownedThing = [[MyClass alloc] init];
|
||||
[(MyClass*)owner->ownedThing test];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4493,7 +4493,7 @@ ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
|
|||
|
||||
case clang::Type::ObjCObjectPointer: {
|
||||
const clang::ObjCObjectPointerType *objc_class_type =
|
||||
qual_type->getAsObjCInterfacePointerType();
|
||||
qual_type->getAs<clang::ObjCObjectPointerType>();
|
||||
const clang::ObjCInterfaceType *objc_interface_type =
|
||||
objc_class_type->getInterfaceType();
|
||||
if (objc_interface_type &&
|
||||
|
@ -4602,7 +4602,7 @@ ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
|
|||
|
||||
case clang::Type::ObjCObjectPointer: {
|
||||
const clang::ObjCObjectPointerType *objc_class_type =
|
||||
qual_type->getAsObjCInterfacePointerType();
|
||||
qual_type->getAs<clang::ObjCObjectPointerType>();
|
||||
const clang::ObjCInterfaceType *objc_interface_type =
|
||||
objc_class_type->getInterfaceType();
|
||||
if (objc_interface_type &&
|
||||
|
@ -5671,7 +5671,7 @@ uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
|
|||
|
||||
case clang::Type::ObjCObjectPointer: {
|
||||
const clang::ObjCObjectPointerType *objc_class_type =
|
||||
qual_type->getAsObjCInterfacePointerType();
|
||||
qual_type->getAs<clang::ObjCObjectPointerType>();
|
||||
const clang::ObjCInterfaceType *objc_interface_type =
|
||||
objc_class_type->getInterfaceType();
|
||||
if (objc_interface_type &&
|
||||
|
@ -5819,7 +5819,7 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
|
|||
|
||||
case clang::Type::ObjCObjectPointer: {
|
||||
const clang::ObjCObjectPointerType *objc_class_type =
|
||||
qual_type->getAsObjCInterfacePointerType();
|
||||
qual_type->getAs<clang::ObjCObjectPointerType>();
|
||||
const clang::ObjCInterfaceType *objc_interface_type =
|
||||
objc_class_type->getInterfaceType();
|
||||
if (objc_interface_type &&
|
||||
|
|
Loading…
Reference in New Issue