Skip to content

Instantly share code, notes, and snippets.

@adamkaplan
Last active September 5, 2015 00:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamkaplan/3c69fda47bf02790a860 to your computer and use it in GitHub Desktop.
Save adamkaplan/3c69fda47bf02790a860 to your computer and use it in GitHub Desktop.

Compile With AST (OSX Yosemite)

clang -fsyntax-only -v -framework Foundation EXPExpect.m -Xclang -ast-dump

Warnings (should be 2)

EXPExpect.m:25:5: warning: property access result unused - getters should not be used for side effects [-Wunused-getter-return-value]
    (expect).beNil;
    ^~~~~~~~~~~~~~

AST

|-ObjCInterfaceDecl 0x10312e5a0 <EXPExpect.m:9:1, line:11:2> line:9:12 EXPExpect
| |-super ObjCInterface 0x1030b3550 'NSObject'
| |-ObjCImplementation 0x10312e860 'EXPExpect'
| `-ObjCMethodDecl 0x10312e7d0 <line:10:1, col:24> col:1 - beNil 'void (^)(void)'
|-ObjCImplementationDecl 0x10312e860 <line:13:1, line:15:1> line:13:17 EXPExpect
| |-ObjCInterface 0x10312e5a0 'EXPExpect'
| `-ObjCMethodDecl 0x10312ea00 <line:14:1, col:39> col:1 - beNil 'void (^)(void)'
|   |-ImplicitParamDecl 0x10312eac0 <<invalid sloc>> <invalid sloc> implicit self 'EXPExpect *'
|   |-ImplicitParamDecl 0x10312eb20 <<invalid sloc>> <invalid sloc> implicit _cmd 'SEL':'SEL *'
|   `-CompoundStmt 0x10312ec28 <col:25, col:39>
|     `-ReturnStmt 0x10312ec08 <col:27, /usr/include/sys/_types.h:52:33>
|       `-ImplicitCastExpr 0x10312ebf0 <col:23, col:33> 'void (^)(void)' <NullToPointer>
|         `-ParenExpr 0x10312ebd0 <col:23, col:33> 'void *'
|           `-CStyleCastExpr 0x10312eba8 <col:24, col:32> 'void *' <NullToPointer>
|             `-IntegerLiteral 0x10312eb78 <col:32> 'int' 0
|-FunctionDecl 0x10312ec80 <EXPExpect.m:17:1, line:20:1> line:17:6 noWarning 'void ()'
| `-CompoundStmt 0x10312ee38 <col:18, line:20:1>
|   `-PseudoObjectExpr 0x10312ee10 <line:7:16, line:19:12> 'void (^)(void)'
|     |-ObjCPropertyRefExpr 0x10312edb0 <line:7:16, line:19:12> '<pseudo-object type>' lvalue objcproperty Kind=MethodRef Getter="beNil" Setter="(null)" Messaging=Getter
|     | `-OpaqueValueExpr 0x10312ed90 <line:7:16, col:30> 'EXPExpect *'
|     |   `-ObjCMessageExpr 0x10312ed30 <col:16, col:30> 'EXPExpect *' selector=new class='EXPExpect'
|     |-OpaqueValueExpr 0x10312ed90 <col:16, col:30> 'EXPExpect *'
|     | `-ObjCMessageExpr 0x10312ed30 <col:16, col:30> 'EXPExpect *' selector=new class='EXPExpect'
|     `-ObjCMessageExpr 0x10312ede0 <line:19:12> 'void (^)(void)' selector=beNil
|       `-OpaqueValueExpr 0x10312ed90 <line:7:16, col:30> 'EXPExpect *'
|         `-ObjCMessageExpr 0x10312ed30 <col:16, col:30> 'EXPExpect *' selector=new class='EXPExpect'
`-FunctionDecl 0x10312ee80 <line:22:1, line:26:1> line:22:6 okWarning 'void ()'
  `-CompoundStmt 0x10312f058 <col:18, line:26:1>
    `-PseudoObjectExpr 0x10312f030 <line:25:5, col:14> 'void (^)(void)'
      |-ObjCPropertyRefExpr 0x10312efd0 <col:5, col:14> '<pseudo-object type>' lvalue objcproperty Kind=MethodRef Getter="beNil" Setter="(null)" Messaging=Getter
      | `-OpaqueValueExpr 0x10312efb0 <col:5, col:12> 'EXPExpect *'
      |   `-ParenExpr 0x10312ef60 <col:5, col:12> 'EXPExpect *'
      |     `-ObjCMessageExpr 0x10312ef30 <line:7:16, col:30> 'EXPExpect *' selector=new class='EXPExpect'
      |-OpaqueValueExpr 0x10312efb0 <line:25:5, col:12> 'EXPExpect *'
      | `-ParenExpr 0x10312ef60 <col:5, col:12> 'EXPExpect *'
      |   `-ObjCMessageExpr 0x10312ef30 <line:7:16, col:30> 'EXPExpect *' selector=new class='EXPExpect'
      `-ObjCMessageExpr 0x10312f000 <line:25:14> 'void (^)(void)' selector=beNil
        `-OpaqueValueExpr 0x10312efb0 <col:5, col:12> 'EXPExpect *'
          `-ParenExpr 0x10312ef60 <col:5, col:12> 'EXPExpect *'
            `-ObjCMessageExpr 0x10312ef30 <line:7:16, col:30> 'EXPExpect *' selector=new class='EXPExpect'
// Missing 'result unused' warning demo
// Correct: expect.beNil();
// Wrong: expect.beNil;
#import <Foundation/NSObject.h>
#define expect [EXPExpect new]
@interface EXPExpect : NSObject
- (void(^)(void)) beNil;
@end
@implementation EXPExpect
- (void(^)(void)) beNil { return nil; }
@end
void noWarning() {
// This expression should produce a warning: either result is unused or getter causes side effects
expect.beNil;
}
void okWarning() {
// This expression produces the correct warning:
// EXPExpect.m:24:5: Property access result unused - getters should not be used for side effects
(expect).beNil;
}
@adamkaplan
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment