You are right. It is more code to move this into where check is made for 
!S.NSNumberDecl as NSNumberPointer
need be initialized in couple of places. Your patch is fine.
- Fariborz

> On Feb 16, 2015, at 11:38 AM, AlexDenisov <[email protected]> wrote:
> 
> Well, it was there.
> Let’s consider we have this code:
> 
> @class NSNumber;
> 
> void checkNSNumberFDDiagnostic() {
>     id num = @1000;
> }
> 
> @interface NSNumber
> + (NSNumber *)numberWithInt:(int)value;
> @end
> 
> int main() {
>     id num = @1000;
> }
> 
> Parser finds first @1000 and tries to create literal expression, 
> S.NSNumberDecl is nil in this case, so it created NSNumberDecl from forward 
> declaration _and_ it fills NSNumberPointer with NULL type and then fails with 
> error, because class NSNumber is not defined.
> 
> Then, is finds second @1000 and tries to create literal, NSNumber is defined 
> now and has numberWithInt method, everything is fine and seems legit. Then it 
> finally attempts to create literal and passes there NULL type 
> (NSNumberPointer), which is cause the crash.
> 
> Maybe I used a wrong place to solve the problem, but it’s the only place that 
> I’ve found.
> I’d appreciate any suggestions how to improve this code.
> -- 
> AlexDenisov
> Software Engineer, https://github.com/AlexDenisov 
> <https://github.com/AlexDenisov>
> On 16 Feb 2015 at 20:26:56, jahanian ([email protected] 
> <mailto:[email protected]>) wrote:
> 
>> 
>>> On Feb 16, 2015, at 8:17 AM, Alex Denisov <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> Author: alexdenisov
>>> Date: Mon Feb 16 10:17:05 2015
>>> New Revision: 229402
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=229402&view=rev 
>>> <http://llvm.org/viewvc/llvm-project?rev=229402&view=rev>
>>> Log:
>>> Fix crash when clang tries to build NSNumber literal after forward 
>>> declaration
>>> 
>>> Bug report: http://llvm.org/bugs/show_bug.cgi?id=22561 
>>> <http://llvm.org/bugs/show_bug.cgi?id=22561>
>>> 
>>> Clang tries to create ObjCBoxedExpression of type 'NSNumber'
>>> when 'NSNumber' has only forward declaration, this cause a crash later,
>>> when 'Sema' refers to a nil QualType of the whole expression.
>>> Please, refer to the bug report for the better explanation.
>>> 
>>> 
>>> Modified:
>>>    cfe/trunk/lib/Sema/SemaExprObjC.cpp
>>>    cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m
>>> 
>>> Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=229402&r1=229401&r2=229402&view=diff
>>>  
>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=229402&r1=229401&r2=229402&view=diff>
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Feb 16 10:17:05 2015
>>> @@ -218,7 +218,9 @@ static ObjCMethodDecl *getNSNumberFactor
>>>       S.Diag(Loc, diag::err_undeclared_nsnumber);
>>>       return nullptr;
>>>     }
>>> -    
>>> +  }
>>> +
>>> +  if (S.NSNumberPointer.isNull()) {
>> 
>> Creation of NSNumberPointer should go inside if (!S.NSNumberDecl) 
>> which is right before this code. 
>> 
>> - Fariborz
>> 
>>>     // generate the pointer to NSNumber type.
>>>     QualType NSNumberObject = CX.getObjCInterfaceType(S.NSNumberDecl);
>>>     S.NSNumberPointer = CX.getObjCObjectPointerType(NSNumberObject);
>>> 
>>> Modified: cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m?rev=229402&r1=229401&r2=229402&view=diff
>>>  
>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m?rev=229402&r1=229401&r2=229402&view=diff>
>>> ==============================================================================
>>> --- cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m (original)
>>> +++ cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m Mon Feb 16 10:17:05 2015
>>> @@ -9,6 +9,24 @@ typedef unsigned int NSUInteger;
>>> typedef int NSInteger;
>>> #endif
>>> 
>>> +void checkNSNumberUnavailableDiagnostic() {
>>> +  id num = @1000; // expected-error {{NSNumber must be available to use 
>>> Objective-C literals}}
>>> +
>>> +  int x = 1000;
>>> +  id num1 = @(x); // expected-error {{NSNumber must be available to use 
>>> Objective-C literals}}\
>>> +                  // expected-error {{illegal type 'int' used in a boxed 
>>> expression}}
>>> +}
>>> +
>>> +@class NSNumber;
>>> +
>>> +void checkNSNumberFDDiagnostic() {
>>> +  id num = @1000; // expected-error {{NSNumber must be available to use 
>>> Objective-C literals}}
>>> +
>>> +  int x = 1000;
>>> +  id num1 = @(x); // expected-error {{declaration of 'numberWithInt:' is 
>>> missing in NSNumber class}}\
>>> +                  // expected-error {{illegal type 'int' used in a boxed 
>>> expression}}
>>> +}
>>> +
>>> @interface NSObject
>>> + (NSObject*)nsobject;
>>> @end
>>> 
>>> 
>>> _______________________________________________
>>> cfe-commits mailing list
>>> [email protected] <mailto:[email protected]>
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits 
>>> <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits>
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to