Почему этот код дает сбой при компиляции с помощью Apple LLVM, но не в LLVM/GCC?

Я пытаюсь получить этот код: http://code.google.com/p/switchcontrol/source/browse/trunk/code/AFSwitchControl.m компилируется под Apple LLVM в Xcode 4.5.2. Он работает при компиляции с LLVM/GCC, но падает в методе mouseDown при переключении на Apple LLVM в строке 198:

NSRect knobRect = _AFSwitchControlKnobRectForInsetBackground(slotRect, _offset);

Потому что _offset не установлен. Предполагается, что это должно быть установлено в методе привязки с помощью этой строки:

[self setOffset:(CGFloat)[self state]];

Но похоже, что в LLVM по какой-то причине ничего не устанавливается. Мой связывающий вызов выглядит так:

[control bind:NSValueBinding toObject:self withKeyPath:@"isToggleSwitchOn" options:nil];

Любые идеи, почему состояние элемента управления ничего не возвращает в LLVM? Спасибо!


person K_T    schedule 22.11.2012    source источник


Ответы (1)


Проблема на самом деле несколькими строками выше, в вызове _AFSwitchControlPartRects.

- (void)mouseDown:(NSEvent *)event {
    NSRect textRect, backgroundRect;
    _AFSwitchControlPartRects([self bounds], &textRect, &backgroundRect);

    NSRect slotRect = _AFSwitchControlInsetBackgroundRect(backgroundRect);
    NSRect knobRect = _AFSwitchControlKnobRectForInsetBackground(slotRect, _offset);

Второй аргумент _AFSwitchControlPartRects, &textRect — это указатель на прямоугольник.

Однако в реализации функции этот параметр должен быть указателем на достаточное пространство для двух прямоугольников.

NS_INLINE void _AFSwitchControlPartRects(NSRect bounds, NSRect *textRects, NSRect *backgroundRect) {
    NSDivideRect(bounds, textRects, backgroundRect, NSWidth(bounds)/5.0, NSMinXEdge);

    textRects[1] = _AFSwitchControlInsetTextRect(NSOffsetRect(textRects[0], NSWidth(*backgroundRect), 0));
    textRects[0] = _AFSwitchControlInsetTextRect(textRects[0]);

Когда это пишет в textRects[1], оно копается в стеке -mouseDown. Переполнение буфера.

Мне кажется, что это происходит, чтобы уничтожить себя, поэтому следующее разыгрывание себя умрет. Это связано с использованием _offset.

person Ken    schedule 22.09.2013
comment
Спасибо! Я изменил его на NSRect textRect[2] и вместо этого вызвал _AFSwitchControlPartRects([selfbounds], textRect, &backgroundRect). - person K_T; 23.09.2013