Pass arguments correctly to the objc object checker on arm64

Traditionally objc had two entry points, objc_msgSend for scalar
return methods, and objc_msgSend_stret for struct return convention
methods.  But on arm64 the second was not needed (since arm64 doesn't
use an argument register for the struct return pointer) so it was removed.

The code that dispatches to the objc object checker when it sees some
flavor of objc_msgSend was not aware of this change so was sending the
wrong arguments to the checker.

<rdar://problem/48315890>

Differential Revision: https://reviews.llvm.org/D58699

llvm-svn: 355026
This commit is contained in:
Jim Ingham 2019-02-27 20:27:25 +00:00
parent 288a95fc8c
commit b12ac2b689
3 changed files with 39 additions and 2 deletions

View File

@ -18,6 +18,8 @@ class ObjCCheckerTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@ -77,3 +79,16 @@ class ObjCCheckerTestCase(TestBase):
# Make sure the error is helpful:
err_string = expr_error.GetCString()
self.assertTrue("selector" in err_string)
#
# Check that we correctly insert the checker for an
# ObjC method with the struct return convention.
# Getting this wrong would cause us to call the checker
# with the wrong arguments, and the checker would crash
# So I'm just checking "expression runs successfully" here:
#
expr_value = frame.EvaluateExpression("[my_simple getBigStruct]", False)
expr_error = expr_value.GetError()
self.assertTrue(expr_error.Success())

View File

@ -1,11 +1,19 @@
#import <Foundation/Foundation.h>
// This should be a big enough struct that it will force
// the struct return convention:
typedef struct BigStruct {
float a, b, c, d, e, f, g, h, i, j, k, l;
} BigStruct;
@interface Simple : NSObject
{
int _value;
}
- (int) value;
- (void) setValue: (int) newValue;
- (BigStruct) getBigStruct;
@end
@implementation Simple
@ -18,6 +26,13 @@
{
_value = newValue;
}
- (BigStruct) getBigStruct
{
BigStruct big_struct = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0,
7.0, 8.0, 9.0, 10.0, 11.0, 12.0};
return big_struct;
}
@end
int main ()

View File

@ -424,8 +424,15 @@ protected:
switch (msgSend_types[inst]) {
case eMsgSend:
case eMsgSend_fpret:
target_object = call_inst->getArgOperand(0);
selector = call_inst->getArgOperand(1);
// On arm64, clang uses objc_msgSend for scalar and struct return
// calls. The call instruction will record which was used.
if (call_inst->hasStructRetAttr()) {
target_object = call_inst->getArgOperand(1);
selector = call_inst->getArgOperand(2);
} else {
target_object = call_inst->getArgOperand(0);
selector = call_inst->getArgOperand(1);
}
break;
case eMsgSend_stret:
target_object = call_inst->getArgOperand(1);