diff options
author | Jordan Rupprecht <rupprecht@google.com> | 2018-12-19 02:24:12 +0000 |
---|---|---|
committer | Jordan Rupprecht <rupprecht@google.com> | 2018-12-19 02:24:12 +0000 |
commit | 55c8788102d8fd203270fabd6513247b2d7fbd87 (patch) | |
tree | 63ab727404da1afaca89c6578f37f135a50922e7 /test/Analysis | |
parent | 9fa0a1f211b7c9a402767bc895a87481cf347230 (diff) | |
parent | 46efdf2ccc2a80aefebf8433dbf9c7c959f6e629 (diff) |
Creating branches/google/stable and tags/google/stable/2018-12-18 from r349201
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/stable@349597 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis')
71 files changed, 8492 insertions, 379 deletions
diff --git a/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m b/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m index b00d71b1a4..2bf86410f3 100644 --- a/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m +++ b/test/Analysis/Checkers/RunLoopAutoreleaseLeakChecker.m @@ -1,9 +1,15 @@ -// UNSUPPORTED: system-windows -// RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak %s -triple x86_64-darwin -verify -// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP1=1 -fobjc-arc -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak %s -triple x86_64-darwin -verify -// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP2=1 -fobjc-arc -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak %s -triple x86_64-darwin -verify -// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP3=1 -fobjc-arc -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak %s -triple x86_64-darwin -verify -// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP4=1 -fobjc-arc -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak %s -triple x86_64-darwin -verify +// RUN: %clang_analyze_cc1 -fobjc-arc -triple x86_64-darwin\ +// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s +// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP1=1 -fobjc-arc -triple x86_64-darwin\ +// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s +// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP2=1 -fobjc-arc -triple x86_64-darwin\ +// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s +// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP3=1 -fobjc-arc -triple x86_64-darwin\ +// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s +// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP4=1 -fobjc-arc -triple x86_64-darwin\ +// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s +// RUN: %clang_analyze_cc1 -DEXTRA=1 -DAP5=1 -fobjc-arc -triple x86_64-darwin\ +// RUN: -analyzer-checker=core,osx.cocoa.RunLoopAutoreleaseLeak -verify %s #include "../Inputs/system-header-simulator-for-objc-dealloc.h" @@ -122,3 +128,34 @@ int main() { return 0; } #endif + +#ifdef AP5 +@class NSString; +@class NSConstantString; +#define CF_BRIDGED_TYPE(T) __attribute__((objc_bridge(T))) +typedef const CF_BRIDGED_TYPE(id) void * CFTypeRef; +typedef const struct CF_BRIDGED_TYPE(NSString) __CFString * CFStringRef; + +typedef enum { WARNING } Level; +id do_log(Level, const char *); +#define log(level, msg) __extension__({ (do_log(level, msg)); }) + +@interface I +- foo; +@end + +CFStringRef processString(const __NSConstantString *, void *); + +#define CFSTR __builtin___CFStringMakeConstantString + +int main() { + I *i; + @autoreleasepool { + NSString *s1 = (__bridge_transfer NSString *)processString(0, 0); + NSString *s2 = (__bridge_transfer NSString *)processString((CFSTR("")), ((void *)0)); + log(WARNING, "Hello world!"); + } + [[NSRunLoop mainRunLoop] run]; + [i foo]; // no-crash // expected-warning{{Temporary objects allocated in the autorelease pool of last resort followed by the launch of main run loop may never get released; consider moving them to a separate autorelease pool}} +} +#endif diff --git a/test/Analysis/Inputs/ctu-other.c b/test/Analysis/Inputs/ctu-other.c new file mode 100644 index 0000000000..9a95206110 --- /dev/null +++ b/test/Analysis/Inputs/ctu-other.c @@ -0,0 +1,49 @@ +// Test typedef and global variable in function. +typedef struct { + int a; + int b; +} FooBar; +FooBar fb; +int f(int i) { + if (fb.a) { + fb.b = i; + } + return 1; +} + +// Test enums. +enum B { x = 42, + l, + s }; +int enumCheck(void) { + return x; +} + +// Test reporting an error in macro definition +#define MYMACRO(ctx) \ + ctx->a; +struct S { + int a; +}; +int g(struct S *ctx) { + MYMACRO(ctx); + return 0; +} + +// Test that asm import does not fail. +int inlineAsm() { + int res; + asm("mov $42, %0" + : "=r"(res)); + return res; +} + +// Implicit function. +int identImplicit(int in) { + return in; +} + +// ASTImporter doesn't support this construct. +int structInProto(struct DataType {int a;int b; } * d) { + return 0; +} diff --git a/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt b/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt new file mode 100644 index 0000000000..9abaa501a4 --- /dev/null +++ b/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt @@ -0,0 +1,6 @@ +c:@F@inlineAsm ctu-other.c.ast +c:@F@g ctu-other.c.ast +c:@F@f ctu-other.c.ast +c:@F@enumCheck ctu-other.c.ast +c:@F@identImplicit ctu-other.c.ast +c:@F@structInProto ctu-other.c.ast diff --git a/test/Analysis/Inputs/externalFnMap.txt b/test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt index 5461685dc6..5461685dc6 100644 --- a/test/Analysis/Inputs/externalFnMap.txt +++ b/test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt diff --git a/test/Analysis/Inputs/expected-plists/objc-arc.m.plist b/test/Analysis/Inputs/expected-plists/objc-arc.m.plist index 977827d5ad..3f9d63e7a6 100644 --- a/test/Analysis/Inputs/expected-plists/objc-arc.m.plist +++ b/test/Analysis/Inputs/expected-plists/objc-arc.m.plist @@ -1727,12 +1727,12 @@ </dict> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: allocated object of type CFStringRef is not referenced later in this execution path and has a retain count of +1</string> <key>message</key> - <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: allocated object of type CFStringRef is not referenced later in this execution path and has a retain count of +1</string> </dict> </array> - <key>description</key><string>Potential leak of an object</string> + <key>description</key><string>Potential leak of an object of type CFStringRef</string> <key>category</key><string>Memory (Core Foundation/Objective-C)</string> <key>type</key><string>Leak</string> <key>check_name</key><string>osx.cocoa.RetainCount</string> diff --git a/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist b/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist new file mode 100644 index 0000000000..4d1d42438e --- /dev/null +++ b/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist @@ -0,0 +1,5452 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>diagnostics</key> + <array> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>25</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>25</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>26</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>26</integer> + <key>col</key><integer>21</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>26</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>26</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>26</integer> + <key>col</key><integer>21</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>27</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>27</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>27</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>27</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>27</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>27</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>27</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>26</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>SET_PTR_VAR_TO_NULL</string> + <key>expansion</key><string>ptr = 0</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>f8fbc46cc5afbb056d92bd3d3d702781</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>nonFunctionLikeMacroTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>27</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>24</integer> + <integer>25</integer> + <integer>26</integer> + <integer>27</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>38</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>38</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>39</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>39</integer> + <key>col</key><integer>39</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>39</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>39</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>39</integer> + <key>col</key><integer>39</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>40</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>40</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>40</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>40</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>40</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>40</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>40</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>39</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO</string> + <key>expansion</key><string>ptr =0</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>d5eba61193b41c27fc7b2705cbd607ba</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>nonFunctionLikeNestedMacroTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>40</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>37</integer> + <integer>38</integer> + <integer>39</integer> + <integer>40</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>58</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>58</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>59</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>59</integer> + <key>col</key><integer>9</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>59</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>59</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>59</integer> + <key>col</key><integer>15</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'setToNull'</string> + <key>message</key> + <string>Calling 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'functionLikeMacroTest'</string> + <key>message</key> + <string>Entered call from 'functionLikeMacroTest'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>59</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>59</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>59</integer> + <key>col</key><integer>15</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'setToNull'</string> + <key>message</key> + <string>Returning from 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>60</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>60</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>60</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>60</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>60</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>60</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>60</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>59</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>TO_NULL</string> + <key>expansion</key><string>setToNull(&ptr)</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>370a457744311752aac789447b4ef16c</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>functionLikeMacroTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>60</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>50</integer> + <integer>51</integer> + <integer>57</integer> + <integer>58</integer> + <integer>59</integer> + <integer>60</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>78</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>78</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>79</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>79</integer> + <key>col</key><integer>9</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>79</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>79</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>79</integer> + <key>col</key><integer>13</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'setToNull'</string> + <key>message</key> + <string>Calling 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'functionLikeNestedMacroTest'</string> + <key>message</key> + <string>Entered call from 'functionLikeNestedMacroTest'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'a'</string> + <key>message</key> + <string>Null pointer value stored to 'a'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>79</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>79</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>79</integer> + <key>col</key><integer>13</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'setToNull'</string> + <key>message</key> + <string>Returning from 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>80</integer> + <key>col</key><integer>12</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>80</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>80</integer> + <key>col</key><integer>10</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>79</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>TO_NULL</string> + <key>expansion</key><string>setToNull(&a)</string> + </dict> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>80</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>DEREF</string> + <key>expansion</key><string>{ int b; b = 5; } print(a); *a</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>873802674657bba4565f64c7bbf0ded9</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>functionLikeNestedMacroTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>80</integer> + <key>col</key><integer>12</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>50</integer> + <integer>51</integer> + <integer>77</integer> + <integer>78</integer> + <integer>79</integer> + <integer>80</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>97</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>97</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>98</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>98</integer> + <key>col</key><integer>28</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>98</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>98</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>98</integer> + <key>col</key><integer>33</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>99</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>99</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>99</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>99</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>99</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>99</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>99</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>98</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>WILL_UNDEF_SET_NULL_TO_PTR</string> + <key>expansion</key><string>ptr = nullptr;</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>79ce7ac344a15505929edba2fdf178b6</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>undefinedMacroByTheEndOfParsingTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>99</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>96</integer> + <integer>97</integer> + <integer>98</integer> + <integer>99</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>114</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>114</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>115</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>115</integer> + <key>col</key><integer>42</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>115</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>115</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>115</integer> + <key>col</key><integer>47</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>116</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>116</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>116</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>116</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>116</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>116</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>116</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>115</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL</string> + <key>expansion</key><string>ptr = nullptr;</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>cbbecfb64198aebb884f3729dff84896</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>macroRedefinedMultipleTimesTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>116</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>113</integer> + <integer>114</integer> + <integer>115</integer> + <integer>116</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>134</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>134</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>135</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>135</integer> + <key>col</key><integer>39</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>135</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>135</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>135</integer> + <key>col</key><integer>44</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>136</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>136</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>136</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>136</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>136</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>136</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>136</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>135</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>PASS_PTR_TO_MACRO_THAT_WILL_BE_UNDEFD</string> + <key>expansion</key><string>ptr = nullptr;</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>01684c77381713fd6c7be31ebc9b647a</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>undefinedMacroInsideAnotherMacroTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>136</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>133</integer> + <integer>134</integer> + <integer>135</integer> + <integer>136</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>161</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>161</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>162</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>162</integer> + <key>col</key><integer>19</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>162</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>162</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>162</integer> + <key>col</key><integer>52</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'a'</string> + <key>message</key> + <string>Null pointer value stored to 'a'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>163</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>163</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>163</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>163</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>163</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>163</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>163</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>162</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>TO_NULL_AND_PRINT</string> + <key>expansion</key><string>a = 0; print( "Will this , cause a crash?")</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>7a7344244350405a514682fe228e304e</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>macroArgContainsCommaInStringTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>163</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>160</integer> + <integer>161</integer> + <integer>162</integer> + <integer>163</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>170</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>170</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>171</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>171</integer> + <key>col</key><integer>19</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>171</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>171</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>171</integer> + <key>col</key><integer>52</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'a'</string> + <key>message</key> + <string>Null pointer value stored to 'a'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>172</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>172</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>172</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>172</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>172</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>172</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>172</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>171</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>TO_NULL_AND_PRINT</string> + <key>expansion</key><string>a = 0; print( "Will this ( cause a crash?")</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>1d6d14e3f566cec02bd1f3542e3c8044</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>macroArgContainsLParenInStringTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>172</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>169</integer> + <integer>170</integer> + <integer>171</integer> + <integer>172</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>179</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>179</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>180</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>180</integer> + <key>col</key><integer>19</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>180</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>180</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>180</integer> + <key>col</key><integer>52</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'a'</string> + <key>message</key> + <string>Null pointer value stored to 'a'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>181</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>181</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>181</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>181</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>181</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>181</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>181</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>180</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>TO_NULL_AND_PRINT</string> + <key>expansion</key><string>a = 0; print( "Will this ) cause a crash?")</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>7354d762d71f0d0a3ffc9d6d827fe580</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>macroArgContainsRParenInStringTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>181</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>178</integer> + <integer>179</integer> + <integer>180</integer> + <integer>181</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>193</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>193</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>194</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>194</integer> + <key>col</key><integer>15</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>194</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>194</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>194</integer> + <key>col</key><integer>30</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'setToNull'</string> + <key>message</key> + <string>Calling 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'macroArgContainsLParenRParenTest'</string> + <key>message</key> + <string>Entered call from 'macroArgContainsLParenRParenTest'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'a'</string> + <key>message</key> + <string>Null pointer value stored to 'a'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>194</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>194</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>194</integer> + <key>col</key><integer>30</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'setToNull'</string> + <key>message</key> + <string>Returning from 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>195</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>195</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>195</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>195</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>195</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>195</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>195</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>194</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>CALL_FUNCTION</string> + <key>expansion</key><string>setToNull(&a)</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>f00b6f77288a374e864a58609e9a42ea</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>macroArgContainsLParenRParenTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>195</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>50</integer> + <integer>51</integer> + <integer>192</integer> + <integer>193</integer> + <integer>194</integer> + <integer>195</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>207</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>207</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>208</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>208</integer> + <key>col</key><integer>15</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>208</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>208</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>208</integer> + <key>col</key><integer>48</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'setToNullAndPrint'</string> + <key>message</key> + <string>Calling 'setToNullAndPrint'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>201</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'macroArgContainsCommaLParenRParenTest'</string> + <key>message</key> + <string>Entered call from 'macroArgContainsCommaLParenRParenTest'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>201</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>201</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>11</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Calling 'setToNull'</string> + <key>message</key> + <string>Calling 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>2</integer> + <key>extended_message</key> + <string>Entered call from 'setToNullAndPrint'</string> + <key>message</key> + <string>Entered call from 'setToNullAndPrint'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>2</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'a'</string> + <key>message</key> + <string>Null pointer value stored to 'a'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Returning from 'setToNull'</string> + <key>message</key> + <string>Returning from 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>11</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>203</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>203</integer> + <key>col</key><integer>7</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>208</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>208</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>208</integer> + <key>col</key><integer>48</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'setToNullAndPrint'</string> + <key>message</key> + <string>Returning from 'setToNullAndPrint'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>209</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>209</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>209</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>209</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>209</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>209</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>209</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>208</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>CALL_FUNCTION</string> + <key>expansion</key><string>setToNullAndPrint(&a, "Hello!")</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>c5805abeb71bb4edb41b49ab317439b9</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>macroArgContainsCommaLParenRParenTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>209</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>50</integer> + <integer>51</integer> + <integer>201</integer> + <integer>202</integer> + <integer>203</integer> + <integer>206</integer> + <integer>207</integer> + <integer>208</integer> + <integer>209</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>219</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>219</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>220</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>220</integer> + <key>col</key><integer>31</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>220</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>220</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>220</integer> + <key>col</key><integer>64</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'setToNullAndPrint'</string> + <key>message</key> + <string>Calling 'setToNullAndPrint'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>201</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'macroArgContainsCommaLParenRParenTest2'</string> + <key>message</key> + <string>Entered call from 'macroArgContainsCommaLParenRParenTest2'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>201</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>201</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>11</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Calling 'setToNull'</string> + <key>message</key> + <string>Calling 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>2</integer> + <key>extended_message</key> + <string>Entered call from 'setToNullAndPrint'</string> + <key>message</key> + <string>Entered call from 'setToNullAndPrint'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>2</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'a'</string> + <key>message</key> + <string>Null pointer value stored to 'a'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Returning from 'setToNull'</string> + <key>message</key> + <string>Returning from 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>202</integer> + <key>col</key><integer>11</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>203</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>203</integer> + <key>col</key><integer>7</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>220</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>220</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>220</integer> + <key>col</key><integer>64</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'setToNullAndPrint'</string> + <key>message</key> + <string>Returning from 'setToNullAndPrint'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>221</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>221</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>221</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>221</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>221</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>221</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>221</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>220</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>CALL_FUNCTION_WITH_TWO_PARAMS</string> + <key>expansion</key><string>setToNullAndPrint( &a, "Hello!")</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>4014a22ef054933e6ce9be43623ea85e</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>macroArgContainsCommaLParenRParenTest2</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>221</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>50</integer> + <integer>51</integer> + <integer>201</integer> + <integer>202</integer> + <integer>203</integer> + <integer>218</integer> + <integer>219</integer> + <integer>220</integer> + <integer>221</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>231</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>231</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>13</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>58</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'operator()'</string> + <key>message</key> + <string>Calling 'operator()'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'commaInBracketsTest'</string> + <key>message</key> + <string>Entered call from 'commaInBracketsTest'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>58</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Calling 'setToNull'</string> + <key>message</key> + <string>Calling 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>2</integer> + <key>extended_message</key> + <string>Entered call from 'operator()'</string> + <key>message</key> + <string>Entered call from 'operator()'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>2</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>58</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Returning from 'setToNull'</string> + <key>message</key> + <string>Returning from 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>58</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'operator()'</string> + <key>message</key> + <string>Returning from 'operator()'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>236</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>236</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>236</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>236</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>236</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>236</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>236</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>CALL_LAMBDA</string> + <key>expansion</key><string>([&ptr, str] () mutable { setToNull(&ptr); })()</string> + </dict> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>235</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>CALL_LAMBDA</string> + <key>expansion</key><string>([&ptr, str] () mutable { setToNull(&ptr); })()</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>a8918c38ddfa6a991701e7d19c9cd6bb</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>commaInBracketsTest</string> + <key>issue_hash_function_offset</key><string>6</string> + <key>location</key> + <dict> + <key>line</key><integer>236</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>50</integer> + <integer>51</integer> + <integer>230</integer> + <integer>231</integer> + <integer>232</integer> + <integer>235</integer> + <integer>236</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>246</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>246</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>254</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>'ptr' initialized to a null pointer value</string> + <key>message</key> + <string>'ptr' initialized to a null pointer value</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>246</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>246</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>254</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>246</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>PASTE_CODE</string> + <key>expansion</key><string>{ int *ptr = nullptr; *ptr = 5; }</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>63042e03ae0d2f3832b141a63b1d4d49</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>commaInBracesTest</string> + <key>issue_hash_function_offset</key><string>1</string> + <key>location</key> + <dict> + <key>line</key><integer>246</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>245</integer> + <integer>246</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>268</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>268</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>270</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>270</integer> + <key>col</key><integer>25</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>270</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>270</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>270</integer> + <key>col</key><integer>31</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>271</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>271</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>271</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>271</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>271</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>271</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>271</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>270</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>POTENTIALLY_EMPTY_PARAM</string> + <key>expansion</key><string>;ptr = nullptr</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>cd980e278fbcd8f77bbeac79285084e2</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>emptyParamTest</string> + <key>issue_hash_function_offset</key><string>4</string> + <key>location</key> + <dict> + <key>line</key><integer>271</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>267</integer> + <integer>268</integer> + <integer>270</integer> + <integer>271</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>282</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>282</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>284</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>284</integer> + <key>col</key><integer>20</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>284</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>284</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>284</integer> + <key>col</key><integer>27</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>285</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>285</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>285</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>285</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>285</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>285</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>285</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>284</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>NESTED_EMPTY_PARAM</string> + <key>expansion</key><string>; ptr = nullptr;</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>f6a5f6c93b6e3734842ddabd3d5a7341</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>nestedEmptyParamTest</string> + <key>issue_hash_function_offset</key><string>4</string> + <key>location</key> + <dict> + <key>line</key><integer>285</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>281</integer> + <integer>282</integer> + <integer>284</integer> + <integer>285</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>295</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>295</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>296</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>296</integer> + <key>col</key><integer>44</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>296</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>296</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>296</integer> + <key>col</key><integer>61</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'setToNull'</string> + <key>message</key> + <string>Calling 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'lParenRParenInNestedMacro'</string> + <key>message</key> + <string>Entered call from 'lParenRParenInNestedMacro'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>50</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>51</integer> + <key>col</key><integer>17</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>296</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>296</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>296</integer> + <key>col</key><integer>61</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Returning from 'setToNull'</string> + <key>message</key> + <string>Returning from 'setToNull'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>297</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>297</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>297</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>297</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>297</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>297</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>297</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>296</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO</string> + <key>expansion</key><string>setToNull( &ptr)</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>ff00c8344e685317303e814970082d5f</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>lParenRParenInNestedMacro</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>297</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>50</integer> + <integer>51</integer> + <integer>294</integer> + <integer>295</integer> + <integer>296</integer> + <integer>297</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>315</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>315</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>316</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>316</integer> + <key>col</key><integer>22</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>316</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>316</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>316</integer> + <key>col</key><integer>42</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>317</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>317</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>317</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>317</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>317</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>317</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>317</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>316</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>VARIADIC_SET_TO_NULL</string> + <key>expansion</key><string>ptr = nullptr; variadicFunc( 1, 5, "haha!")</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>1b0880549df23e9ce0edb60955ad5ac1</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>variadicMacroArgumentTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>317</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>314</integer> + <integer>315</integer> + <integer>316</integer> + <integer>317</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>324</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>324</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>327</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>327</integer> + <key>col</key><integer>22</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>327</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>327</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>327</integer> + <key>col</key><integer>27</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>328</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>328</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>328</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>328</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>328</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>328</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>328</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>327</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>VARIADIC_SET_TO_NULL</string> + <key>expansion</key><string>ptr = nullptr; variadicFunc()</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>6aa30fd6a1e997027333f16c2064d973</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>variadicMacroArgumentWithoutAnyArgumentTest</string> + <key>issue_hash_function_offset</key><string>5</string> + <key>location</key> + <dict> + <key>line</key><integer>328</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>323</integer> + <integer>324</integer> + <integer>327</integer> + <integer>328</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>343</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>343</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>344</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>344</integer> + <key>col</key><integer>30</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>344</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>344</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>344</integer> + <key>col</key><integer>45</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>345</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>345</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>345</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>345</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>345</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>345</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>345</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>344</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>DECLARE_FUNC_AND_SET_TO_NULL</string> + <key>expansion</key><string>void generated_whatever(); ptr = nullptr;</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>453ed8096f5394e74e16f965886e5623</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>hashHashOperatorTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>345</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>342</integer> + <integer>343</integer> + <integer>344</integer> + <integer>345</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>352</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>352</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>19</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>53</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'a'</string> + <key>message</key> + <string>Null pointer value stored to 'a'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>354</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>354</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>354</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>354</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>354</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>354</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>354</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>353</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>TO_NULL_AND_PRINT</string> + <key>expansion</key><string>a = 0; print( "Will this ## cause a crash?")</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>6817572ced27cb7d28fc87b2aba75fb4</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>macroArgContainsHashHashInStringTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>354</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>351</integer> + <integer>352</integer> + <integer>353</integer> + <integer>354</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>365</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>365</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>366</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>366</integer> + <key>col</key><integer>11</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>366</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>366</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>366</integer> + <key>col</key><integer>23</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>367</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>367</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>367</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>367</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>367</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>367</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>367</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>366</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>PRINT_STR</string> + <key>expansion</key><string>print("Hello"); ptr = nullptr</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>e6947ee72df70243a3b4c9e9eaed0888</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>hashOperatorTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>367</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>364</integer> + <integer>365</integer> + <integer>366</integer> + <integer>367</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>374</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>374</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>375</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>375</integer> + <key>col</key><integer>19</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>375</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>375</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>375</integer> + <key>col</key><integer>52</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'a'</string> + <key>message</key> + <string>Null pointer value stored to 'a'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'a')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>375</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>TO_NULL_AND_PRINT</string> + <key>expansion</key><string>a = 0; print( "Will this # cause a crash?")</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>b1da2db423e721067ed5cfda858890be</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>macroArgContainsHashInStringTest</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>376</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>373</integer> + <integer>374</integer> + <integer>375</integer> + <integer>376</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>422</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>422</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>422</integer> + <key>col</key><integer>18</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>422</integer> + <key>col</key><integer>43</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>422</integer> + <key>col</key><integer>18</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>422</integer> + <key>col</key><integer>18</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>422</integer> + <key>col</key><integer>49</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Calling 'getLowestCommonDenominator'</string> + <key>message</key> + <string>Calling 'getLowestCommonDenominator'</string> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>417</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Entered call from 'testVeryComplexAlgorithm'</string> + <key>message</key> + <string>Entered call from 'testVeryComplexAlgorithm'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>417</integer> + <key>col</key><integer>1</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>417</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>418</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>418</integer> + <key>col</key><integer>21</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>418</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>418</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>418</integer> + <key>col</key><integer>27</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>1</integer> + <key>extended_message</key> + <string>Division by zero</string> + <key>message</key> + <string>Division by zero</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>418</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>EUCLIDEAN_ALGORITHM</string> + <key>expansion</key><string>if (A<0 ){A=-A;} if ( B<0 ){ B=- B;}return B / ( B - B);</string> + </dict> + </array> + <key>description</key><string>Division by zero</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Division by zero</string> + <key>check_name</key><string>core.DivideZero</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>3484e210b755ea46d632296fffd709e0</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>getLowestCommonDenominator</string> + <key>issue_hash_function_offset</key><string>1</string> + <key>location</key> + <dict> + <key>line</key><integer>418</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>417</integer> + <integer>418</integer> + <integer>421</integer> + <integer>422</integer> + </array> + </dict> + </dict> + <dict> + <key>path</key> + <array> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>437</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>437</integer> + <key>col</key><integer>5</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>438</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>438</integer> + <key>col</key><integer>25</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>438</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>438</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>438</integer> + <key>col</key><integer>67</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Null pointer value stored to 'ptr'</string> + <key>message</key> + <string>Null pointer value stored to 'ptr'</string> + </dict> + <dict> + <key>kind</key><string>control</string> + <key>edges</key> + <array> + <dict> + <key>start</key> + <array> + <dict> + <key>line</key><integer>439</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>439</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + <key>end</key> + <array> + <dict> + <key>line</key><integer>439</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>439</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>kind</key><string>event</string> + <key>location</key> + <dict> + <key>line</key><integer>439</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ranges</key> + <array> + <array> + <dict> + <key>line</key><integer>439</integer> + <key>col</key><integer>4</integer> + <key>file</key><integer>0</integer> + </dict> + <dict> + <key>line</key><integer>439</integer> + <key>col</key><integer>6</integer> + <key>file</key><integer>0</integer> + </dict> + </array> + </array> + <key>depth</key><integer>0</integer> + <key>extended_message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>message</key> + <string>Dereference of null pointer (loaded from variable 'ptr')</string> + </dict> + </array> + <key>macro_expansions</key> + <array> + <dict> + <key>location</key> + <dict> + <key>line</key><integer>438</integer> + <key>col</key><integer>3</integer> + <key>file</key><integer>0</integer> + </dict> + <key>name</key><string>YET_ANOTHER_SET_TO_NULL</string> + <key>expansion</key><string>print((void *)5); print((void *)"Remember the Vasa"); ptr = nullptr;</string> + </dict> + </array> + <key>description</key><string>Dereference of null pointer (loaded from variable 'ptr')</string> + <key>category</key><string>Logic error</string> + <key>type</key><string>Dereference of null pointer</string> + <key>check_name</key><string>core.NullDereference</string> + <!-- This hash is experimental and going to change! --> + <key>issue_hash_content_of_line_in_context</key><string>42143f52fc9638fb2c0af41916e09d2f</string> + <key>issue_context_kind</key><string>function</string> + <key>issue_context</key><string>test</string> + <key>issue_hash_function_offset</key><string>3</string> + <key>location</key> + <dict> + <key>line</key><integer>439</integer> + <key>col</key><integer>8</integer> + <key>file</key><integer>0</integer> + </dict> + <key>ExecutedLines</key> + <dict> + <key>0</key> + <array> + <integer>436</integer> + <integer>437</integer> + <integer>438</integer> + <integer>439</integer> + </array> + </dict> + </dict> + </array> + <key>files</key> + <array> + <string>/home/szelethus/Documents/macro_expansion/clang/test/Analysis/plist-macros-with-expansion.cpp</string> + </array> +</dict> +</plist> diff --git a/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist b/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist index 340c8dcb87..f7ff277b54 100644 --- a/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist +++ b/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist @@ -3834,12 +3834,12 @@ </array> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: allocated object of type MyObj * is not referenced later in this execution path and has a retain count of +1</string> <key>message</key> - <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: allocated object of type MyObj * is not referenced later in this execution path and has a retain count of +1</string> </dict> </array> - <key>description</key><string>Potential leak of an object</string> + <key>description</key><string>Potential leak of an object of type MyObj *</string> <key>category</key><string>Memory (Core Foundation/Objective-C)</string> <key>type</key><string>Leak</string> <key>check_name</key><string>osx.cocoa.RetainCount</string> @@ -4233,12 +4233,12 @@ </array> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'y' is not referenced later in this execution path and has a retain count of +1</string> <key>message</key> - <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> + <string>Object leaked: object allocated and stored into 'y' is not referenced later in this execution path and has a retain count of +1</string> </dict> </array> - <key>description</key><string>Potential leak of an object</string> + <key>description</key><string>Potential leak of an object stored into 'y'</string> <key>category</key><string>Memory (Core Foundation/Objective-C)</string> <key>type</key><string>Leak</string> <key>check_name</key><string>osx.cocoa.RetainCount</string> diff --git a/test/Analysis/Inputs/system-header-simulator-cxx.h b/test/Analysis/Inputs/system-header-simulator-cxx.h index ccd54cf3b2..6f92a42173 100644 --- a/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -12,6 +12,13 @@ typedef __typeof__((char*)0-(char*)0) ptrdiff_t; void *memmove(void *s1, const void *s2, size_t n); namespace std { + typedef size_t size_type; +#if __cplusplus >= 201103L + using nullptr_t = decltype(nullptr); +#endif +} + +namespace std { struct input_iterator_tag { }; struct output_iterator_tag { }; struct forward_iterator_tag : public input_iterator_tag { }; @@ -230,6 +237,13 @@ namespace std { return static_cast<RvalRef>(a); } + template <class T> + void swap(T &a, T &b) { + T c(std::move(a)); + a = std::move(b); + b = std::move(c); + } + template<typename T> class vector { typedef T value_type; @@ -517,6 +531,42 @@ namespace std { const T& front() const { return *begin(); } }; + template <typename CharT> + class basic_string { + public: + basic_string(); + basic_string(const CharT *s); + + ~basic_string(); + void clear(); + + basic_string &operator=(const basic_string &str); + basic_string &operator+=(const basic_string &str); + + const CharT *c_str() const; + const CharT *data() const; + CharT *data(); + + basic_string &append(size_type count, CharT ch); + basic_string &assign(size_type count, CharT ch); + basic_string &erase(size_type index, size_type count); + basic_string &insert(size_type index, size_type count, CharT ch); + basic_string &replace(size_type pos, size_type count, const basic_string &str); + void pop_back(); + void push_back(CharT ch); + void reserve(size_type new_cap); + void resize(size_type count); + void shrink_to_fit(); + void swap(basic_string &other); + }; + + typedef basic_string<char> string; + typedef basic_string<wchar_t> wstring; +#if __cplusplus >= 201103L + typedef basic_string<char16_t> u16string; + typedef basic_string<char32_t> u32string; +#endif + class exception { public: exception() throw(); @@ -727,6 +777,22 @@ namespace std { } +#if __cplusplus >= 201103L +namespace std { + template <typename T> // TODO: Implement the stub for deleter. + class unique_ptr { + public: + unique_ptr(const unique_ptr &) = delete; + unique_ptr(unique_ptr &&); + + T *get() const; + + typename std::add_lvalue_reference<T>::type operator*() const; + T *operator->() const; + }; +} +#endif + #ifdef TEST_INLINABLE_ALLOCATORS namespace std { void *malloc(size_t); diff --git a/test/Analysis/NewDelete-custom.cpp b/test/Analysis/NewDelete-custom.cpp index f5a2952699..8c4d9a663a 100644 --- a/test/Analysis/NewDelete-custom.cpp +++ b/test/Analysis/NewDelete-custom.cpp @@ -1,12 +1,8 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -analyzer-config c++-allocator-inlining=false -fblocks -verify %s -// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -analyzer-config c++-allocator-inlining=false -DLEAKS=1 -fblocks -verify %s -// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -DALLOCATOR_INLINING=1 -fblocks -verify %s -// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -DLEAKS=1 -DALLOCATOR_INLINING=1 -fblocks -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -fblocks -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -fblocks -verify %s -analyzer-config c++-allocator-inlining=false #include "Inputs/system-header-simulator-cxx.h" -#if !(LEAKS && !ALLOCATOR_INLINING) // expected-no-diagnostics -#endif void *allocator(std::size_t size); @@ -24,24 +20,18 @@ public: void testNewMethod() { void *p1 = C::operator new(0); // no warn - C *p2 = new C; // no warn + C *p2 = new C; // no-warning - C *c3 = ::new C; + C *c3 = ::new C; // no-warning } -#if LEAKS && !ALLOCATOR_INLINING -// expected-warning@-2{{Potential leak of memory pointed to by 'c3'}} -#endif void testOpNewArray() { void *p = operator new[](0); // call is inlined, no warn } void testNewExprArray() { - int *p = new int[0]; + int *p = new int[0]; // no-warning } -#if LEAKS && !ALLOCATOR_INLINING -// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} -#endif //----- Custom non-placement operators @@ -50,12 +40,8 @@ void testOpNew() { } void testNewExpr() { - int *p = new int; + int *p = new int; // no-warning } -#if LEAKS && !ALLOCATOR_INLINING -// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} -#endif - //----- Custom NoThrow placement operators void testOpNewNoThrow() { @@ -63,11 +49,8 @@ void testOpNewNoThrow() { } void testNewExprNoThrow() { - int *p = new(std::nothrow) int; + int *p = new(std::nothrow) int; // no-warning } -#if LEAKS && !ALLOCATOR_INLINING -// expected-warning@-2{{Potential leak of memory pointed to by 'p'}} -#endif //----- Custom placement operators void testOpNewPlacement() { diff --git a/test/Analysis/NewDelete-sized-deallocation.cpp b/test/Analysis/NewDelete-sized-deallocation.cpp new file mode 100644 index 0000000000..b0f2cfb765 --- /dev/null +++ b/test/Analysis/NewDelete-sized-deallocation.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -fsized-deallocation +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -DINCLUDE_INCLUDES +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -DINCLUDE_INCLUDES -fsized-deallocation +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -DINCLUDE_INCLUDES -DTEST_INLINABLE_ALLOCATORS +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -DINCLUDE_INCLUDES -DTEST_INLINABLE_ALLOCATORS -fsized-deallocation + +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++14 +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++14 -fsized-deallocation +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++14 -DINCLUDE_INCLUDES +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++14 -DINCLUDE_INCLUDES -fsized-deallocation +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++14 -DINCLUDE_INCLUDES -DTEST_INLINABLE_ALLOCATORS +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++14 -DINCLUDE_INCLUDES -DTEST_INLINABLE_ALLOCATORS -fsized-deallocation + +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++17 +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++17 -fsized-deallocation +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++17 -DINCLUDE_INCLUDES +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++17 -DINCLUDE_INCLUDES -fsized-deallocation +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++17 -DINCLUDE_INCLUDES -DTEST_INLINABLE_ALLOCATORS +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus -verify -analyzer-output=text %s -std=c++17 -DINCLUDE_INCLUDES -DTEST_INLINABLE_ALLOCATORS -fsized-deallocation + +// Test all three: undeclared operator delete, operator delete forward-declared +// in the system header, operator delete defined in system header. +#ifdef INCLUDE_INCLUDES +// TEST_INLINABLE_ALLOCATORS is used within this include. +#include "Inputs/system-header-simulator-cxx.h" +#endif + +void leak() { + int *x = new int; // expected-note{{Memory is allocated}} +} // expected-warning{{Potential leak of memory pointed to by 'x'}} + // expected-note@-1{{Potential leak of memory pointed to by 'x'}} + +// This function was incorrectly diagnosed as leak under -fsized-deallocation +// because the sized operator delete was mistaken for a custom delete. +void no_leak() { + int *x = new int; // no-note + delete x; +} // no-warning diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c index c932fe12ae..ed13a85b59 100644 --- a/test/Analysis/analyzer-config.c +++ b/test/Analysis/analyzer-config.c @@ -1,16 +1,16 @@ // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core,osx.cocoa,debug.ConfigDumper -analyzer-max-loop 34 > %t 2>&1 // RUN: FileCheck --input-file=%t %s --match-full-lines -void bar() {} -void foo() { - // Call bar 33 times so max-times-inline-large is met and - // min-blocks-for-inline-large is checked - for (int i = 0; i < 34; ++i) { - bar(); - } -} - // CHECK: [config] +// CHECK-NEXT: aggressive-binary-operation-simplification = false +// CHECK-NEXT: avoid-suppressing-null-argument-paths = false +// CHECK-NEXT: c++-allocator-inlining = true +// CHECK-NEXT: c++-container-inlining = false +// CHECK-NEXT: c++-inlining = destructors +// CHECK-NEXT: c++-shared_ptr-inlining = false +// CHECK-NEXT: c++-stdlib-inlining = true +// CHECK-NEXT: c++-temp-dtor-inlining = true +// CHECK-NEXT: c++-template-inlining = true // CHECK-NEXT: cfg-conditional-static-initializers = true // CHECK-NEXT: cfg-implicit-dtors = true // CHECK-NEXT: cfg-lifetime = false @@ -18,23 +18,38 @@ void foo() { // CHECK-NEXT: cfg-rich-constructors = true // CHECK-NEXT: cfg-scopes = false // CHECK-NEXT: cfg-temporary-dtors = true +// CHECK-NEXT: crosscheck-with-z3 = false +// CHECK-NEXT: ctu-dir = "" +// CHECK-NEXT: ctu-index-name = externalFnMap.txt +// CHECK-NEXT: display-ctu-progress = false // CHECK-NEXT: eagerly-assume = true // CHECK-NEXT: elide-constructors = true +// CHECK-NEXT: expand-macros = false +// CHECK-NEXT: experimental-enable-naive-ctu-analysis = false // CHECK-NEXT: exploration_strategy = unexplored_first_queue // CHECK-NEXT: faux-bodies = true // CHECK-NEXT: graph-trim-interval = 1000 // CHECK-NEXT: inline-lambdas = true // CHECK-NEXT: ipa = dynamic-bifurcate // CHECK-NEXT: ipa-always-inline-size = 3 -// CHECK-NEXT: leak-diagnostics-reference-allocation = false // CHECK-NEXT: max-inlinable-size = 100 // CHECK-NEXT: max-nodes = 225000 +// CHECK-NEXT: max-symbol-complexity = 35 // CHECK-NEXT: max-times-inline-large = 32 // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14 // CHECK-NEXT: mode = deep +// CHECK-NEXT: model-path = "" +// CHECK-NEXT: notes-as-events = false +// CHECK-NEXT: objc-inlining = true +// CHECK-NEXT: prune-paths = true // CHECK-NEXT: region-store-small-struct-limit = 2 +// CHECK-NEXT: report-in-main-source-file = false // CHECK-NEXT: serialize-stats = false +// CHECK-NEXT: stable-report-filename = false +// CHECK-NEXT: suppress-c++-stdlib = true +// CHECK-NEXT: suppress-inlined-defensive-checks = true +// CHECK-NEXT: suppress-null-return-paths = true // CHECK-NEXT: unroll-loops = false // CHECK-NEXT: widen-loops = false // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 25 +// CHECK-NEXT: num-entries = 49 diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp deleted file mode 100644 index 5bbe71d8c0..0000000000 --- a/test/Analysis/analyzer-config.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core,osx.cocoa,debug.ConfigDumper -analyzer-max-loop 34 > %t 2>&1 -// RUN: FileCheck --input-file=%t %s --match-full-lines - -void bar() {} -void foo() { - // Call bar 33 times so max-times-inline-large is met and - // min-blocks-for-inline-large is checked - for (int i = 0; i < 34; ++i) { - bar(); - } -} - -class Foo { -public: - ~Foo() {} - void baz() { Foo(); } - void bar() { const Foo &f = Foo(); } - void foo() { bar(); } -}; - -// CHECK: [config] -// CHECK-NEXT: c++-container-inlining = false -// CHECK-NEXT: c++-inlining = destructors -// CHECK-NEXT: c++-shared_ptr-inlining = false -// CHECK-NEXT: c++-stdlib-inlining = true -// CHECK-NEXT: c++-temp-dtor-inlining = true -// CHECK-NEXT: c++-template-inlining = true -// CHECK-NEXT: cfg-conditional-static-initializers = true -// CHECK-NEXT: cfg-implicit-dtors = true -// CHECK-NEXT: cfg-lifetime = false -// CHECK-NEXT: cfg-loopexit = false -// CHECK-NEXT: cfg-rich-constructors = true -// CHECK-NEXT: cfg-scopes = false -// CHECK-NEXT: cfg-temporary-dtors = true -// CHECK-NEXT: eagerly-assume = true -// CHECK-NEXT: elide-constructors = true -// CHECK-NEXT: experimental-enable-naive-ctu-analysis = false -// CHECK-NEXT: exploration_strategy = unexplored_first_queue -// CHECK-NEXT: faux-bodies = true -// CHECK-NEXT: graph-trim-interval = 1000 -// CHECK-NEXT: inline-lambdas = true -// CHECK-NEXT: ipa = dynamic-bifurcate -// CHECK-NEXT: ipa-always-inline-size = 3 -// CHECK-NEXT: leak-diagnostics-reference-allocation = false -// CHECK-NEXT: max-inlinable-size = 100 -// CHECK-NEXT: max-nodes = 225000 -// CHECK-NEXT: max-times-inline-large = 32 -// CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14 -// CHECK-NEXT: mode = deep -// CHECK-NEXT: region-store-small-struct-limit = 2 -// CHECK-NEXT: serialize-stats = false -// CHECK-NEXT: unroll-loops = false -// CHECK-NEXT: widen-loops = false -// CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 32 diff --git a/test/Analysis/analyzer-list-configs.c b/test/Analysis/analyzer-list-configs.c new file mode 100644 index 0000000000..c9f6e55167 --- /dev/null +++ b/test/Analysis/analyzer-list-configs.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -analyzer-config-help 2>&1 | FileCheck %s +// CHECK: OVERVIEW: Clang Static Analyzer -analyzer-config Option List +// +// CHECK: USAGE: clang -cc1 [CLANG_OPTIONS] -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...> +// +// CHCEK: clang -cc1 [CLANG_OPTIONS] -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ... +// +// CHECK: clang [CLANG_OPTIONS] -Xclang -analyzer-config -Xclang<OPTION1=VALUE,OPTION2=VALUE,...> +// +// CHECK: clang [CLANG_OPTIONS] -Xclang -analyzer-config -Xclang OPTION1=VALUE, -Xclang -analyzer-config -Xclang OPTION2=VALUE, ... +// +// +// CHECK: OPTIONS: +// +// CHECK: aggressive-binary-operation-simplification +// CHECK: (bool) Whether SValBuilder should rearrange +// CHECK: comparisons and additive operations of symbolic +// CHECK: expressions which consist of a sum of a +// CHECK: symbol and a concrete integer into the format +// CHECK: where symbols are on the left-hand side +// CHECK: and the integer is on the right. This is +// CHECK: only done if both symbols and both concrete +// CHECK: integers are signed, greater than or equal +// CHECK: to the quarter of the minimum value of the +// CHECK: type and less than or equal to the quarter +// CHECK: of the maximum value of that type. A +// CHECK: + n +// CHECK: <OP> B + m becomes A - B <OP> m - n, where +// CHECK: A and B symbolic, n and m are integers. +// CHECK: <OP> is any of '==', '!=', '<', '<=', '>', +// CHECK: '>=', '+' or '-'. The rearrangement also +// CHECK: happens with '-' instead of '+' on either +// CHECK: or both side and also if any or both integers +// CHECK: are missing. (default: false) diff --git a/test/Analysis/asm.cpp b/test/Analysis/asm.cpp new file mode 100644 index 0000000000..1180063502 --- /dev/null +++ b/test/Analysis/asm.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker debug.ExprInspection -fheinous-gnu-extensions -w %s -verify + +int clang_analyzer_eval(int); + +int global; +void testRValueOutput() { + int &ref = global; + ref = 1; + __asm__("" : "=r"(((int)(global)))); // don't crash on rvalue output operand + clang_analyzer_eval(global == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(ref == 1); // expected-warning{{UNKNOWN}} +} diff --git a/test/Analysis/builtin-functions.cpp b/test/Analysis/builtin-functions.cpp index 19984963b4..da2fcf915d 100644 --- a/test/Analysis/builtin-functions.cpp +++ b/test/Analysis/builtin-functions.cpp @@ -70,14 +70,14 @@ void test_constant_p() { const int j = 2; constexpr int k = 3; clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{UNKNOWN}} clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{UNKNOWN}} clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{UNKNOWN}} clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}} clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}} } diff --git a/test/Analysis/casts.cpp b/test/Analysis/casts.cpp index 2c29105279..e920bd96da 100644 --- a/test/Analysis/casts.cpp +++ b/test/Analysis/casts.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s void clang_analyzer_eval(bool); diff --git a/test/Analysis/cfg.cpp b/test/Analysis/cfg.cpp index 85c5be5a98..f43a809c77 100644 --- a/test/Analysis/cfg.cpp +++ b/test/Analysis/cfg.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -analyzer-config cfg-rich-constructors=false %s > %t 2>&1 +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -fheinous-gnu-extensions -std=c++11 -analyzer-config cfg-rich-constructors=false %s > %t 2>&1 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,WARNINGS %s -// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -analyzer-config cfg-rich-constructors=true %s > %t 2>&1 +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -fheinous-gnu-extensions -std=c++11 -analyzer-config cfg-rich-constructors=true %s > %t 2>&1 // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,ANALYZER %s // This file tests how we construct two different flavors of the Clang CFG - @@ -84,6 +84,24 @@ void checkDeclStmts() { static_assert(1, "abc"); } + +// CHECK-LABEL: void checkGCCAsmRValueOutput() +// CHECK: [B2 (ENTRY)] +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B1] +// CHECK-NEXT: 1: int arg +// CHECK-NEXT: 2: arg +// CHECK-NEXT: 3: (int)[B1.2] (CStyleCastExpr, NoOp, int) +// CHECK-NEXT: 4: asm ("" : "=r" ([B1.3])); +// CHECK-NEXT: 5: arg +// CHECK-NEXT: 6: asm ("" : "=r" ([B1.5])); +void checkGCCAsmRValueOutput() { + int arg; + __asm__("" : "=r"((int)arg)); // rvalue output operand + __asm__("" : "=r"(arg)); // lvalue output operand +} + + // CHECK-LABEL: void F(EmptyE e) // CHECK: ENTRY // CHECK-NEXT: Succs (1): B1 diff --git a/test/Analysis/conversion.c b/test/Analysis/conversion.c index 7adb336eb2..8b77e25358 100644 --- a/test/Analysis/conversion.c +++ b/test/Analysis/conversion.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -Wno-conversion -Wno-tautological-constant-compare -analyzer-checker=core,alpha.core.Conversion -verify %s +// RUN: %clang_analyze_cc1 -Wno-conversion -Wno-tautological-constant-compare -analyzer-checker=core,apiModeling,alpha.core.Conversion -verify %s unsigned char U8; signed char S8; @@ -137,16 +137,21 @@ void dontwarn5() { U8 = S + 10; } +char dontwarn6(long long x) { + long long y = 42; + y += x; + return y == 42; +} + -// false positives.. +// C library functions, handled via apiModeling.StdCLibraryFunctions int isascii(int c); -void falsePositive1() { +void libraryFunction1() { char kb2[5]; int X = 1000; if (isascii(X)) { - // FIXME: should not warn here: - kb2[0] = X; // expected-warning {{Loss of precision}} + kb2[0] = X; // no-warning } } @@ -155,8 +160,8 @@ typedef struct FILE {} FILE; int getc(FILE *stream); # define EOF (-1) char reply_string[8192]; FILE *cin; -extern int dostuff (void); -int falsePositive2() { +extern int dostuff(void); +int libraryFunction2() { int c, n; int dig; char *cp = reply_string; @@ -175,9 +180,31 @@ int falsePositive2() { if (c == EOF) return(4); if (cp < &reply_string[sizeof(reply_string) - 1]) - // FIXME: should not warn here: - *cp++ = c; // expected-warning {{Loss of precision}} + *cp++ = c; // no-warning } } } +double floating_point(long long a, int b) { + if (a > 1LL << 55) { + double r = a; // expected-warning {{Loss of precision}} + return r; + } else if (b > 1 << 25) { + float f = b; // expected-warning {{Loss of precision}} + return f; + } + return 137; +} + +double floating_point2() { + int a = 1 << 24; + long long b = 1LL << 53; + float f = a; // no-warning + double d = b; // no-warning + return d - f; +} + +int floating_point_3(unsigned long long a) { + double b = a; // no-warning + return 42; +} diff --git a/test/Analysis/cstring-plist.c b/test/Analysis/cstring-plist.c index 395937f340..c527564d49 100644 --- a/test/Analysis/cstring-plist.c +++ b/test/Analysis/cstring-plist.c @@ -1,5 +1,8 @@ // RUN: rm -f %t -// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,unix.Malloc,unix.cstring.NullArg -analyzer-disable-checker=alpha.unix.cstring.OutOfBounds -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s +// RUN: %clang_analyze_cc1 -fblocks \ +// RUN: -analyzer-checker=core,unix.Malloc,unix.cstring.NullArg \ +// RUN: -analyzer-disable-checker=alpha.unix.cstring.OutOfBounds \ +// RUN: -analyzer-output=plist -o %t %s // RUN: FileCheck -input-file %t %s typedef __typeof(sizeof(int)) size_t; diff --git a/test/Analysis/ctu-different-triples.cpp b/test/Analysis/ctu-different-triples.cpp new file mode 100644 index 0000000000..314bada0c2 --- /dev/null +++ b/test/Analysis/ctu-different-triples.cpp @@ -0,0 +1,20 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: mkdir -p %t/ctudir +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \ +// RUN: -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp +// RUN: cp %S/Inputs/ctu-other.cpp.externalFnMap.txt %t/ctudir/externalFnMap.txt +// RUN: %clang_analyze_cc1 -triple powerpc64-montavista-linux-gnu \ +// RUN: -analyzer-checker=core,debug.ExprInspection \ +// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ +// RUN: -analyzer-config ctu-dir=%t/ctudir \ +// RUN: -Werror=ctu \ +// RUN: -verify %s + +// We expect an error in this file, but without a location. +// expected-error-re@./ctu-different-triples.cpp:*{{imported AST from {{.*}} had been generated for a different target, current: powerpc64-montavista-linux-gnu, imported: x86_64-pc-linux-gnu}} + +int f(int); + +int main() { + return f(5); +} diff --git a/test/Analysis/ctu-main.c b/test/Analysis/ctu-main.c new file mode 100644 index 0000000000..239d51ab49 --- /dev/null +++ b/test/Analysis/ctu-main.c @@ -0,0 +1,67 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: mkdir -p %t/ctudir2 +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \ +// RUN: -emit-pch -o %t/ctudir2/ctu-other.c.ast %S/Inputs/ctu-other.c +// RUN: cp %S/Inputs/ctu-other.c.externalFnMap.txt %t/ctudir2/externalFnMap.txt +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -std=c89 -analyze \ +// RUN: -analyzer-checker=core,debug.ExprInspection \ +// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ +// RUN: -analyzer-config ctu-dir=%t/ctudir2 \ +// RUN: -verify %s + +void clang_analyzer_eval(int); + +// Test typedef and global variable in function. +typedef struct { + int a; + int b; +} FooBar; +extern FooBar fb; +int f(int); +void testGlobalVariable() { + clang_analyzer_eval(f(5) == 1); // expected-warning{{TRUE}} +} + +// Test enums. +int enumCheck(void); +enum A { x, + y, + z }; +void testEnum() { + clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(enumCheck() == 42); // expected-warning{{TRUE}} +} + +// Test that asm import does not fail. +int inlineAsm(); +int testInlineAsm() { + return inlineAsm(); +} + +// Test reporting error in a macro. +struct S; +int g(struct S *); +void testMacro(void) { + g(0); // expected-warning@Inputs/ctu-other.c:29 {{Access to field 'a' results in a dereference of a null pointer (loaded from variable 'ctx')}} +} + +// The external function prototype is incomplete. +// warning:implicit functions are prohibited by c99 +void testImplicit() { + int res = identImplicit(6); // external implicit functions are not inlined + clang_analyzer_eval(res == 6); // expected-warning{{TRUE}} +} + +// Tests the import of functions that have a struct parameter +// defined in its prototype. +struct DataType { + int a; + int b; +}; +int structInProto(struct DataType *d); +void testStructDefInArgument() { + struct DataType d; + d.a = 1; + d.b = 0; + clang_analyzer_eval(structInProto(&d) == 0); // expected-warning{{TRUE}} expected-warning{{FALSE}} +} diff --git a/test/Analysis/ctu-main.cpp b/test/Analysis/ctu-main.cpp index 33da84962c..44c0c07603 100644 --- a/test/Analysis/ctu-main.cpp +++ b/test/Analysis/ctu-main.cpp @@ -1,8 +1,23 @@ -// RUN: mkdir -p %T/ctudir -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-pch -o %T/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-pch -o %T/ctudir/ctu-chain.cpp.ast %S/Inputs/ctu-chain.cpp -// RUN: cp %S/Inputs/externalFnMap.txt %T/ctudir/ -// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config experimental-enable-naive-ctu-analysis=true -analyzer-config ctu-dir=%T/ctudir -verify %s +// RUN: rm -rf %t && mkdir %t +// RUN: mkdir -p %t/ctudir +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \ +// RUN: -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \ +// RUN: -emit-pch -o %t/ctudir/ctu-chain.cpp.ast %S/Inputs/ctu-chain.cpp +// RUN: cp %S/Inputs/ctu-other.cpp.externalFnMap.txt %t/ctudir/externalFnMap.txt +// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu \ +// RUN: -analyzer-checker=core,debug.ExprInspection \ +// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ +// RUN: -analyzer-config ctu-dir=%t/ctudir \ +// RUN: -verify %s +// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu \ +// RUN: -analyzer-checker=core,debug.ExprInspection \ +// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ +// RUN: -analyzer-config ctu-dir=%t/ctudir \ +// RUN: -analyzer-config display-ctu-progress=true 2>&1 %s | FileCheck %s + +// CHECK: CTU loaded AST file: {{.*}}ctu-other.cpp.ast +// CHECK: CTU loaded AST file: {{.*}}ctu-chain.cpp.ast #include "ctu-hdr.h" diff --git a/test/Analysis/ctu-unknown-parts-in-triples.cpp b/test/Analysis/ctu-unknown-parts-in-triples.cpp new file mode 100644 index 0000000000..a632cfbb32 --- /dev/null +++ b/test/Analysis/ctu-unknown-parts-in-triples.cpp @@ -0,0 +1,22 @@ +// We do not expect any error when one part of the triple is unknown, but other +// known parts are equal. + +// RUN: rm -rf %t && mkdir %t +// RUN: mkdir -p %t/ctudir +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \ +// RUN: -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp +// RUN: cp %S/Inputs/ctu-other.cpp.externalFnMap.txt %t/ctudir/externalFnMap.txt +// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux-gnu \ +// RUN: -analyzer-checker=core,debug.ExprInspection \ +// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ +// RUN: -analyzer-config ctu-dir=%t/ctudir \ +// RUN: -Werror=ctu \ +// RUN: -verify %s + +// expected-no-diagnostics + +int f(int); + +int main() { + return f(5); +} diff --git a/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp b/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp index 4f95f09cc0..edc594a0bf 100644 --- a/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp +++ b/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp @@ -257,8 +257,10 @@ void fCharPointerTest() { } struct CyclicPointerTest1 { - int *ptr; - CyclicPointerTest1() : ptr(reinterpret_cast<int *>(&ptr)) {} + int *ptr; // expected-note{{object references itself 'this->ptr'}} + int dontGetFilteredByNonPedanticMode = 0; + + CyclicPointerTest1() : ptr(reinterpret_cast<int *>(&ptr)) {} // expected-warning{{1 uninitialized field}} }; void fCyclicPointerTest1() { @@ -266,8 +268,10 @@ void fCyclicPointerTest1() { } struct CyclicPointerTest2 { - int **pptr; // no-crash - CyclicPointerTest2() : pptr(reinterpret_cast<int **>(&pptr)) {} + int **pptr; // expected-note{{object references itself 'this->pptr'}} + int dontGetFilteredByNonPedanticMode = 0; + + CyclicPointerTest2() : pptr(reinterpret_cast<int **>(&pptr)) {} // expected-warning{{1 uninitialized field}} }; void fCyclicPointerTest2() { @@ -353,9 +357,10 @@ void fVoidPointerLRefTest() { } struct CyclicVoidPointerTest { - void *vptr; // no-crash + void *vptr; // expected-note{{object references itself 'this->vptr'}} + int dontGetFilteredByNonPedanticMode = 0; - CyclicVoidPointerTest() : vptr(&vptr) {} + CyclicVoidPointerTest() : vptr(&vptr) {} // expected-warning{{1 uninitialized field}} }; void fCyclicVoidPointerTest() { @@ -860,3 +865,44 @@ void fReferenceTest5() { ReferenceTest4::RecordType c, d{37, 38}; ReferenceTest4(d, c); } + +//===----------------------------------------------------------------------===// +// Tests for objects containing multiple references to the same object. +//===----------------------------------------------------------------------===// + +struct IntMultipleReferenceToSameObjectTest { + int *iptr; // expected-note{{uninitialized pointee 'this->iptr'}} + int &iref; // no-note, pointee of this->iref was already reported + + int dontGetFilteredByNonPedanticMode = 0; + + IntMultipleReferenceToSameObjectTest(int *i) : iptr(i), iref(*i) {} // expected-warning{{1 uninitialized field}} +}; + +void fIntMultipleReferenceToSameObjectTest() { + int a; + IntMultipleReferenceToSameObjectTest Test(&a); +} + +struct IntReferenceWrapper1 { + int &a; // expected-note{{uninitialized pointee 'this->a'}} + + int dontGetFilteredByNonPedanticMode = 0; + + IntReferenceWrapper1(int &a) : a(a) {} // expected-warning{{1 uninitialized field}} +}; + +struct IntReferenceWrapper2 { + int &a; // no-note, pointee of this->a was already reported + + int dontGetFilteredByNonPedanticMode = 0; + + IntReferenceWrapper2(int &a) : a(a) {} // no-warning +}; + +void fMultipleObjectsReferencingTheSameObjectTest() { + int a; + + IntReferenceWrapper1 T1(a); + IntReferenceWrapper2 T2(a); +} diff --git a/test/Analysis/debug-CallGraph.c b/test/Analysis/debug-CallGraph.cpp index 9f3865b35a..1d6844fad9 100644 --- a/test/Analysis/debug-CallGraph.c +++ b/test/Analysis/debug-CallGraph.cpp @@ -51,8 +51,28 @@ void test_single_call() { do_nothing(); } +namespace SomeNS { +template<typename T> +void templ(T t) { + ccc(); +} + +template<> +void templ<double>(double t) { + eee(); +} + +void templUser() { + templ(5); + templ(5.5); +} +} + // CHECK:--- Call graph Dump --- -// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call $}} +// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call SomeNS::templ SomeNS::templ SomeNS::templUser $}} +// CHECK-NEXT: {{Function: SomeNS::templUser calls: SomeNS::templ SomeNS::templ $}} +// CHECK-NEXT: {{Function: SomeNS::templ calls: eee $}} +// CHECK-NEXT: {{Function: SomeNS::templ calls: ccc $}} // CHECK-NEXT: {{Function: test_single_call calls: do_nothing $}} // CHECK-NEXT: {{Function: do_nothing calls: $}} // CHECK-NEXT: {{Function: fff calls: eee $}} diff --git a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif new file mode 100644 index 0000000000..cdf4a2daa2 --- /dev/null +++ b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif @@ -0,0 +1,114 @@ +{ + "$schema": "http://json.schemastore.org/sarif-2.0.0-csd.2.beta.2018-11-28", + "runs": [ + { + "files": [ + { + "fileLocation": { + "uri": "file:sarif-diagnostics-taint-test.c" + }, + "length": 413, + "mimeType": "text/plain", + "roles": [ + "resultFile" + ] + } + ], + "resources": { + "rules": [ + { + "fullDescription": { + "text": "Mark tainted symbols as such." + }, + "id": "debug.TaintTest", + "name": { + "text": "debug.TaintTest" + } + } + ] + }, + "results": [ + { + "codeFlows": [ + { + "threadFlows": [ + { + "locations": [ + { + "importance": "essential", + "location": { + "message": { + "text": "Calling 'f'" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-diagnostics-taint-test.c" + }, + "region": { + "endColumn": 5, + "endLine": 13, + "startColumn": 3, + "startLine": 13 + } + } + } + }, + { + "importance": "essential", + "location": { + "message": { + "text": "tainted" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-diagnostics-taint-test.c" + }, + "region": { + "endColumn": 17, + "endLine": 9, + "startColumn": 11, + "startLine": 9 + } + } + } + } + ] + } + ] + } + ], + "locations": [ + { + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-diagnostics-taint-test.c" + }, + "region": { + "endColumn": 17, + "endLine": 9, + "startColumn": 11, + "startLine": 9 + } + } + } + ], + "message": { + "text": "tainted" + }, + "ruleId": "debug.TaintTest", + "ruleIndex": 0 + } + ], + "tool": { + "fullName": "clang static analyzer", + "language": "en-US", + "name": "clang", + "version": "clang version 8.0.0 (https://github.com/llvm-project/clang.git a5ccb257a7a70928ede717a7c282f5fc8cbed310) (https://github.com/llvm-mirror/llvm.git 73cebd79c512f7129eca16b0f3a7abd21d2881e8)" + } + } + ], + "version": "2.0.0-csd.2.beta.2018-11-28" +} diff --git a/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif new file mode 100644 index 0000000000..4b581b2e0f --- /dev/null +++ b/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif @@ -0,0 +1,318 @@ +{ + "$schema": "http://json.schemastore.org/sarif-2.0.0-csd.2.beta.2018-11-28", + "runs": [ + { + "files": [ + { + "fileLocation": { + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "length": 665, + "mimeType": "text/plain", + "roles": [ + "resultFile" + ] + } + ], + "resources": { + "rules": [ + { + "fullDescription": { + "text": "Mark tainted symbols as such." + }, + "id": "debug.TaintTest", + "name": { + "text": "debug.TaintTest" + } + }, + { + "fullDescription": { + "text": "Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers)" + }, + "id": "core.CallAndMessage", + "name": { + "text": "core.CallAndMessage" + } + }, + { + "fullDescription": { + "text": "Check for division by zero" + }, + "id": "core.DivideZero", + "name": { + "text": "core.DivideZero" + } + } + ] + }, + "results": [ + { + "codeFlows": [ + { + "threadFlows": [ + { + "locations": [ + { + "importance": "essential", + "location": { + "message": { + "text": "Calling 'f'" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 5, + "endLine": 24, + "startColumn": 3, + "startLine": 24 + } + } + } + }, + { + "importance": "essential", + "location": { + "message": { + "text": "tainted" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 17, + "endLine": 9, + "startColumn": 11, + "startLine": 9 + } + } + } + } + ] + } + ] + } + ], + "locations": [ + { + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 17, + "endLine": 9, + "startColumn": 11, + "startLine": 9 + } + } + } + ], + "message": { + "text": "tainted" + }, + "ruleId": "debug.TaintTest", + "ruleIndex": 0 + }, + { + "codeFlows": [ + { + "threadFlows": [ + { + "locations": [ + { + "importance": "essential", + "location": { + "message": { + "text": "Calling 'g'" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 5, + "endLine": 25, + "startColumn": 3, + "startLine": 25 + } + } + } + }, + { + "importance": "essential", + "location": { + "message": { + "text": "'fp' declared without an initial value" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 10, + "endLine": 13, + "startColumn": 3, + "startLine": 13 + } + } + } + }, + { + "importance": "essential", + "location": { + "message": { + "text": "Called function pointer is an uninitialized pointer value" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 8, + "endLine": 14, + "startColumn": 3, + "startLine": 14 + } + } + } + } + ] + } + ] + } + ], + "locations": [ + { + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 8, + "endLine": 14, + "startColumn": 3, + "startLine": 14 + } + } + } + ], + "message": { + "text": "Called function pointer is an uninitialized pointer value" + }, + "ruleId": "core.CallAndMessage", + "ruleIndex": 1 + }, + { + "codeFlows": [ + { + "threadFlows": [ + { + "locations": [ + { + "importance": "important", + "location": { + "message": { + "text": "Assuming 'i' is equal to 0" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 12, + "endLine": 18, + "startColumn": 7, + "startLine": 18 + } + } + } + }, + { + "importance": "unimportant", + "location": { + "message": { + "text": "Taking true branch" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 3, + "endLine": 18, + "startColumn": 3, + "startLine": 18 + } + } + } + }, + { + "importance": "essential", + "location": { + "message": { + "text": "Division by zero" + }, + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 14, + "endLine": 19, + "startColumn": 14, + "startLine": 19 + } + } + } + } + ] + } + ] + } + ], + "locations": [ + { + "physicalLocation": { + "fileLocation": { + "fileIndex": 0, + "uri": "file:sarif-multi-diagnostic-test.c" + }, + "region": { + "endColumn": 14, + "endLine": 19, + "startColumn": 14, + "startLine": 19 + } + } + } + ], + "message": { + "text": "Division by zero" + }, + "ruleId": "core.DivideZero", + "ruleIndex": 2 + } + ], + "tool": { + "fullName": "clang static analyzer", + "language": "en-US", + "name": "clang", + "version": "clang version 8.0.0 (trunk 345822) (llvm/trunk 345824)" + } + } + ], + "version": "2.0.0-csd.2.beta.2018-11-28" +} diff --git a/test/Analysis/diagnostics/explicit-suppression.cpp b/test/Analysis/diagnostics/explicit-suppression.cpp index 50d24fd53f..2bb969059f 100644 --- a/test/Analysis/diagnostics/explicit-suppression.cpp +++ b/test/Analysis/diagnostics/explicit-suppression.cpp @@ -19,6 +19,6 @@ class C { void testCopyNull(C *I, C *E) { std::copy(I, E, (C *)0); #ifndef SUPPRESSED - // expected-warning@../Inputs/system-header-simulator-cxx.h:627 {{Called C++ object pointer is null}} + // expected-warning@../Inputs/system-header-simulator-cxx.h:677 {{Called C++ object pointer is null}} #endif } diff --git a/test/Analysis/diagnostics/no-store-func-path-notes.cpp b/test/Analysis/diagnostics/no-store-func-path-notes.cpp index 6e7aca05c8..587c08fae1 100644 --- a/test/Analysis/diagnostics/no-store-func-path-notes.cpp +++ b/test/Analysis/diagnostics/no-store-func-path-notes.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -x c++ -analyzer-checker=core -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -x c++ -std=c++14 -analyzer-checker=core -analyzer-output=text -verify %s int initializer1(int &p, int x) { if (x) { // expected-note{{Taking false branch}} diff --git a/test/Analysis/diagnostics/sarif-diagnostics-taint-test.c b/test/Analysis/diagnostics/sarif-diagnostics-taint-test.c new file mode 100644 index 0000000000..75defbd2fb --- /dev/null +++ b/test/Analysis/diagnostics/sarif-diagnostics-taint-test.c @@ -0,0 +1,15 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify -analyzer-output=sarif -o - | %diff_sarif %S/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif +#include "../Inputs/system-header-simulator.h" + +int atoi(const char *nptr); + +void f(void) { + char s[80]; + scanf("%s", s); + int d = atoi(s); // expected-warning {{tainted}} +} + +int main(void) { + f(); + return 0; +} diff --git a/test/Analysis/diagnostics/sarif-multi-diagnostic-test.c b/test/Analysis/diagnostics/sarif-multi-diagnostic-test.c new file mode 100644 index 0000000000..481e3a5814 --- /dev/null +++ b/test/Analysis/diagnostics/sarif-multi-diagnostic-test.c @@ -0,0 +1,29 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.security.taint,debug.TaintTest %s -verify -analyzer-output=sarif -o - | %diff_sarif %S/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif +#include "../Inputs/system-header-simulator.h" + +int atoi(const char *nptr); + +void f(void) { + char s[80]; + scanf("%s", s); + int d = atoi(s); // expected-warning {{tainted}} +} + +void g(void) { + void (*fp)(int); + fp(12); // expected-warning {{Called function pointer is an uninitialized pointer value}} +} + +int h(int i) { + if (i == 0) + return 1 / i; // expected-warning {{Division by zero}} + return 0; +} + +int main(void) { + f(); + g(); + h(0); + return 0; +} + diff --git a/test/Analysis/dump_egraph.c b/test/Analysis/dump_egraph.c index 70b7e1f088..6e8793b202 100644 --- a/test/Analysis/dump_egraph.c +++ b/test/Analysis/dump_egraph.c @@ -1,12 +1,13 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-dump-egraph=%t.dot %s // RUN: cat %t.dot | FileCheck %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-dump-egraph=%t.dot -trim-egraph %s // REQUIRES: asserts int getJ(); int foo() { - int *x = 0; - return *x; + int *x = 0, *y = 0; + return *x + *y; } // CHECK: digraph "Exploded Graph" { diff --git a/test/Analysis/dump_egraph.cpp b/test/Analysis/dump_egraph.cpp new file mode 100644 index 0000000000..10e33a7523 --- /dev/null +++ b/test/Analysis/dump_egraph.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-dump-egraph=%t.dot %s +// RUN: cat %t.dot | FileCheck %s +// REQUIRES: asserts + +struct S { + ~S(); +}; + +struct T { + S s; + T() : s() {} +}; + +void foo() { + // Test that dumping symbols conjured on null statements doesn't crash. + T t; +} + +// CHECK: (LC1,S{{[0-9]*}},construct into local variable) T t;\n : &t +// CHECK: (LC2,I{{[0-9]*}},construct into member variable) s : &t-\>s +// CHECK: conj_$5\{int, LC3, no stmt, #1\} + diff --git a/test/Analysis/enum-cast-out-of-range.cpp b/test/Analysis/enum-cast-out-of-range.cpp new file mode 100644 index 0000000000..e77339b551 --- /dev/null +++ b/test/Analysis/enum-cast-out-of-range.cpp @@ -0,0 +1,192 @@ +// RUN: %clang_analyze_cc1 \ +// RUN: -analyzer-checker=core,alpha.cplusplus.EnumCastOutOfRange \ +// RUN: -std=c++11 -verify %s + +enum unscoped_unspecified_t { + unscoped_unspecified_0 = -4, + unscoped_unspecified_1, + unscoped_unspecified_2 = 1, + unscoped_unspecified_3, + unscoped_unspecified_4 = 4 +}; + +enum unscoped_specified_t : int { + unscoped_specified_0 = -4, + unscoped_specified_1, + unscoped_specified_2 = 1, + unscoped_specified_3, + unscoped_specified_4 = 4 +}; + +enum class scoped_unspecified_t { + scoped_unspecified_0 = -4, + scoped_unspecified_1, + scoped_unspecified_2 = 1, + scoped_unspecified_3, + scoped_unspecified_4 = 4 +}; + +enum class scoped_specified_t : int { + scoped_specified_0 = -4, + scoped_specified_1, + scoped_specified_2 = 1, + scoped_specified_3, + scoped_specified_4 = 4 +}; + +struct S { + unscoped_unspecified_t E : 5; +}; + +void unscopedUnspecified() { + unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast<unscoped_unspecified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t ValidNegativeValue1 = static_cast<unscoped_unspecified_t>(-4); // OK. + unscoped_unspecified_t ValidNegativeValue2 = static_cast<unscoped_unspecified_t>(-3); // OK. + unscoped_unspecified_t InvalidInsideRange1 = static_cast<unscoped_unspecified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t InvalidInsideRange2 = static_cast<unscoped_unspecified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t InvalidInsideRange3 = static_cast<unscoped_unspecified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t ValidPositiveValue1 = static_cast<unscoped_unspecified_t>(1); // OK. + unscoped_unspecified_t ValidPositiveValue2 = static_cast<unscoped_unspecified_t>(2); // OK. + unscoped_unspecified_t InvalidInsideRange4 = static_cast<unscoped_unspecified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t ValidPositiveValue3 = static_cast<unscoped_unspecified_t>(4); // OK. + unscoped_unspecified_t InvalidAfterRangeEnd = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void unscopedSpecified() { + unscoped_specified_t InvalidBeforeRangeBegin = static_cast<unscoped_specified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t ValidNegativeValue1 = static_cast<unscoped_specified_t>(-4); // OK. + unscoped_specified_t ValidNegativeValue2 = static_cast<unscoped_specified_t>(-3); // OK. + unscoped_specified_t InvalidInsideRange1 = static_cast<unscoped_specified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t InvalidInsideRange2 = static_cast<unscoped_specified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t InvalidInsideRange3 = static_cast<unscoped_specified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t ValidPositiveValue1 = static_cast<unscoped_specified_t>(1); // OK. + unscoped_specified_t ValidPositiveValue2 = static_cast<unscoped_specified_t>(2); // OK. + unscoped_specified_t InvalidInsideRange4 = static_cast<unscoped_specified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t ValidPositiveValue3 = static_cast<unscoped_specified_t>(4); // OK. + unscoped_specified_t InvalidAfterRangeEnd = static_cast<unscoped_specified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void scopedUnspecified() { + scoped_unspecified_t InvalidBeforeRangeBegin = static_cast<scoped_unspecified_t>(-5); // expected-warning{{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t ValidNegativeValue1 = static_cast<scoped_unspecified_t>(-4); // OK. + scoped_unspecified_t ValidNegativeValue2 = static_cast<scoped_unspecified_t>(-3); // OK. + scoped_unspecified_t InvalidInsideRange1 = static_cast<scoped_unspecified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t InvalidInsideRange2 = static_cast<scoped_unspecified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t InvalidInsideRange3 = static_cast<scoped_unspecified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t ValidPositiveValue1 = static_cast<scoped_unspecified_t>(1); // OK. + scoped_unspecified_t ValidPositiveValue2 = static_cast<scoped_unspecified_t>(2); // OK. + scoped_unspecified_t InvalidInsideRange4 = static_cast<scoped_unspecified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t ValidPositiveValue3 = static_cast<scoped_unspecified_t>(4); // OK. + scoped_unspecified_t InvalidAfterRangeEnd = static_cast<scoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void scopedSpecified() { + scoped_specified_t InvalidBeforeRangeBegin = static_cast<scoped_specified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t ValidNegativeValue1 = static_cast<scoped_specified_t>(-4); // OK. + scoped_specified_t ValidNegativeValue2 = static_cast<scoped_specified_t>(-3); // OK. + scoped_specified_t InvalidInsideRange1 = static_cast<scoped_specified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t InvalidInsideRange2 = static_cast<scoped_specified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t InvalidInsideRange3 = static_cast<scoped_specified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t ValidPositiveValue1 = static_cast<scoped_specified_t>(1); // OK. + scoped_specified_t ValidPositiveValue2 = static_cast<scoped_specified_t>(2); // OK. + scoped_specified_t InvalidInsideRange4 = static_cast<scoped_specified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t ValidPositiveValue3 = static_cast<scoped_specified_t>(4); // OK. + scoped_specified_t InvalidAfterRangeEnd = static_cast<scoped_specified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void unscopedUnspecifiedCStyle() { + unscoped_unspecified_t InvalidBeforeRangeBegin = (unscoped_unspecified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t ValidNegativeValue1 = (unscoped_unspecified_t)(-4); // OK. + unscoped_unspecified_t ValidNegativeValue2 = (unscoped_unspecified_t)(-3); // OK. + unscoped_unspecified_t InvalidInsideRange1 = (unscoped_unspecified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t InvalidInsideRange2 = (unscoped_unspecified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t InvalidInsideRange3 = (unscoped_unspecified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t ValidPositiveValue1 = (unscoped_unspecified_t)(1); // OK. + unscoped_unspecified_t ValidPositiveValue2 = (unscoped_unspecified_t)(2); // OK. + unscoped_unspecified_t InvalidInsideRange4 = (unscoped_unspecified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_unspecified_t ValidPositiveValue3 = (unscoped_unspecified_t)(4); // OK. + unscoped_unspecified_t InvalidAfterRangeEnd = (unscoped_unspecified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void unscopedSpecifiedCStyle() { + unscoped_specified_t InvalidBeforeRangeBegin = (unscoped_specified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t ValidNegativeValue1 = (unscoped_specified_t)(-4); // OK. + unscoped_specified_t ValidNegativeValue2 = (unscoped_specified_t)(-3); // OK. + unscoped_specified_t InvalidInsideRange1 = (unscoped_specified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t InvalidInsideRange2 = (unscoped_specified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t InvalidInsideRange3 = (unscoped_specified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t ValidPositiveValue1 = (unscoped_specified_t)(1); // OK. + unscoped_specified_t ValidPositiveValue2 = (unscoped_specified_t)(2); // OK. + unscoped_specified_t InvalidInsideRange4 = (unscoped_specified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + unscoped_specified_t ValidPositiveValue3 = (unscoped_specified_t)(4); // OK. + unscoped_specified_t InvalidAfterRangeEnd = (unscoped_specified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void scopedUnspecifiedCStyle() { + scoped_unspecified_t InvalidBeforeRangeBegin = (scoped_unspecified_t)(-5); // expected-warning{{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t ValidNegativeValue1 = (scoped_unspecified_t)(-4); // OK. + scoped_unspecified_t ValidNegativeValue2 = (scoped_unspecified_t)(-3); // OK. + scoped_unspecified_t InvalidInsideRange1 = (scoped_unspecified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t InvalidInsideRange2 = (scoped_unspecified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t InvalidInsideRange3 = (scoped_unspecified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t ValidPositiveValue1 = (scoped_unspecified_t)(1); // OK. + scoped_unspecified_t ValidPositiveValue2 = (scoped_unspecified_t)(2); // OK. + scoped_unspecified_t InvalidInsideRange4 = (scoped_unspecified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_unspecified_t ValidPositiveValue3 = (scoped_unspecified_t)(4); // OK. + scoped_unspecified_t InvalidAfterRangeEnd = (scoped_unspecified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void scopedSpecifiedCStyle() { + scoped_specified_t InvalidBeforeRangeBegin = (scoped_specified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t ValidNegativeValue1 = (scoped_specified_t)(-4); // OK. + scoped_specified_t ValidNegativeValue2 = (scoped_specified_t)(-3); // OK. + scoped_specified_t InvalidInsideRange1 = (scoped_specified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t InvalidInsideRange2 = (scoped_specified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t InvalidInsideRange3 = (scoped_specified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t ValidPositiveValue1 = (scoped_specified_t)(1); // OK. + scoped_specified_t ValidPositiveValue2 = (scoped_specified_t)(2); // OK. + scoped_specified_t InvalidInsideRange4 = (scoped_specified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} + scoped_specified_t ValidPositiveValue3 = (scoped_specified_t)(4); // OK. + scoped_specified_t InvalidAfterRangeEnd = (scoped_specified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void rangeContstrained1(int input) { + if (input > -5 && input < 5) + auto value = static_cast<scoped_specified_t>(input); // OK. Being conservative, this is a possibly good value. +} + +void rangeConstrained2(int input) { + if (input < -5) + auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void rangeConstrained3(int input) { + if (input >= -2 && input <= -1) + auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void rangeConstrained4(int input) { + if (input >= -2 && input <= 1) + auto value = static_cast<scoped_specified_t>(input); // OK. Possibly 1. +} + +void rangeConstrained5(int input) { + if (input >= 1 && input <= 2) + auto value = static_cast<scoped_specified_t>(input); // OK. Strict inner matching. +} + +void rangeConstrained6(int input) { + if (input >= 2 && input <= 4) + auto value = static_cast<scoped_specified_t>(input); // OK. The value is possibly 2 or 4, dont warn. +} + +void rangeConstrained7(int input) { + if (input >= 3 && input <= 3) + auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} + +void enumBitFieldAssignment() { + S s; + s.E = static_cast<unscoped_unspecified_t>(4); // OK. + s.E = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} +} diff --git a/test/Analysis/html_diagnostics/relevant_lines/synthesized_body.cpp b/test/Analysis/html_diagnostics/relevant_lines/synthesized_body.cpp index a4e30e3c9a..2ed8355f6e 100644 --- a/test/Analysis/html_diagnostics/relevant_lines/synthesized_body.cpp +++ b/test/Analysis/html_diagnostics/relevant_lines/synthesized_body.cpp @@ -20,6 +20,6 @@ void call_deref_once() { // RUN: rm -rf %t.output -// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core -analyzer-output html -o %t.output %s +// RUN: %clang_analyze_cc1 -std=c++11 -analyze -analyzer-checker=core -analyzer-output html -o %t.output %s // RUN: cat %t.output/* | FileCheck %s --match-full-lines // CHECK: var relevant_lines = {"1": {"3": 1, "8": 1, "11": 1, "12": 1, "15": 1, "16": 1, "17": 1, "18": 1}}; diff --git a/test/Analysis/inner-pointer.cpp b/test/Analysis/inner-pointer.cpp index 25d7069ed3..81b750d7e5 100644 --- a/test/Analysis/inner-pointer.cpp +++ b/test/Analysis/inner-pointer.cpp @@ -1,43 +1,9 @@ -//RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.InnerPointer %s -analyzer-output=text -verify +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.InnerPointer \ +// RUN: %s -analyzer-output=text -verify +#include "Inputs/system-header-simulator-cxx.h" namespace std { -typedef int size_type; - -template <typename CharT> -class basic_string { -public: - basic_string(); - basic_string(const CharT *s); - - ~basic_string(); - void clear(); - - basic_string &operator=(const basic_string &str); - basic_string &operator+=(const basic_string &str); - - const CharT *c_str() const; - const CharT *data() const; - CharT *data(); - - basic_string &append(size_type count, CharT ch); - basic_string &assign(size_type count, CharT ch); - basic_string &erase(size_type index, size_type count); - basic_string &insert(size_type index, size_type count, CharT ch); - basic_string &replace(size_type pos, size_type count, const basic_string &str); - void pop_back(); - void push_back(CharT ch); - void reserve(size_type new_cap); - void resize(size_type count); - void shrink_to_fit(); - void swap(basic_string &other); -}; - -typedef basic_string<char> string; -typedef basic_string<wchar_t> wstring; -typedef basic_string<char16_t> u16string; -typedef basic_string<char32_t> u32string; - template <typename T> void func_ref(T &a); diff --git a/test/Analysis/invalid-analyzer-config-value.c b/test/Analysis/invalid-analyzer-config-value.c new file mode 100644 index 0000000000..34a73a7f9d --- /dev/null +++ b/test/Analysis/invalid-analyzer-config-value.c @@ -0,0 +1,71 @@ +// RUN: not %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config notes-as-events=yesplease \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-BOOL-INPUT + +// CHECK-BOOL-INPUT: (frontend): invalid input for analyzer-config option +// CHECK-BOOL-INPUT-SAME: 'notes-as-events', that expects a boolean value + +// RUN: %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config-compatibility-mode=true \ +// RUN: -analyzer-config notes-as-events=yesplease + + +// RUN: not %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config max-inlinable-size=400km/h \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-UINT-INPUT + +// CHECK-UINT-INPUT: (frontend): invalid input for analyzer-config option +// CHECK-UINT-INPUT-SAME: 'max-inlinable-size', that expects an unsigned +// CHECK-UINT-INPUT-SAME: value + +// RUN: %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config-compatibility-mode=true \ +// RUN: -analyzer-config max-inlinable-size=400km/h + + +// RUN: not %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config ctu-dir=0123012301230123 \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-FILENAME-INPUT + +// CHECK-FILENAME-INPUT: (frontend): invalid input for analyzer-config option +// CHECK-FILENAME-INPUT-SAME: 'ctu-dir', that expects a filename +// CHECK-FILENAME-INPUT-SAME: value + +// RUN: %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config-compatibility-mode=true \ +// RUN: -analyzer-config ctu-dir=0123012301230123 + + +// RUN: not %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config no-false-positives=true \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-UNKNOWN-CFG + +// CHECK-UNKNOWN-CFG: (frontend): unknown analyzer-config 'no-false-positives' + +// RUN: %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config-compatibility-mode=true \ +// RUN: -analyzer-config no-false-positives=true + + +// Test the driver properly using "analyzer-config-compatibility-mode=true", +// no longer causing an error on input error. +// RUN: %clang --analyze %s + +// RUN: not %clang --analyze %s \ +// RUN: -Xclang -analyzer-config -Xclang no-false-positives=true \ +// RUN: -Xclang -analyzer-config-compatibility-mode=false \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-NO-COMPAT + +// CHECK-NO-COMPAT: error: unknown analyzer-config 'no-false-positives' + +// expected-no-diagnostics + +int main() {} diff --git a/test/Analysis/iterator-range.cpp b/test/Analysis/iterator-range.cpp index 32e3495a12..6fc8939c8e 100644 --- a/test/Analysis/iterator-range.cpp +++ b/test/Analysis/iterator-range.cpp @@ -23,34 +23,13 @@ void simple_good_end_negated(const std::vector<int> &v) { void simple_bad_end(const std::vector<int> &v) { auto i = v.end(); - *i; // expected-warning{{Iterator accessed outside of its range}} -} - -void simple_good_begin(const std::vector<int> &v) { - auto i = v.begin(); - if (i != v.begin()) { - clang_analyzer_warnIfReached(); - *--i; // no-warning - } -} - -void simple_good_begin_negated(const std::vector<int> &v) { - auto i = v.begin(); - if (!(i == v.begin())) { - clang_analyzer_warnIfReached(); - *--i; // no-warning - } -} - -void simple_bad_begin(const std::vector<int> &v) { - auto i = v.begin(); - *--i; // expected-warning{{Iterator accessed outside of its range}} + *i; // expected-warning{{Past-the-end iterator dereferenced}} } void copy(const std::vector<int> &v) { auto i1 = v.end(); auto i2 = i1; - *i2; // expected-warning{{Iterator accessed outside of its range}} + *i2; // expected-warning{{Past-the-end iterator dereferenced}} } void decrease(const std::vector<int> &v) { @@ -70,7 +49,7 @@ void copy_and_decrease2(const std::vector<int> &v) { auto i1 = v.end(); auto i2 = i1; --i1; - *i2; // expected-warning{{Iterator accessed outside of its range}} + *i2; // expected-warning{{Past-the-end iterator dereferenced}} } void copy_and_increase1(const std::vector<int> &v) { @@ -86,7 +65,7 @@ void copy_and_increase2(const std::vector<int> &v) { auto i2 = i1; ++i1; if (i2 == v.end()) - *i2; // expected-warning{{Iterator accessed outside of its range}} + *i2; // expected-warning{{Past-the-end iterator dereferenced}} } void copy_and_increase3(const std::vector<int> &v) { @@ -94,14 +73,36 @@ void copy_and_increase3(const std::vector<int> &v) { auto i2 = i1; ++i1; if (v.end() == i2) - *i2; // expected-warning{{Iterator accessed outside of its range}} + *i2; // expected-warning{{Past-the-end iterator dereferenced}} +} + +template <class InputIterator, class T> +InputIterator nonStdFind(InputIterator first, InputIterator last, + const T &val) { + for (auto i = first; i != last; ++i) { + if (*i == val) { + return i; + } + } + return last; +} + +void good_non_std_find(std::vector<int> &V, int e) { + auto first = nonStdFind(V.begin(), V.end(), e); + if (V.end() != first) + *first; // no-warning +} + +void bad_non_std_find(std::vector<int> &V, int e) { + auto first = nonStdFind(V.begin(), V.end(), e); + *first; // expected-warning{{Past-the-end iterator dereferenced}} } void tricky(std::vector<int> &V, int e) { const auto first = V.begin(); const auto comp1 = (first != V.end()), comp2 = (first == V.end()); if (comp1) - *first; + *first; // no-warning } void loop(std::vector<int> &V, int e) { @@ -125,7 +126,7 @@ void bad_push_back(std::list<int> &L, int n) { auto i0 = --L.cend(); L.push_back(n); ++i0; - *++i0; // expected-warning{{Iterator accessed outside of its range}} + *++i0; // expected-warning{{Past-the-end iterator dereferenced}} } void good_pop_back(std::list<int> &L, int n) { @@ -137,7 +138,7 @@ void good_pop_back(std::list<int> &L, int n) { void bad_pop_back(std::list<int> &L, int n) { auto i0 = --L.cend(); --i0; L.pop_back(); - *++i0; // expected-warning{{Iterator accessed outside of its range}} + *++i0; // expected-warning{{Past-the-end iterator dereferenced}} } void good_push_front(std::list<int> &L, int n) { @@ -150,7 +151,7 @@ void bad_push_front(std::list<int> &L, int n) { auto i0 = L.cbegin(); L.push_front(n); --i0; - *--i0; // expected-warning{{Iterator accessed outside of its range}} + --i0; // expected-warning{{Iterator decremented ahead of its valid range}} } void good_pop_front(std::list<int> &L, int n) { @@ -162,13 +163,13 @@ void good_pop_front(std::list<int> &L, int n) { void bad_pop_front(std::list<int> &L, int n) { auto i0 = ++L.cbegin(); L.pop_front(); - *--i0; // expected-warning{{Iterator accessed outside of its range}} + --i0; // expected-warning{{Iterator decremented ahead of its valid range}} } void bad_move(std::list<int> &L1, std::list<int> &L2) { auto i0 = --L2.cend(); L1 = std::move(L2); - *++i0; // expected-warning{{Iterator accessed outside of its range}} + *++i0; // expected-warning{{Past-the-end iterator dereferenced}} } void bad_move_push_back(std::list<int> &L1, std::list<int> &L2, int n) { @@ -176,5 +177,62 @@ void bad_move_push_back(std::list<int> &L1, std::list<int> &L2, int n) { L2.push_back(n); L1 = std::move(L2); ++i0; - *++i0; // expected-warning{{Iterator accessed outside of its range}} + *++i0; // expected-warning{{Past-the-end iterator dereferenced}} +} + +void good_incr_begin(const std::list<int> &L) { + auto i0 = L.begin(); + ++i0; // no-warning +} + +void bad_decr_begin(const std::list<int> &L) { + auto i0 = L.begin(); + --i0; // expected-warning{{Iterator decremented ahead of its valid range}} +} + +void good_decr_end(const std::list<int> &L) { + auto i0 = L.end(); + --i0; // no-warning +} + +void bad_incr_end(const std::list<int> &L) { + auto i0 = L.end(); + ++i0; // expected-warning{{Iterator incremented behind the past-the-end iterator}} +} + +struct simple_iterator_base { + simple_iterator_base(); + simple_iterator_base(const simple_iterator_base& rhs); + simple_iterator_base &operator=(const simple_iterator_base& rhs); + virtual ~simple_iterator_base(); + bool friend operator==(const simple_iterator_base &lhs, + const simple_iterator_base &rhs); + bool friend operator!=(const simple_iterator_base &lhs, + const simple_iterator_base &rhs); +private: + int *ptr; +}; + +struct simple_derived_iterator: public simple_iterator_base { + int& operator*(); + int* operator->(); + simple_iterator_base &operator++(); + simple_iterator_base operator++(int); + simple_iterator_base &operator--(); + simple_iterator_base operator--(int); +}; + +struct simple_container { + typedef simple_derived_iterator iterator; + + iterator begin(); + iterator end(); +}; + +void good_derived(simple_container c) { + auto i0 = c.end(); + if (i0 != c.end()) { + clang_analyzer_warnIfReached(); + *i0; // no-warning + } } diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m index 1725ce15f0..15a3b66b1a 100644 --- a/test/Analysis/keychainAPI.m +++ b/test/Analysis/keychainAPI.m @@ -212,7 +212,7 @@ int foo(CFTypeRef keychainOrArray, SecProtocolType protocol, if (st == noErr) SecKeychainItemFreeContent(ptr, outData[3]); } - if (length) { // TODO: We do not report a warning here since the symbol is no longer live, but it's not marked as dead. + if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}} length++; } return 0; @@ -454,3 +454,15 @@ int radar_19196494() { } return 0; } +int radar_19196494_v2() { + @autoreleasepool { + AuthorizationValue login_password = {}; + OSStatus err = SecKeychainFindGenericPassword(0, 0, "", 0, "", (UInt32 *)&login_password.length, (void**)&login_password.data, 0); + if (!login_password.data) return 0; + cb.SetContextVal(&login_password); + if (err == noErr) { + SecKeychainItemFreeContent(0, login_password.data); + } + } + return 0; +} diff --git a/test/Analysis/lit.local.cfg b/test/Analysis/lit.local.cfg index 811af6e54f..fdab3cfd12 100644 --- a/test/Analysis/lit.local.cfg +++ b/test/Analysis/lit.local.cfg @@ -14,5 +14,9 @@ config.test_format = analyzer_test.AnalyzerTest( config.substitutions.append(('%diff_plist', 'diff -u -w -I "<string>/" -I "<string>.:" -I "version" -')) +# Diff command for testing SARIF output to reference output. +config.substitutions.append(('%diff_sarif', + '''diff -U1 -w -I ".*file:.*%basename_t" -I '"version":' -I "2\.0\.0\-csd\.[0-9]*\.beta\." -''')) + if not config.root.clang_staticanalyzer: config.unsupported = True diff --git a/test/Analysis/llvm-conventions.cpp b/test/Analysis/llvm-conventions.cpp new file mode 100644 index 0000000000..49bdc6380b --- /dev/null +++ b/test/Analysis/llvm-conventions.cpp @@ -0,0 +1,225 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.llvm.Conventions \ +// RUN: -std=c++14 -verify %s + +#include "Inputs/system-header-simulator-cxx.h" + +//===----------------------------------------------------------------------===// +// Forward declarations for StringRef tests. +//===----------------------------------------------------------------------===// + +using size_type = size_t; + +namespace std { + +template <class T> +struct numeric_limits { const static bool is_signed; }; + +} // end of namespace std + +namespace llvm { + +template <class T> +struct iterator_range; + +template <class Func> +struct function_ref; + +struct hash_code; + +template <class T> +struct SmallVectorImpl; + +struct APInt; + +class StringRef { +public: + static const size_t npos = ~size_t(0); + using iterator = const char *; + using const_iterator = const char *; + using size_type = size_t; + + /*implicit*/ StringRef() = default; + StringRef(std::nullptr_t) = delete; + /*implicit*/ StringRef(const char *Str); + /*implicit*/ constexpr StringRef(const char *data, size_t length); + /*implicit*/ StringRef(const std::string &Str); + + static StringRef withNullAsEmpty(const char *data); + iterator begin() const; + iterator end() const; + const unsigned char *bytes_begin() const; + const unsigned char *bytes_end() const; + iterator_range<const unsigned char *> bytes() const; + const char *data() const; + bool empty() const; + size_t size() const; + char front() const; + char back() const; + template <typename Allocator> + StringRef copy(Allocator &A) const; + bool equals(StringRef RHS) const; + bool equals_lower(StringRef RHS) const; + int compare(StringRef RHS) const; + int compare_lower(StringRef RHS) const; + int compare_numeric(StringRef RHS) const; + unsigned edit_distance(StringRef Other, bool AllowReplacements = true, + unsigned MaxEditDistance = 0) const; + std::string str() const; + char operator[](size_t Index) const; + template <typename T> + typename std::enable_if<std::is_same<T, std::string>::value, + StringRef>::type & + operator=(T &&Str) = delete; + operator std::string() const; + bool startswith(StringRef Prefix) const; + bool startswith_lower(StringRef Prefix) const; + bool endswith(StringRef Suffix) const; + bool endswith_lower(StringRef Suffix) const; + size_t find(char C, size_t From = 0) const; + size_t find_lower(char C, size_t From = 0) const; + size_t find_if(function_ref<bool(char)> F, size_t From = 0) const; + size_t find_if_not(function_ref<bool(char)> F, size_t From = 0) const; + size_t find(StringRef Str, size_t From = 0) const; + size_t find_lower(StringRef Str, size_t From = 0) const; + size_t rfind(char C, size_t From = npos) const; + size_t rfind_lower(char C, size_t From = npos) const; + size_t rfind(StringRef Str) const; + size_t rfind_lower(StringRef Str) const; + size_t find_first_of(char C, size_t From = 0) const; + size_t find_first_of(StringRef Chars, size_t From = 0) const; + size_t find_first_not_of(char C, size_t From = 0) const; + size_t find_first_not_of(StringRef Chars, size_t From = 0) const; + size_t find_last_of(char C, size_t From = npos) const; + size_t find_last_of(StringRef Chars, size_t From = npos) const; + size_t find_last_not_of(char C, size_t From = npos) const; + size_t find_last_not_of(StringRef Chars, size_t From = npos) const; + bool contains(StringRef Other) const; + bool contains(char C) const; + bool contains_lower(StringRef Other) const; + bool contains_lower(char C) const; + size_t count(char C) const; + size_t count(StringRef Str) const; + template <typename T> + typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type + getAsInteger(unsigned Radix, T &Result) const; + template <typename T> + typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type + getAsInteger(unsigned Radix, T &Result) const; + template <typename T> + typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type + consumeInteger(unsigned Radix, T &Result); + template <typename T> + typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type + consumeInteger(unsigned Radix, T &Result); + bool getAsInteger(unsigned Radix, APInt &Result) const; + bool getAsDouble(double &Result, bool AllowInexact = true) const; + std::string lower() const; + std::string upper() const; + StringRef substr(size_t Start, size_t N = npos) const; + StringRef take_front(size_t N = 1) const; + StringRef take_back(size_t N = 1) const; + StringRef take_while(function_ref<bool(char)> F) const; + StringRef take_until(function_ref<bool(char)> F) const; + StringRef drop_front(size_t N = 1) const; + StringRef drop_back(size_t N = 1) const; + StringRef drop_while(function_ref<bool(char)> F) const; + StringRef drop_until(function_ref<bool(char)> F) const; + bool consume_front(StringRef Prefix); + bool consume_back(StringRef Suffix); + StringRef slice(size_t Start, size_t End) const; + std::pair<StringRef, StringRef> split(char Separator) const; + std::pair<StringRef, StringRef> split(StringRef Separator) const; + std::pair<StringRef, StringRef> rsplit(StringRef Separator) const; + void split(SmallVectorImpl<StringRef> &A, + StringRef Separator, int MaxSplit = -1, + bool KeepEmpty = true) const; + void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1, + bool KeepEmpty = true) const; + std::pair<StringRef, StringRef> rsplit(char Separator) const; + StringRef ltrim(char Char) const; + StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const; + StringRef rtrim(char Char) const; + StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const; + StringRef trim(char Char) const; + StringRef trim(StringRef Chars = " \t\n\v\f\r") const; +}; + +inline bool operator==(StringRef LHS, StringRef RHS); +inline bool operator!=(StringRef LHS, StringRef RHS); +inline bool operator<(StringRef LHS, StringRef RHS); +inline bool operator<=(StringRef LHS, StringRef RHS); +inline bool operator>(StringRef LHS, StringRef RHS); +inline bool operator>=(StringRef LHS, StringRef RHS); +inline std::string &operator+=(std::string &buffer, StringRef string); +hash_code hash_value(StringRef S); +template <typename T> struct isPodLike; +template <> struct isPodLike<StringRef> { static const bool value = true; }; + +} // end of namespace llvm + +//===----------------------------------------------------------------------===// +// Tests for StringRef. +//===----------------------------------------------------------------------===// + +void temporarayStringToStringRefAssignmentTest() { + // TODO: Emit a warning. + llvm::StringRef Ref = std::string("Yimmy yummy test."); +} + +void assigningStringToStringRefWithLongerLifetimeTest() { + llvm::StringRef Ref; + { + // TODO: Emit a warning. + std::string TmpStr("This is a fine string."); + Ref = TmpStr; + } +} + +std::string getTemporaryString() { + return "One two three."; +} + +void assigningTempStringFromFunctionToStringRefTest() { + // TODO: Emit a warning. + llvm::StringRef Ref = getTemporaryString(); +} + +//===----------------------------------------------------------------------===// +// Forward declaration for Clang AST nodes. +//===----------------------------------------------------------------------===// + +namespace llvm { + +template <class T, int Size> +struct SmallVector {}; + +} // end of namespace llvm + +namespace clang { + +struct Type; +struct Decl; +struct Stmt; +struct Attr; + +} // end of namespace clang + +//===----------------------------------------------------------------------===// +// Tests for Clang AST nodes. +//===----------------------------------------------------------------------===// + +namespace clang { + +struct Type { + std::string str; // expected-warning{{AST class 'Type' has a field 'str' that allocates heap memory (type std::string)}} +}; + +} // end of namespace clang + +namespace clang { + +struct Decl { + llvm::SmallVector<int, 5> Vec; // expected-warning{{AST class 'Decl' has a field 'Vec' that allocates heap memory (type llvm::SmallVector<int, 5>)}} +}; + +} // end of namespace clang diff --git a/test/Analysis/localization-aggressive.m b/test/Analysis/localization-aggressive.m index ea5e0b1529..2e273e0c48 100644 --- a/test/Analysis/localization-aggressive.m +++ b/test/Analysis/localization-aggressive.m @@ -1,6 +1,10 @@ // RUN: %clang_cc1 -fblocks -x objective-c-header -emit-pch -o %t.pch %S/Inputs/localization-pch.h -// RUN: %clang_analyze_cc1 -fblocks -analyzer-store=region -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=optin.osx.cocoa.localizability.EmptyLocalizationContextChecker -include-pch %t.pch -verify -analyzer-config AggressiveReport=true %s +// RUN: %clang_analyze_cc1 -fblocks -analyzer-store=region \ +// RUN: -analyzer-config optin.osx.cocoa.localizability.NonLocalizedStringChecker:AggressiveReport=true \ +// RUN: -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker \ +// RUN: -analyzer-checker=optin.osx.cocoa.localizability.EmptyLocalizationContextChecker \ +// RUN: -include-pch %t.pch -verify %s // These declarations were reduced using Delta-Debugging from Foundation.h // on Mac OS X. diff --git a/test/Analysis/loop-block-counts.c b/test/Analysis/loop-block-counts.c new file mode 100644 index 0000000000..04a3f747c2 --- /dev/null +++ b/test/Analysis/loop-block-counts.c @@ -0,0 +1,26 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_eval(int); + +void callee(void **p) { + int x; + *p = &x; +} + +void loop() { + void *arr[2]; + for (int i = 0; i < 2; ++i) + callee(&arr[i]); + // FIXME: Should be UNKNOWN. + clang_analyzer_eval(arr[0] == arr[1]); // expected-warning{{TRUE}} +} + +void loopWithCall() { + void *arr[2]; + for (int i = 0; i < 2; ++i) { + int x; + arr[i] = &x; + } + // FIXME: Should be UNKNOWN. + clang_analyzer_eval(arr[0] == arr[1]); // expected-warning{{TRUE}} +} diff --git a/test/Analysis/member-expr.cpp b/test/Analysis/member-expr.cpp index 9951943e30..8fb6fe48f0 100644 --- a/test/Analysis/member-expr.cpp +++ b/test/Analysis/member-expr.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %s -verify +// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,debug.ExprInspection %s -verify void clang_analyzer_checkInlined(bool); void clang_analyzer_eval(int); diff --git a/test/Analysis/mismatched-iterator.cpp b/test/Analysis/mismatched-iterator.cpp index 7910b77c0b..23f54d3f79 100644 --- a/test/Analysis/mismatched-iterator.cpp +++ b/test/Analysis/mismatched-iterator.cpp @@ -144,6 +144,19 @@ void bad_overwrite(std::vector<int> &v1, std::vector<int> &v2, int n) { v1.insert(i, n); // expected-warning{{Container accessed using foreign iterator argument}} } +template<typename Container, typename Iterator> +bool is_cend(Container cont, Iterator it) { + return it == cont.cend(); +} + +void good_empty(std::vector<int> &v) { + is_cend(v, v.cbegin()); // no-warning +} + +void bad_empty(std::vector<int> &v1, std::vector<int> &v2) { + is_cend(v1, v2.cbegin()); // expected-warning@-8{{Iterators of different containers used where the same container is expected}} +} + void good_move(std::vector<int> &v1, std::vector<int> &v2) { const auto i0 = ++v2.cbegin(); v1 = std::move(v2); diff --git a/test/Analysis/new-aligned.cpp b/test/Analysis/new-aligned.cpp new file mode 100644 index 0000000000..fae1f48648 --- /dev/null +++ b/test/Analysis/new-aligned.cpp @@ -0,0 +1,14 @@ +//RUN: %clang_analyze_cc1 -std=c++17 -analyze -analyzer-checker=core -verify %s + +// expected-no-diagnostics + +// Notice the weird alignment. +struct alignas(1024) S {}; + +void foo() { + // Operator new() here is the C++17 aligned new that takes two arguments: + // size and alignment. Size is passed implicitly as usual, and alignment + // is passed implicitly in a similar manner. + S *s = new S; // no-warning + delete s; +} diff --git a/test/Analysis/nullability-arc.mm b/test/Analysis/nullability-arc.mm new file mode 100644 index 0000000000..5c68dda42e --- /dev/null +++ b/test/Analysis/nullability-arc.mm @@ -0,0 +1,39 @@ +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,nullability\ +// RUN: -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,nullability\ +// RUN: -analyzer-output=text -verify %s -fobjc-arc + +#if !__has_feature(objc_arc) +// expected-no-diagnostics +#endif + + +#define nil ((id)0) + +@interface Param +@end + +@interface Base +- (void)foo:(Param *_Nonnull)param; +@end + +@interface Derived : Base +@end + +@implementation Derived +- (void)foo:(Param *)param { + // FIXME: Why do we not emit the warning under ARC? + [super foo:param]; +#if __has_feature(objc_arc) + // expected-warning@-2{{nil passed to a callee that requires a non-null 1st parameter}} + // expected-note@-3 {{nil passed to a callee that requires a non-null 1st parameter}} +#endif + + [self foo:nil]; +#if __has_feature(objc_arc) + // expected-note@-2{{Calling 'foo:'}} + // expected-note@-3{{Passing nil object reference via 1st parameter 'param'}} +#endif +} +@end + diff --git a/test/Analysis/nullability.mm b/test/Analysis/nullability.mm index 2278efff3e..c3f27e4d22 100644 --- a/test/Analysis/nullability.mm +++ b/test/Analysis/nullability.mm @@ -1,5 +1,36 @@ -// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -DNOSYSTEMHEADERS=0 -verify %s -// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s +// RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core \ +// RUN: -analyzer-checker=nullability.NullPassedToNonnull \ +// RUN: -analyzer-checker=nullability.NullReturnedFromNonnull \ +// RUN: -analyzer-checker=nullability.NullablePassedToNonnull \ +// RUN: -analyzer-checker=nullability.NullableReturnedFromNonnull \ +// RUN: -analyzer-checker=nullability.NullableDereferenced \ +// RUN: -DNOSYSTEMHEADERS=0 + +// RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core \ +// RUN: -analyzer-checker=nullability.NullPassedToNonnull \ +// RUN: -analyzer-checker=nullability.NullReturnedFromNonnull \ +// RUN: -analyzer-checker=nullability.NullablePassedToNonnull \ +// RUN: -analyzer-checker=nullability.NullableReturnedFromNonnull \ +// RUN: -analyzer-checker=nullability.NullableDereferenced \ +// RUN: -DNOSYSTEMHEADERS=1 \ +// RUN: -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true + +// RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core\ +// RUN: -analyzer-checker=nullability.NullPassedToNonnull\ +// RUN: -analyzer-checker=nullability.NullReturnedFromNonnull\ +// RUN: -analyzer-checker=nullability.NullablePassedToNonnull\ +// RUN: -analyzer-checker=nullability.NullableReturnedFromNonnull\ +// RUN: -analyzer-checker=nullability.NullableDereferenced\ +// RUN: -DNOSYSTEMHEADERS=0 -fobjc-arc + +// RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core\ +// RUN: -analyzer-checker=nullability.NullPassedToNonnull\ +// RUN: -analyzer-checker=nullability.NullReturnedFromNonnull\ +// RUN: -analyzer-checker=nullability.NullablePassedToNonnull\ +// RUN: -analyzer-checker=nullability.NullableReturnedFromNonnull\ +// RUN: -analyzer-checker=nullability.NullableDereferenced\ +// RUN: -DNOSYSTEMHEADERS=1 -fobjc-arc\ +// RUN: -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true #include "Inputs/system-header-simulator-for-nullability.h" diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp index 38e099b7fb..1d913c11d3 100644 --- a/test/Analysis/nullptr.cpp +++ b/test/Analysis/nullptr.cpp @@ -125,21 +125,16 @@ struct Type { }; void shouldNotCrash() { - decltype(nullptr) p; // expected-note{{'p' declared without an initial value}} - if (getSymbol()) // expected-note {{Assuming the condition is false}} - // expected-note@-1{{Taking false branch}} - // expected-note@-2{{Assuming the condition is false}} - // expected-note@-3{{Taking false branch}} - // expected-note@-4{{Assuming the condition is true}} - // expected-note@-5{{Taking true branch}} - invokeF(p); // expected-warning{{1st function call argument is an uninitialized value}} - // expected-note@-1{{1st function call argument is an uninitialized value}} + decltype(nullptr) p; // expected-note{{'p' initialized to a null pointer value}} if (getSymbol()) // expected-note {{Assuming the condition is false}} // expected-note@-1{{Taking false branch}} // expected-note@-2{{Assuming the condition is true}} // expected-note@-3{{Taking true branch}} - invokeF(nullptr); // expected-note {{Calling 'invokeF'}} - // expected-note@-1{{Passing null pointer value via 1st parameter 'x'}} + invokeF(p); // expected-note{{Passing null pointer value via 1st parameter 'x'}} + // expected-note@-1{{Calling 'invokeF'}} + if (getSymbol()) // expected-note {{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + invokeF(nullptr); if (getSymbol()) { // expected-note {{Assuming the condition is true}} // expected-note@-1{{Taking true branch}} X *xx = Type().x; // expected-note {{Null pointer value stored to field 'x'}} diff --git a/test/Analysis/objc-radar17039661.m b/test/Analysis/objc-radar17039661.m index 0d2ddbfc30..5f7c531eae 100644 --- a/test/Analysis/objc-radar17039661.m +++ b/test/Analysis/objc-radar17039661.m @@ -1315,12 +1315,12 @@ void runTest() { // CHECK: </array> // CHECK: <key>depth</key><integer>4</integer> // CHECK: <key>extended_message</key> -// CHECK: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <string>Object leaked: allocated object of type NSNumber * is not referenced later in this execution path and has a retain count of +1</string> // CHECK: <key>message</key> -// CHECK: <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <string>Object leaked: allocated object of type NSNumber * is not referenced later in this execution path and has a retain count of +1</string> // CHECK: </dict> // CHECK: </array> -// CHECK: <key>description</key><string>Potential leak of an object</string> +// CHECK: <key>description</key><string>Potential leak of an object of type NSNumber *</string> // CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> // CHECK: <key>type</key><string>Leak</string> // CHECK: <key>location</key> diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp index 18bdf0bafc..b8eb462d20 100644 --- a/test/Analysis/osobject-retain-release.cpp +++ b/test/Analysis/osobject-retain-release.cpp @@ -1,43 +1,231 @@ -// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config osx.cocoa.RetainCount:CheckOSObject=true -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=text -verify %s + +struct OSMetaClass; + +#define OS_CONSUME __attribute__((os_consumed)) +#define OS_RETURNS_RETAINED __attribute__((os_returns_retained)) +#define OS_RETURNS_NOT_RETAINED __attribute__((os_returns_not_retained)) +#define OS_CONSUMES_THIS __attribute__((os_consumes_this)) + +#define OSTypeID(type) (type::metaClass) + +#define OSDynamicCast(type, inst) \ + ((type *) OSMetaClassBase::safeMetaCast((inst), OSTypeID(type))) + +using size_t = decltype(sizeof(int)); struct OSObject { virtual void retain(); - virtual void release(); - + virtual void release() {}; + virtual void free(); virtual ~OSObject(){} + + unsigned int foo() { return 42; } + + virtual OS_RETURNS_NOT_RETAINED OSObject *identity(); + + static OSObject *generateObject(int); + + static OSObject *getObject(); + static OSObject *GetObject(); + + static void * operator new(size_t size); + + static const OSMetaClass * const metaClass; +}; + +struct OSIterator : public OSObject { + + static const OSMetaClass * const metaClass; }; struct OSArray : public OSObject { unsigned int getCount(); + OSIterator * getIterator(); + + OSObject *identity() override; + + virtual OSObject *generateObject(OSObject *input); + + virtual void consumeReference(OS_CONSUME OSArray *other); + + void putIntoArray(OSArray *array) OS_CONSUMES_THIS; + + template <typename T> + void putIntoT(T *owner) OS_CONSUMES_THIS; + + static OSArray *generateArrayHasCode() { + return new OSArray; + } + static OSArray *withCapacity(unsigned int capacity); + static void consumeArray(OS_CONSUME OSArray * array); + + static OSArray* consumeArrayHasCode(OS_CONSUME OSArray * array) { + return nullptr; + } + + static OS_RETURNS_NOT_RETAINED OSArray *MaskedGetter(); + static OS_RETURNS_RETAINED OSArray *getOoopsActuallyCreate(); + + static const OSMetaClass * const metaClass; }; -void use_after_release() { - OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain count}} - arr->release(); // expected-note{{Object released}} - arr->getCount(); // expected-warning{{Reference-counted object is used after it is released}} - // expected-note@-1{{Reference-counted object is used after it is released}} +struct MyArray : public OSArray { + void consumeReference(OSArray *other) override; + + OSObject *identity() override; + + OSObject *generateObject(OSObject *input) override; +}; + +struct OtherStruct { + static void doNothingToArray(OSArray *array); + OtherStruct(OSArray *arr); +}; + +struct OSMetaClassBase { + static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta); +}; + +void escape(void *); +bool coin(); + +bool os_consume_violation(OS_CONSUME OSObject *obj) { + if (coin()) { // expected-note{{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + escape(obj); + return true; + } + return false; // expected-note{{Parameter 'obj' is marked as consuming, but the function does not consume the reference}} } -void potential_leak() { - OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain count}} +void os_consume_ok(OS_CONSUME OSObject *obj) { + escape(obj); +} + +void use_os_consume_violation() { + OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type OSObject with a +1 retain count}} + os_consume_violation(obj); // expected-note{{Calling 'os_consume_violation'}} + // expected-note@-1{{Returning from 'os_consume_violation'}} +} // expected-note{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}} + // expected-warning@-1{{Potential leak of an object stored into 'obj'}} + +void use_os_consume_ok() { + OSObject *obj = new OSObject; + os_consume_ok(obj); +} + +void test_escaping_into_voidstar() { + OSObject *obj = new OSObject; + escape(obj); +} + +void test_no_infinite_check_recursion(MyArray *arr) { + OSObject *input = new OSObject; + OSObject *o = arr->generateObject(input); + o->release(); + input->release(); +} + + +void check_param_attribute_propagation(MyArray *parent) { + OSArray *arr = new OSArray; + parent->consumeReference(arr); +} + +unsigned int check_attribute_propagation(OSArray *arr) { + OSObject *other = arr->identity(); + OSArray *casted = OSDynamicCast(OSArray, other); + if (casted) + return casted->getCount(); + return 0; +} + +unsigned int check_attribute_indirect_propagation(MyArray *arr) { + OSObject *other = arr->identity(); + OSArray *casted = OSDynamicCast(OSArray, other); + if (casted) + return casted->getCount(); + return 0; +} + +void check_consumes_this(OSArray *owner) { + OSArray *arr = new OSArray; + arr->putIntoArray(owner); +} + +void check_consumes_this_with_template(OSArray *owner) { + OSArray *arr = new OSArray; + arr->putIntoT(owner); +} + +void check_free_no_error() { + OSArray *arr = OSArray::withCapacity(10); + arr->retain(); + arr->retain(); + arr->retain(); + arr->free(); +} + +void check_free_use_after_free() { + OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}} arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}} - arr->release(); // expected-note{{Reference count decremented. The object now has a +1 retain count}} - arr->getCount(); + arr->free(); // expected-note{{Object released}} + arr->retain(); // expected-warning{{Reference-counted object is used after it is released}} + // expected-note@-1{{Reference-counted object is used after it is released}} +} + +unsigned int check_leak_explicit_new() { + OSArray *arr = new OSArray; // expected-note{{Operator 'new' returns an OSObject of type OSArray with a +1 retain count}} + return arr->getCount(); // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}} + // expected-warning@-1{{Potential leak of an object stored into 'arr'}} +} + +unsigned int check_leak_factory() { + OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}} + return arr->getCount(); // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}} + // expected-warning@-1{{Potential leak of an object stored into 'arr'}} +} + +void check_get_object() { + OSObject::getObject(); +} + +void check_Get_object() { + OSObject::GetObject(); +} + +void check_custom_iterator_rule(OSArray *arr) { + OSIterator *it = arr->getIterator(); + it->release(); +} + +void check_iterator_leak(OSArray *arr) { + arr->getIterator(); // expected-note{{Call to method 'OSArray::getIterator' returns an OSObject of type OSIterator with a +1 retain count}} +} // expected-note{{Object leaked: allocated object of type OSIterator is not referenced later}} + // expected-warning@-1{{Potential leak of an object of type OSIterator}} + +void check_no_invalidation() { + OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}} + OtherStruct::doNothingToArray(arr); } // expected-warning{{Potential leak of an object stored into 'arr'}} - // expected-note@-1{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}} + // expected-note@-1{{Object leaked}} -void proper_cleanup() { - OSArray *arr = OSArray::withCapacity(10); // +1 - arr->retain(); // +2 - arr->release(); // +1 - arr->getCount(); - arr->release(); // 0 +void check_no_invalidation_other_struct() { + OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}} + OtherStruct other(arr); // expected-warning{{Potential leak}} + // expected-note@-1{{Object leaked}} } -struct ArrayOwner { +struct ArrayOwner : public OSObject { OSArray *arr; + ArrayOwner(OSArray *arr) : arr(arr) {} + + static ArrayOwner* create(OSArray *arr) { + return new ArrayOwner(arr); + } OSArray *getArray() { return arr; @@ -52,10 +240,116 @@ struct ArrayOwner { OSArray *getArraySourceUnknown(); }; -//unsigned int leak_on_create_no_release(ArrayOwner *owner) { - //OSArray *myArray = +OSArray *generateArray() { + return OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}} + // expected-note@-1{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}} +} -//} +unsigned int check_leak_good_error_message() { + unsigned int out; + { + OSArray *leaked = generateArray(); // expected-note{{Calling 'generateArray'}} + // expected-note@-1{{Returning from 'generateArray'}} + out = leaked->getCount(); // expected-warning{{Potential leak of an object stored into 'leaked'}} + // expected-note@-1{{Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1}} + } + return out; +} + +unsigned int check_leak_msg_temporary() { + return generateArray()->getCount(); // expected-warning{{Potential leak of an object}} + // expected-note@-1{{Calling 'generateArray'}} + // expected-note@-2{{Returning from 'generateArray'}} + // expected-note@-3{{Object leaked: allocated object of type OSArray is not referenced later in this execution path and has a retain count of +1}} +} + +void check_confusing_getters() { + OSArray *arr = OSArray::withCapacity(10); + + ArrayOwner *AO = ArrayOwner::create(arr); + AO->getArray(); + + AO->release(); + arr->release(); +} + +void check_rc_consumed() { + OSArray *arr = OSArray::withCapacity(10); + OSArray::consumeArray(arr); +} + +void check_rc_consume_temporary() { + OSArray::consumeArray(OSArray::withCapacity(10)); +} + +void check_rc_getter() { + OSArray *arr = OSArray::MaskedGetter(); + (void)arr; +} + +void check_rc_create() { + OSArray *arr = OSArray::getOoopsActuallyCreate(); + arr->release(); +} + + +void check_dynamic_cast() { + OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1)); + arr->release(); +} + +unsigned int check_dynamic_cast_no_null_on_orig(OSObject *obj) { + OSArray *arr = OSDynamicCast(OSArray, obj); + if (arr) { + return arr->getCount(); + } else { + + // The fact that dynamic cast has failed should not imply that + // the input object was null. + return obj->foo(); // no-warning + } +} + +void check_dynamic_cast_null_branch(OSObject *obj) { + OSArray *arr1 = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject}} + OSArray *arr = OSDynamicCast(OSArray, obj); + if (!arr) // expected-note{{Taking true branch}} + return; // expected-warning{{Potential leak of an object stored into 'arr1'}} + // expected-note@-1{{Object leaked}} + arr1->release(); +} + +void check_dynamic_cast_null_check() { + OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1)); // expected-note{{Call to method 'OSObject::generateObject' returns an OSObject}} + // expected-warning@-1{{Potential leak of an object}} + // expected-note@-2{{Object leaked}} + if (!arr) + return; + arr->release(); +} + +void use_after_release() { + OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}} + arr->release(); // expected-note{{Object released}} + arr->getCount(); // expected-warning{{Reference-counted object is used after it is released}} + // expected-note@-1{{Reference-counted object is used after it is released}} +} + +void potential_leak() { + OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}} + arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}} + arr->release(); // expected-note{{Reference count decremented. The object now has a +1 retain count}} + arr->getCount(); +} // expected-warning{{Potential leak of an object stored into 'arr'}} + // expected-note@-1{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}} + +void proper_cleanup() { + OSArray *arr = OSArray::withCapacity(10); // +1 + arr->retain(); // +2 + arr->release(); // +1 + arr->getCount(); + arr->release(); // 0 +} unsigned int no_warning_on_getter(ArrayOwner *owner) { OSArray *arr = owner->getArray(); @@ -63,9 +357,11 @@ unsigned int no_warning_on_getter(ArrayOwner *owner) { } unsigned int warn_on_overrelease(ArrayOwner *owner) { - OSArray *arr = owner->getArray(); // expected-note{{function call returns an OSObject of type struct OSArray * with a +0 retain count}} - arr->release(); // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} - // expected-note@-1{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} + // FIXME: summaries are not applied in case the source of the getter/setter + // is known. + // rdar://45681203 + OSArray *arr = owner->getArray(); + arr->release(); return arr->getCount(); } @@ -91,7 +387,7 @@ unsigned int no_warn_ok_release(ArrayOwner *owner) { } unsigned int warn_on_overrelease_with_unknown_source(ArrayOwner *owner) { - OSArray *arr = owner->getArraySourceUnknown(); // expected-note{{function call returns an OSObject of type struct OSArray * with a +0 retain count}} + OSArray *arr = owner->getArraySourceUnknown(); // expected-note{{Call to method 'ArrayOwner::getArraySourceUnknown' returns an OSObject of type OSArray with a +0 retain count}} arr->release(); // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} // expected-note@-1{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} return arr->getCount(); diff --git a/test/Analysis/padding_inherit.cpp b/test/Analysis/padding_inherit.cpp new file mode 100644 index 0000000000..2222c990a1 --- /dev/null +++ b/test/Analysis/padding_inherit.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=20 -verify %s + +// A class that has no fields and one base class should visit that base class +// instead. Note that despite having excess padding of 2, this is flagged +// because of its usage in an array of 100 elements below (`ais'). +// TODO: Add a note to the bug report with BugReport::addNote() to mention the +// variable using the class and also mention what class is inherting from what. +// expected-warning@+1{{Excessive padding in 'struct FakeIntSandwich'}} +struct FakeIntSandwich { + char c1; + int i; + char c2; +}; + +struct AnotherIntSandwich : FakeIntSandwich { // no-warning +}; + +// But we don't yet support multiple base classes. +struct IntSandwich {}; +struct TooManyBaseClasses : FakeIntSandwich, IntSandwich { // no-warning +}; + +AnotherIntSandwich ais[100]; + +struct Empty {}; +struct DoubleEmpty : Empty { // no-warning + Empty e; +}; diff --git a/test/Analysis/plist-macros-with-expansion.cpp b/test/Analysis/plist-macros-with-expansion.cpp new file mode 100644 index 0000000000..14dccd07c6 --- /dev/null +++ b/test/Analysis/plist-macros-with-expansion.cpp @@ -0,0 +1,442 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s +// +// RUN: %clang_analyze_cc1 -analyzer-checker=core %s \ +// RUN: -analyzer-output=plist -o %t.plist \ +// RUN: -analyzer-config expand-macros=true +// +// Check the actual plist output. +// RUN: cat %t.plist | %diff_plist \ +// RUN: %S/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist +// +// Check the macro expansions from the plist output here, to make the test more +// understandable. +// RUN: FileCheck --input-file=%t.plist %s + +void print(const void*); + +//===----------------------------------------------------------------------===// +// Tests for non-function-like macro expansions. +//===----------------------------------------------------------------------===// + +#define SET_PTR_VAR_TO_NULL \ + ptr = 0 + +void nonFunctionLikeMacroTest() { + int *ptr; + SET_PTR_VAR_TO_NULL; + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>SET_PTR_VAR_TO_NULL</string> +// CHECK-NEXT: <key>expansion</key><string>ptr = 0</string> + +#define NULL 0 +#define SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO \ + ptr = NULL + +void nonFunctionLikeNestedMacroTest() { + int *ptr; + SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO; + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO</string> +// CHECK-NEXT: <key>expansion</key><string>ptr =0</string> + +//===----------------------------------------------------------------------===// +// Tests for function-like macro expansions. +//===----------------------------------------------------------------------===// + +void setToNull(int **vptr) { + *vptr = nullptr; +} + +#define TO_NULL(x) \ + setToNull(x) + +void functionLikeMacroTest() { + int *ptr; + TO_NULL(&ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>TO_NULL</string> +// CHECK-NEXT: <key>expansion</key><string>setToNull(&ptr)</string> + +#define DOES_NOTHING(x) \ + { \ + int b; \ + b = 5; \ + } \ + print(x) + +#define DEREF(x) \ + DOES_NOTHING(x); \ + *x + +void functionLikeNestedMacroTest() { + int *a; + TO_NULL(&a); + DEREF(a) = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>TO_NULL</string> +// CHECK-NEXT: <key>expansion</key><string>setToNull(&a)</string> + +// CHECK: <key>name</key><string>DEREF</string> +// CHECK-NEXT: <key>expansion</key><string>{ int b; b = 5; } print(a); *a</string> + +//===----------------------------------------------------------------------===// +// Tests for undefining and/or redifining macros. +//===----------------------------------------------------------------------===// + +#define WILL_UNDEF_SET_NULL_TO_PTR(ptr) \ + ptr = nullptr; + +void undefinedMacroByTheEndOfParsingTest() { + int *ptr; + WILL_UNDEF_SET_NULL_TO_PTR(ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +#undef WILL_UNDEF_SET_NULL_TO_PTR + +// CHECK: <key>name</key><string>WILL_UNDEF_SET_NULL_TO_PTR</string> +// CHECK-NEXT: <key>expansion</key><string>ptr = nullptr;</string> + +#define WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr) \ + /* Nothing */ +#undef WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL +#define WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr) \ + ptr = nullptr; + +void macroRedefinedMultipleTimesTest() { + int *ptr; + WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr) + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +#undef WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL +#define WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr) \ + print("This string shouldn't be in the plist file at all. Or anywhere, " \ + "but here."); + +// CHECK: <key>name</key><string>WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL</string> +// CHECK-NEXT: <key>expansion</key><string>ptr = nullptr;</string> + +#define WILL_UNDEF_SET_NULL_TO_PTR_2(ptr) \ + ptr = nullptr; + +#define PASS_PTR_TO_MACRO_THAT_WILL_BE_UNDEFD(ptr) \ + WILL_UNDEF_SET_NULL_TO_PTR_2(ptr) + +void undefinedMacroInsideAnotherMacroTest() { + int *ptr; + PASS_PTR_TO_MACRO_THAT_WILL_BE_UNDEFD(ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// TODO: Expand arguments. +// CHECK: <key>name</key><string>PASS_PTR_TO_MACRO_THAT_WILL_BE_UNDEFD</string> +// CHECK-NEXT: <key>expansion</key><string>ptr = nullptr;</string> + +#undef WILL_UNDEF_SET_NULL_TO_PTR_2 + +//===----------------------------------------------------------------------===// +// Tests for macro arguments containing commas and parantheses. +// +// As of writing these tests, the algorithm expands macro arguments by lexing +// the macro's expansion location, and relies on finding tok::comma and +// tok::l_paren/tok::r_paren. +//===----------------------------------------------------------------------===// + +// Note that this commas, parantheses in strings aren't parsed as tok::comma or +// tok::l_paren/tok::r_paren, but why not test them. + +#define TO_NULL_AND_PRINT(x, str) \ + x = 0; \ + print(str) + +void macroArgContainsCommaInStringTest() { + int *a; + TO_NULL_AND_PRINT(a, "Will this , cause a crash?"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>TO_NULL_AND_PRINT</string> +// CHECK-NEXT: <key>expansion</key><string>a = 0; print( "Will this , cause a crash?")</string> + +void macroArgContainsLParenInStringTest() { + int *a; + TO_NULL_AND_PRINT(a, "Will this ( cause a crash?"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>TO_NULL_AND_PRINT</string> +// CHECK-NEXT: <key>expansion</key><string>a = 0; print( "Will this ( cause a crash?")</string> + +void macroArgContainsRParenInStringTest() { + int *a; + TO_NULL_AND_PRINT(a, "Will this ) cause a crash?"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>TO_NULL_AND_PRINT</string> +// CHECK-NEXT: <key>expansion</key><string>a = 0; print( "Will this ) cause a crash?")</string> + +#define CALL_FUNCTION(funcCall) \ + funcCall + +// Function calls do contain both tok::comma and tok::l_paren/tok::r_paren. + +void macroArgContainsLParenRParenTest() { + int *a; + CALL_FUNCTION(setToNull(&a)); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>CALL_FUNCTION</string> +// CHECK-NEXT: <key>expansion</key><string>setToNull(&a)</string> + +void setToNullAndPrint(int **vptr, const char *str) { + setToNull(vptr); + print(str); +} + +void macroArgContainsCommaLParenRParenTest() { + int *a; + CALL_FUNCTION(setToNullAndPrint(&a, "Hello!")); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>CALL_FUNCTION</string> +// CHECK-NEXT: <key>expansion</key><string>setToNullAndPrint(&a, "Hello!")</string> + +#define CALL_FUNCTION_WITH_TWO_PARAMS(funcCall, param1, param2) \ + funcCall(param1, param2) + +void macroArgContainsCommaLParenRParenTest2() { + int *a; + CALL_FUNCTION_WITH_TWO_PARAMS(setToNullAndPrint, &a, "Hello!"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>CALL_FUNCTION_WITH_TWO_PARAMS</string> +// CHECK-NEXT: <key>expansion</key><string>setToNullAndPrint( &a, "Hello!")</string> + +#define CALL_LAMBDA(l) \ + l() + +void commaInBracketsTest() { + int *ptr; + const char str[] = "Hello!"; + // You need to add parantheses around a lambda expression to compile this, + // else the comma in the capture will be parsed as divider of macro args. + CALL_LAMBDA(([&ptr, str] () mutable { TO_NULL(&ptr); })); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>CALL_LAMBDA</string> +// CHECK-NEXT: <key>expansion</key><string>([&ptr, str] () mutable { setToNull(&ptr); })()</string> + +#define PASTE_CODE(code) \ + code + +void commaInBracesTest() { + PASTE_CODE({ // expected-warning{{Dereference of null pointer}} + // NOTE: If we were to add a new variable here after a comma, we'd get a + // compilation error, so this test is mainly here to show that this was also + // investigated. + + // int *ptr = nullptr, a; + int *ptr = nullptr; + *ptr = 5; + }) +} + +// CHECK: <key>name</key><string>PASTE_CODE</string> +// CHECK-NEXT: <key>expansion</key><string>{ int *ptr = nullptr; *ptr = 5; }</string> + +// Example taken from +// https://gcc.gnu.org/onlinedocs/cpp/Macro-Arguments.html#Macro-Arguments. + +#define POTENTIALLY_EMPTY_PARAM(x, y) \ + x; \ + y = nullptr + +void emptyParamTest() { + int *ptr; + + POTENTIALLY_EMPTY_PARAM(,ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>POTENTIALLY_EMPTY_PARAM</string> +// CHECK-NEXT: <key>expansion</key><string>;ptr = nullptr</string> + +#define NESTED_EMPTY_PARAM(a, b) \ + POTENTIALLY_EMPTY_PARAM(a, b); + + +void nestedEmptyParamTest() { + int *ptr; + + NESTED_EMPTY_PARAM(, ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>NESTED_EMPTY_PARAM</string> +// CHECK-NEXT: <key>expansion</key><string>; ptr = nullptr;</string> + +#define CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO(func, param) \ + CALL_FUNCTION(func(param)) + +void lParenRParenInNestedMacro() { + int *ptr; + CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO(setToNull, &ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO</string> +// CHECK-NEXT: <key>expansion</key><string>setToNull( &ptr)</string> + +//===----------------------------------------------------------------------===// +// Tests for variadic macro arguments. +//===----------------------------------------------------------------------===// + +template <typename ...Args> +void variadicFunc(Args ...args); + +#define VARIADIC_SET_TO_NULL(ptr, ...) \ + ptr = nullptr; \ + variadicFunc(__VA_ARGS__) + +void variadicMacroArgumentTest() { + int *ptr; + VARIADIC_SET_TO_NULL(ptr, 1, 5, "haha!"); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>VARIADIC_SET_TO_NULL</string> +// CHECK-NEXT: <key>expansion</key><string>ptr = nullptr; variadicFunc( 1, 5, "haha!")</string> + +void variadicMacroArgumentWithoutAnyArgumentTest() { + int *ptr; + // Not adding a single parameter to ... is silly (and also causes a + // preprocessor warning), but is not an excuse to crash on it. + VARIADIC_SET_TO_NULL(ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>VARIADIC_SET_TO_NULL</string> +// CHECK-NEXT: <key>expansion</key><string>ptr = nullptr; variadicFunc()</string> + +//===----------------------------------------------------------------------===// +// Tests for # and ##. +//===----------------------------------------------------------------------===// + +#define DECLARE_FUNC_AND_SET_TO_NULL(funcName, ptr) \ + void generated_##funcName(); \ + ptr = nullptr; + +void hashHashOperatorTest() { + int *ptr; + DECLARE_FUNC_AND_SET_TO_NULL(whatever, ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>DECLARE_FUNC_AND_SET_TO_NULL</string> +// CHECK-NEXT: <key>expansion</key><string>void generated_whatever(); ptr = nullptr;</string> + +void macroArgContainsHashHashInStringTest() { + int *a; + TO_NULL_AND_PRINT(a, "Will this ## cause a crash?"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>TO_NULL_AND_PRINT</string> +// CHECK-NEXT: <key>expansion</key><string>a = 0; print( "Will this ## cause a crash?")</string> + +#define PRINT_STR(str, ptr) \ + print(#str); \ + ptr = nullptr + +void hashOperatorTest() { + int *ptr; + PRINT_STR(Hello, ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>PRINT_STR</string> +// CHECK-NEXT: <key>expansion</key><string>print("Hello"); ptr = nullptr</string> + +void macroArgContainsHashInStringTest() { + int *a; + TO_NULL_AND_PRINT(a, "Will this # cause a crash?"); + *a = 5; // expected-warning{{Dereference of null pointer}} +} + +// CHECK: <key>name</key><string>TO_NULL_AND_PRINT</string> +// CHECK-NEXT: <key>expansion</key><string>a = 0; print( "Will this # cause a crash?")</string> + +//===----------------------------------------------------------------------===// +// Tests for more complex macro expansions. +// +// We won't cover anything that wasn't covered up to this point, but rather +// show more complex, macros with deeper nesting, more arguments (some unused) +// and so on. +//===----------------------------------------------------------------------===// + +#define IF(Condition) \ + if ( Condition ) + +#define L_BRACE { +#define R_BRACE } +#define LESS < +#define GREATER > +#define EQUALS = +#define SEMICOLON ; +#define NEGATIVE - +#define RETURN return +#define ZERO 0 + +#define EUCLIDEAN_ALGORITHM(A, B) \ + IF(A LESS ZERO) L_BRACE \ + A EQUALS NEGATIVE A SEMICOLON \ + R_BRACE \ + IF(B LESS ZERO) L_BRACE \ + B EQUALS NEGATIVE B SEMICOLON \ + R_BRACE \ + \ + /* This is where a while loop would be, but that seems to be too complex */ \ + /* for the analyzer just yet. Let's just pretend that this algorithm */ \ + /* works. */ \ + \ + RETURN B / (B - B) SEMICOLON + +int getLowestCommonDenominator(int A, int B) { + EUCLIDEAN_ALGORITHM(A, B) // expected-warning{{Division by zero}} +} + +void testVeryComplexAlgorithm() { + int tmp = 8 / (getLowestCommonDenominator(5, 7) - 1); + print(&tmp); +} +// CHECK: <key>name</key><string>EUCLIDEAN_ALGORITHM</string> +// CHECK-NEXT: <key>expansion</key><string>if (A<0 ){A=-A;} if ( B<0 ){ B=- B;}return B / ( B - B);</string> + +#define YET_ANOTHER_SET_TO_NULL(x, y, z) \ + print((void *) x); \ + print((void *) y); \ + z = nullptr; + +#define DO_NOTHING(str) str +#define DO_NOTHING2(str2) DO_NOTHING(str2) + +void test() { + int *ptr; + YET_ANOTHER_SET_TO_NULL(5, DO_NOTHING2("Remember the Vasa"), ptr); + *ptr = 5; // expected-warning{{Dereference of null pointer}} +} +// CHECK: <key>name</key><string>YET_ANOTHER_SET_TO_NULL</string> +// CHECK-NEXT: <key>expansion</key><string>print((void *)5); print((void *)"Remember the Vasa"); ptr = nullptr;</string> diff --git a/test/Analysis/pr22954.c b/test/Analysis/pr22954.c index c58a8aa714..6d5b04417a 100644 --- a/test/Analysis/pr22954.c +++ b/test/Analysis/pr22954.c @@ -585,7 +585,7 @@ int f28(int i, int j, int k, int l) { m28[j].s3[k] = 1; struct ll * l28 = (struct ll*)(&m28[1]); l28->s1[l] = 2; - char input[] = {'a', 'b', 'c', 'd'}; + char input[] = {'a', 'b', 'c', 'd'}; // expected-warning{{Potential leak of memory pointed to by field 's4'}} memcpy(l28->s1, input, 4); clang_analyzer_eval(m28[0].s3[0] == 1); // expected-warning{{UNKNOWN}} clang_analyzer_eval(m28[0].s3[1] == 1); // expected-warning{{UNKNOWN}} diff --git a/test/Analysis/retain-release-cpp-classes.cpp b/test/Analysis/retain-release-cpp-classes.cpp new file mode 100644 index 0000000000..9ed1c0b3b5 --- /dev/null +++ b/test/Analysis/retain-release-cpp-classes.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-output=text -verify %s + +// expected-no-diagnostics + +typedef void *CFTypeRef; +typedef struct _CFURLCacheRef *CFURLCacheRef; + +CFTypeRef CustomCFRetain(CFTypeRef); +void invalidate(void *); +struct S1 { + CFTypeRef s; + CFTypeRef returnFieldAtPlus0() { + return s; + } +}; +struct S2 { + S1 *s1; +}; +void foo(S1 *s1) { + invalidate(s1); + S2 s2; + s2.s1 = s1; + CustomCFRetain(s1->returnFieldAtPlus0()); + + // Definitely no leak end-of-path note here. The retained pointer + // is still accessible through s1 and s2. + ((void) 0); // no-warning + + // FIXME: Ideally we need to warn after this invalidate(). The per-function + // retain-release contract is violated: the programmer should release + // the symbol after it was retained, within the same function. + invalidate(&s2); +} diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m index c9f9798199..2ade99d883 100644 --- a/test/Analysis/retain-release-path-notes.m +++ b/test/Analysis/retain-release-path-notes.m @@ -227,7 +227,7 @@ static int Cond; // expected-note@-1 {{Method returns an instance of MyObj with a +1 retain count}} // expected-note@-2 {{Calling 'initX'}} // expected-note@-3 {{Returning from 'initX'}} - // expected-note@-4 {{Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1}} + // expected-note@-4 {{Object leaked: allocated object of type MyObj * is not referenced later in this execution path and has a retain count of +1}} // initI is inlined because the allocation happens within initY id y = [[MyObj alloc] initY]; // expected-note@-1 {{Calling 'initY'}} @@ -235,7 +235,7 @@ static int Cond; // initZ is not inlined id z = [[MyObj alloc] initZ]; // expected-warning {{Potential leak of an object}} - // expected-note@-1 {{Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1}} + // expected-note@-1 {{Object leaked: object allocated and stored into 'y' is not referenced later in this execution path and has a retain count of +1}} [x release]; [z release]; diff --git a/test/Analysis/retaincountchecker-compoundregion.m b/test/Analysis/retaincountchecker-compoundregion.m index d9967b7fab..ce1f7a9aa1 100644 --- a/test/Analysis/retaincountchecker-compoundregion.m +++ b/test/Analysis/retaincountchecker-compoundregion.m @@ -19,7 +19,7 @@ void foo(CFAllocatorRef allocator) { int width = 0; int height = 0; CFTypeRef* values = (CFTypeRef[]){ - CFNumberCreate(allocator, kCFNumberSInt32Type, &width), //expected-warning-re{{Potential leak of an object{{$}}}} - CFNumberCreate(allocator, kCFNumberSInt32Type, &height), //expected-warning-re{{Potential leak of an object{{$}}}} + CFNumberCreate(allocator, kCFNumberSInt32Type, &width), //expected-warning{{Potential leak of an object of type CFNumberRef}} + CFNumberCreate(allocator, kCFNumberSInt32Type, &height), //expected-warning{{Potential leak of an object of type CFNumberRef}} }; } diff --git a/test/Analysis/self-assign.cpp b/test/Analysis/self-assign.cpp index 8597e9dfe7..ca28c534f1 100644 --- a/test/Analysis/self-assign.cpp +++ b/test/Analysis/self-assign.cpp @@ -32,13 +32,14 @@ StringUsed& StringUsed::operator=(const StringUsed &rhs) { // expected-note{{Ass clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}} expected-warning{{UNKNOWN}} expected-note{{TRUE}} expected-note{{UNKNOWN}} free(str); // expected-note{{Memory is released}} str = strdup(rhs.str); // expected-warning{{Use of memory after it is freed}} expected-note{{Use of memory after it is freed}} +// expected-note@-1{{Memory is allocated}} return *this; } StringUsed& StringUsed::operator=(StringUsed &&rhs) { // expected-note{{Assuming rhs == *this}} expected-note{{Assuming rhs != *this}} clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}} expected-warning{{UNKNOWN}} expected-note{{TRUE}} expected-note{{UNKNOWN}} str = rhs.str; - rhs.str = nullptr; // FIXME: An improved leak checker should warn here + rhs.str = nullptr; // expected-warning{{Potential memory leak}} expected-note{{Potential memory leak}} return *this; } @@ -83,7 +84,7 @@ StringUnused::operator const char*() const { int main() { StringUsed s1 ("test"), s2; - s2 = s1; - s2 = std::move(s1); + s2 = s1; // expected-note{{Calling copy assignment operator for 'StringUsed'}} // expected-note{{Returned allocated memory}} + s2 = std::move(s1); // expected-note{{Calling move assignment operator for 'StringUsed'}} return 0; } diff --git a/test/Analysis/simple-stream-checks.c b/test/Analysis/simple-stream-checks.c index ca1c781575..f37a7039f5 100644 --- a/test/Analysis/simple-stream-checks.c +++ b/test/Analysis/simple-stream-checks.c @@ -89,3 +89,8 @@ void testPassToSystemHeaderFunctionIndirectly() { fs.p = fopen("myfile.txt", "w"); fakeSystemHeaderCall(&fs); // invalidates fs, making fs.p unreachable } // no-warning + +void testOverwrite() { + FILE *fp = fopen("myfile.txt", "w"); + fp = 0; +} // expected-warning {{Opened file is never closed; potential resource leak}} diff --git a/test/Analysis/std-c-library-functions-inlined.c b/test/Analysis/std-c-library-functions-inlined.c index 5277a6efbe..e22df14085 100644 --- a/test/Analysis/std-c-library-functions-inlined.c +++ b/test/Analysis/std-c-library-functions-inlined.c @@ -1,8 +1,8 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=unix.StdCLibraryFunctions -verify %s -// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions -verify %s -// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions -verify %s -// RUN: %clang_analyze_cc1 -triple armv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions -verify %s -// RUN: %clang_analyze_cc1 -triple thumbv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=apiModeling.StdCLibraryFunctions -verify %s +// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=apiModeling.StdCLibraryFunctions -verify %s +// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=apiModeling.StdCLibraryFunctions -verify %s +// RUN: %clang_analyze_cc1 -triple armv7-a15-linux -analyzer-checker=apiModeling.StdCLibraryFunctions -verify %s +// RUN: %clang_analyze_cc1 -triple thumbv7-a15-linux -analyzer-checker=apiModeling.StdCLibraryFunctions -verify %s // This test tests crashes that occur when standard functions are available // for inlining. diff --git a/test/Analysis/std-c-library-functions.c b/test/Analysis/std-c-library-functions.c index 0ccf1a0833..9fb8833175 100644 --- a/test/Analysis/std-c-library-functions.c +++ b/test/Analysis/std-c-library-functions.c @@ -1,8 +1,8 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s -// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s -// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s -// RUN: %clang_analyze_cc1 -triple armv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s -// RUN: %clang_analyze_cc1 -triple thumbv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -triple armv7-a15-linux -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -triple thumbv7-a15-linux -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s void clang_analyzer_eval(int); diff --git a/test/Analysis/std-c-library-functions.cpp b/test/Analysis/std-c-library-functions.cpp index 00b341af5f..87f84fa881 100644 --- a/test/Analysis/std-c-library-functions.cpp +++ b/test/Analysis/std-c-library-functions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s +// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify %s // Test that we don't model functions with broken prototypes. // Because they probably work differently as well. diff --git a/test/Analysis/string.c b/test/Analysis/string.c index a3a6a26906..024e224a2b 100644 --- a/test/Analysis/string.c +++ b/test/Analysis/string.c @@ -1184,11 +1184,14 @@ void strsep_changes_input_string() { } //===----------------------------------------------------------------------=== -// memset() +// memset() / explicit_bzero() / bzero() //===----------------------------------------------------------------------=== void *memset(void *dest, int ch, size_t count); +void bzero(void *dst, size_t count); +void explicit_bzero(void *dest, size_t count); + void *malloc(size_t size); void free(void *); @@ -1383,6 +1386,57 @@ void memset26_upper_UCHAR_MAX() { clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}} } +void bzero1_null() { + char *a = NULL; + + bzero(a, 10); // expected-warning{{Null pointer argument in call to memory clearance function}} +} + +void bzero2_char_array_null() { + char str[] = "abcd"; + clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} + bzero(str, 2); + clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}} +} + +void bzero3_char_ptr_null() { + char *str = "abcd"; + clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}} + bzero(str + 2, 2); + clang_analyzer_eval(strlen(str) == 0); // expected-warning{{FALSE}} +} + +void explicit_bzero1_null() { + char *a = NULL; + + explicit_bzero(a, 10); // expected-warning{{Null pointer argument in call to memory clearance function}} +} + +void explicit_bzero2_clear_mypassword() { + char passwd[7] = "passwd"; + + explicit_bzero(passwd, sizeof(passwd)); // no-warning + + clang_analyzer_eval(strlen(passwd) == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(passwd[0] == '\0'); // expected-warning{{TRUE}} +} + +void explicit_bzero3_out_ofbound() { + char *privkey = (char *)malloc(7); + const char newprivkey[10] = "mysafekey"; + + strcpy(privkey, "random"); + explicit_bzero(privkey, sizeof(newprivkey)); +#ifndef SUPPRESS_OUT_OF_BOUND + // expected-warning@-2 {{Memory clearance function accesses out-of-bound array element}} +#endif + clang_analyzer_eval(privkey[0] == '\0'); +#ifdef SUPPRESS_OUT_OF_BOUND + // expected-warning@-2 {{UNKNOWN}} +#endif + free(privkey); +} + //===----------------------------------------------------------------------=== // FIXMEs //===----------------------------------------------------------------------=== diff --git a/test/Analysis/svalbuilder-rearrange-comparisons.c b/test/Analysis/svalbuilder-rearrange-comparisons.c index daf17b66b2..9e9bf0a9db 100644 --- a/test/Analysis/svalbuilder-rearrange-comparisons.c +++ b/test/Analysis/svalbuilder-rearrange-comparisons.c @@ -979,3 +979,20 @@ int mixed_integer_types(int x, int y) { short a = x - 1U; return a - y; } + +unsigned gu(); +unsigned fu() { + unsigned x = gu(); + // Assert that no overflows occur in this test file. + // Assuming that concrete integers are also within that range. + assert(x <= ((unsigned)UINT_MAX / 4)); + return x; +} + +void unsigned_concrete_int_no_crash() { + unsigned x = fu() + 1U, y = fu() + 1U; + clang_analyzer_denote(x - 1U, "$x"); + clang_analyzer_denote(y - 1U, "$y"); + clang_analyzer_express(y); // expected-warning {{$y}} + clang_analyzer_express(x == y); // expected-warning {{$x + 1U == $y + 1U}} +} diff --git a/test/Analysis/symbol-reaper.c b/test/Analysis/symbol-reaper.c index a47161bea2..ef8ff18a2d 100644 --- a/test/Analysis/symbol-reaper.c +++ b/test/Analysis/symbol-reaper.c @@ -85,8 +85,7 @@ void test_loc_as_integer_element_index_lifetime() { x = (int)&(s->field); ptr = &arr[x]; if (s) {} - // FIXME: Should not warn. The symbol is still alive within the ptr's index. - } while (0); // expected-warning{{SYMBOL DEAD}} + } while (0); } // Test below checks lifetime of SymbolRegionValue in certain conditions. diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp index 4a0a9f194c..7a6b8b0409 100644 --- a/test/Analysis/temporaries.cpp +++ b/test/Analysis/temporaries.cpp @@ -9,7 +9,7 @@ extern bool clang_analyzer_eval(bool); extern bool clang_analyzer_warnIfReached(); void clang_analyzer_checkInlined(bool); -#include "Inputs/system-header-simulator-cxx.h"; +#include "Inputs/system-header-simulator-cxx.h" struct Trivial { Trivial(int x) : value(x) {} diff --git a/test/Analysis/test-separate-retaincount.cpp b/test/Analysis/test-separate-retaincount.cpp new file mode 100644 index 0000000000..be6534f544 --- /dev/null +++ b/test/Analysis/test-separate-retaincount.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-disable-checker osx.cocoa.RetainCount -DNO_CF_OBJECT -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-disable-checker osx.OSObjectRetainCount -DNO_OS_OBJECT -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-config "osx.cocoa.RetainCount:CheckOSObject=false" -DNO_OS_OBJECT -verify %s + +typedef const void * CFTypeRef; +extern CFTypeRef CFRetain(CFTypeRef cf); +extern void CFRelease(CFTypeRef cf); + +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +extern CFTypeRef CFCreate() CF_RETURNS_RETAINED; + +using size_t = decltype(sizeof(int)); + +struct OSObject { + virtual void retain(); + virtual void release(); + + static void * operator new(size_t size); + virtual ~OSObject(){} +}; + +void cf_overrelease() { + CFTypeRef cf = CFCreate(); + CFRelease(cf); + CFRelease(cf); +#ifndef NO_CF_OBJECT + // expected-warning@-2{{Reference-counted object is used after it is released}} +#endif +} + +void osobject_overrelease() { + OSObject *o = new OSObject; + o->release(); + o->release(); +#ifndef NO_OS_OBJECT + // expected-warning@-2{{Reference-counted object is used after it is released}} +#endif +} diff --git a/test/Analysis/trustnonnullchecker_test.m b/test/Analysis/trustnonnullchecker_test.m index e7ff5e1e22..81eac863d5 100644 --- a/test/Analysis/trustnonnullchecker_test.m +++ b/test/Analysis/trustnonnullchecker_test.m @@ -1,3 +1,6 @@ +// Temporarily disabling the test, it failes the "system is over-constrained" +// assertion in *non* optimized builds. +// REQUIRES: rdar44992170 // RUN: %clang_analyze_cc1 -fblocks -analyze -analyzer-checker=core,nullability,apiModeling,debug.ExprInspection -verify %s #include "Inputs/system-header-simulator-for-nullability.h" @@ -170,3 +173,25 @@ NSString *_Nonnull checkAssumeOnMutableDictionaryOtherMethod(NSMutableDictionary if (k) {} return k; // no-warning } + +// Check that we don't crash when the added assumption is enough +// to make the state unfeasible. +@class DummyClass; +@interface DictionarySubclass : NSDictionary { + DummyClass *g; + DictionarySubclass *d; +} +@end +@implementation DictionarySubclass +- (id) objectForKey:(id)e { + if (e) {} + return d; +} +- (void) coder { + for (id e in g) { + id f = [self objectForKey:e]; + if (f) + (void)e; + } +} +@end diff --git a/test/Analysis/undef-call.c b/test/Analysis/undef-call.c index 35c0b685ce..c7aa844d79 100644 --- a/test/Analysis/undef-call.c +++ b/test/Analysis/undef-call.c @@ -1,3 +1,5 @@ +// RUN: rm -rf %T/ctudir +// RUN: mkdir %T/ctudir // RUN: %clang_cc1 -fsyntax-only -analyze -analyzer-checker=debug.ExprInspection -analyzer-config experimental-enable-naive-ctu-analysis=true -analyzer-config ctu-dir=%T/ctudir -verify %s // expected-no-diagnostics diff --git a/test/Analysis/unions.cpp b/test/Analysis/unions.cpp index 0713bc0eb8..618d4c314a 100644 --- a/test/Analysis/unions.cpp +++ b/test/Analysis/unions.cpp @@ -90,9 +90,8 @@ namespace PR17596 { char str[] = "abc"; vv.s = str; - // FIXME: This is a leak of uu.s. uu = vv; - } + } // expected-warning{{leak}} void testIndirectInvalidation() { IntOrString uu; diff --git a/test/Analysis/MisusedMovedObject.cpp b/test/Analysis/use-after-move.cpp index 1c6c8f4cde..18e1b3da6a 100644 --- a/test/Analysis/MisusedMovedObject.cpp +++ b/test/Analysis/use-after-move.cpp @@ -1,38 +1,19 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.MisusedMovedObject -std=c++11 -verify -analyzer-output=text -analyzer-config exploration_strategy=unexplored_first_queue,eagerly-assume=false %s -// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.MisusedMovedObject -std=c++11 -analyzer-config exploration_strategy=dfs,eagerly-assume=false -verify -analyzer-output=text -DDFS=1 %s - -namespace std { - -template <typename> -struct remove_reference; - -template <typename _Tp> -struct remove_reference { typedef _Tp type; }; - -template <typename _Tp> -struct remove_reference<_Tp &> { typedef _Tp type; }; - -template <typename _Tp> -struct remove_reference<_Tp &&> { typedef _Tp type; }; - -template <typename _Tp> -typename remove_reference<_Tp>::type &&move(_Tp &&__t) { - return static_cast<typename remove_reference<_Tp>::type &&>(__t); -} - -template <typename _Tp> -_Tp &&forward(typename remove_reference<_Tp>::type &__t) noexcept { - return static_cast<_Tp &&>(__t); -} - -template <class T> -void swap(T &a, T &b) { - T c(std::move(a)); - a = std::move(b); - b = std::move(c); -} - -} // namespace std +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ +// RUN: -analyzer-config exploration_strategy=unexplored_first_queue +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ +// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1 +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ +// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ +// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\ +// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ +// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\ +// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE + +#include "Inputs/system-header-simulator-cxx.h" class B { public: @@ -67,7 +48,10 @@ public: moveconstruct(std::move(*a)); } A(const A &other) : i(other.i), d(other.d), b(other.b) {} - A(A &&other) : i(other.i), d(other.d), b(std::move(other.b)) { // expected-note {{'b' became 'moved-from' here}} + A(A &&other) : i(other.i), d(other.d), b(std::move(other.b)) { +#ifdef AGGRESSIVE + // expected-note@-2{{Object 'b' is moved}} +#endif } A(A &&other, char *k) { moveconstruct(std::move(other)); @@ -88,9 +72,23 @@ public: void reset(); void destroy(); void clear(); + void resize(std::size_t); bool empty() const; bool isEmpty() const; operator bool() const; + + void testUpdateField() { + A a; + A b = std::move(a); + a.i = 1; + a.foo(); // no-warning + } + void testUpdateFieldDouble() { + A a; + A b = std::move(a); + a.d = 1.0; + a.foo(); // no-warning + } }; int bignum(); @@ -115,18 +113,18 @@ void copyOrMoveCall(A a) { void simpleMoveCtorTest() { { A a; - A b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + A b = std::move(a); // expected-note {{Object 'a' is moved}} + a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} } { A a; - A b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - b = a; // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}} + A b = std::move(a); // expected-note {{Object 'a' is moved}} + b = a; // expected-warning {{Moved-from object 'a' is copied}} expected-note {{Moved-from object 'a' is copied}} } { A a; - A b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - b = std::move(a); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}} + A b = std::move(a); // expected-note {{Object 'a' is moved}} + b = std::move(a); // expected-warning {{Moved-from object 'a' is moved}} expected-note {{Moved-from object 'a' is moved}} } } @@ -134,20 +132,20 @@ void simpleMoveAssignementTest() { { A a; A b; - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + b = std::move(a); // expected-note {{Object 'a' is moved}} + a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} } { A a; A b; - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - A c(a); // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}} + b = std::move(a); // expected-note {{Object 'a' is moved}} + A c(a); // expected-warning {{Moved-from object 'a' is copied}} expected-note {{Moved-from object 'a' is copied}} } { A a; A b; - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - A c(std::move(a)); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}} + b = std::move(a); // expected-note {{Object 'a' is moved}} + A c(std::move(a)); // expected-warning {{Moved-from object 'a' is moved}} expected-note {{Moved-from object 'a' is moved}} } } @@ -156,8 +154,8 @@ void moveInInitListTest() { A a; }; A a; - S s{std::move(a)}; // expected-note {{'a' became 'moved-from' here}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + S s{std::move(a)}; // expected-note {{Object 'a' is moved}} + a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} } // Don't report a bug if the variable was assigned to in the meantime. @@ -205,19 +203,19 @@ void reinitializationTest(int i) { A b; b = std::move(a); a = A(); - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + b = std::move(a); // expected-note {{Object 'a' is moved}} + a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} } // If a path exist where we not reinitialize the variable we report a bug. { A a; A b; - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} + b = std::move(a); // expected-note {{Object 'a' is moved}} if (i < 10) { // expected-note {{Assuming 'i' is >= 10}} expected-note {{Taking false branch}} a = A(); } if (i > 5) { // expected-note {{Taking true branch}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} } } } @@ -303,8 +301,8 @@ void loopTest() { { A a; for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is true. Entering loop body}} expected-note {{Loop condition is true. Entering loop body}} - constCopyOrMoveCall(std::move(a)); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}} - // expected-note@-1 {{'a' became 'moved-from' here}} + constCopyOrMoveCall(std::move(a)); // expected-warning {{Moved-from object 'a' is moved}} expected-note {{Moved-from object 'a' is moved}} + // expected-note@-1 {{Object 'a' is moved}} } } @@ -326,10 +324,10 @@ void loopTest() { void uniqueTest(bool cond) { A a(42, 42.0); A b; - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} + b = std::move(a); // expected-note {{Object 'a' is moved}} if (cond) { // expected-note {{Assuming 'cond' is not equal to 0}} expected-note {{Taking true branch}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} } if (cond) { a.bar(); // no-warning @@ -340,8 +338,8 @@ void uniqueTest(bool cond) { void uniqueTest2() { A a; - A a1 = std::move(a); // expected-note {{'a' became 'moved-from' here}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + A a1 = std::move(a); // expected-note {{Object 'a' is moved}} + a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} A a2 = std::move(a); // no-warning a.foo(); // no-warning @@ -351,12 +349,12 @@ void uniqueTest2() { //even on moved-from objects. void moveSafeFunctionsTest() { A a; - A b = std::move(a); // expected-note {{'a' became 'moved-from' here}} + A b = std::move(a); // expected-note {{Object 'a' is moved}} a.empty(); // no-warning a.isEmpty(); // no-warning (void)a; // no-warning (bool)a; // expected-warning {{expression result unused}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} } void moveStateResetFunctionsTest() { @@ -381,6 +379,13 @@ void moveStateResetFunctionsTest() { a.foo(); // no-warning a.b.foo(); // no-warning } + { + A a; + A b = std::move(a); + a.resize(0); // no-warning + a.foo(); // no-warning + a.b.foo(); // no-warning + } } // Moves or uses that occur as part of template arguments. @@ -420,26 +425,51 @@ class memberVariablesTest { void f() { A b; - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object 'a'}} + b = std::move(a); + a.foo(); +#ifdef AGGRESSIVE + // expected-note@-3{{Object 'a' is moved}} + // expected-warning@-3 {{Method called on moved-from object 'a'}} + // expected-note@-4{{Method called on moved-from object 'a'}} +#endif - b = std::move(static_a); // expected-note {{'static_a' became 'moved-from' here}} - static_a.foo(); // expected-warning {{Method call on a 'moved-from' object 'static_a'}} expected-note {{Method call on a 'moved-from' object 'static_a'}} + b = std::move(static_a); + static_a.foo(); +#ifdef AGGRESSIVE + // expected-note@-3{{Object 'static_a' is moved}} + // expected-warning@-3{{Method called on moved-from object 'static_a'}} + // expected-note@-4{{Method called on moved-from object 'static_a'}} +#endif } }; void PtrAndArrayTest() { A *Ptr = new A(1, 1.5); A Arr[10]; - Arr[2] = std::move(*Ptr); // expected-note {{Became 'moved-from' here}} - (*Ptr).foo(); // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object}} + Arr[2] = std::move(*Ptr); + (*Ptr).foo(); +#ifdef AGGRESSIVE + // expected-note@-3{{Object is moved}} + // expected-warning@-3{{Method called on moved-from object}} + // expected-note@-4{{Method called on moved-from object}} +#endif Ptr = &Arr[1]; - Arr[3] = std::move(Arr[1]); // expected-note {{Became 'moved-from' here}} - Ptr->foo(); // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object}} + Arr[3] = std::move(Arr[1]); + Ptr->foo(); +#ifdef AGGRESSIVE + // expected-note@-3{{Object is moved}} + // expected-warning@-3{{Method called on moved-from object}} + // expected-note@-4{{Method called on moved-from object}} +#endif - Arr[3] = std::move(Arr[2]); // expected-note {{Became 'moved-from' here}} - Arr[2].foo(); // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object}} + Arr[3] = std::move(Arr[2]); + Arr[2].foo(); +#ifdef AGGRESSIVE + // expected-note@-3{{Object is moved}} + // expected-warning@-3{{Method called on moved-from object}} + // expected-note@-4{{Method called on moved-from object}} +#endif Arr[2] = std::move(Arr[3]); // reinitialization Arr[2].foo(); // no-warning @@ -498,9 +528,9 @@ void differentBranchesTest(int i) { A a, b; switch (i) { // expected-note {{Control jumps to 'case 1:'}} case 1: - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} + b = std::move(a); // expected-note {{Object 'a' is moved}} case 2: - a.foo(); // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object 'a'}} + a.foo(); // expected-warning {{Method called on moved-from object}} expected-note {{Method called on moved-from object 'a'}} break; } } @@ -515,13 +545,13 @@ void tempTest() { } void interFunTest1(A &a) { - a.bar(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + a.bar(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} } void interFunTest2() { A a; A b; - b = std::move(a); // expected-note {{'a' became 'moved-from' here}} + b = std::move(a); // expected-note {{Object 'a' is moved}} interFunTest1(a); // expected-note {{Calling 'interFunTest1'}} } @@ -530,31 +560,57 @@ void foobar(int i, A a); void paramEvaluateOrderTest() { A a; - foobar(std::move(a), a.getI()); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} - // expected-note@-1 {{'a' became 'moved-from' here}} + foobar(std::move(a), a.getI()); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + // expected-note@-1 {{Object 'a' is moved}} //FALSE NEGATIVE since parameters evaluate order is undefined foobar(a.getI(), std::move(a)); //no-warning } -void not_known(A &a); -void not_known(A *a); +void not_known_pass_by_ref(A &a); +void not_known_pass_by_const_ref(const A &a); +void not_known_pass_by_rvalue_ref(A &&a); +void not_known_pass_by_ptr(A *a); +void not_known_pass_by_const_ptr(const A *a); void regionAndPointerEscapeTest() { { A a; A b; b = std::move(a); - not_known(a); - a.foo(); //no-warning + not_known_pass_by_ref(a); + a.foo(); // no-warning + } + { + A a; + A b; + b = std::move(a); // expected-note{{Object 'a' is moved}} + not_known_pass_by_const_ref(a); + a.foo(); // expected-warning{{Method called on moved-from object 'a'}} + // expected-note@-1{{Method called on moved-from object 'a'}} + } + { + A a; + A b; + b = std::move(a); + not_known_pass_by_rvalue_ref(std::move(a)); + a.foo(); // no-warning } { A a; A b; b = std::move(a); - not_known(&a); + not_known_pass_by_ptr(&a); a.foo(); // no-warning } + { + A a; + A b; + b = std::move(a); // expected-note{{Object 'a' is moved}} + not_known_pass_by_const_ptr(&a); + a.foo(); // expected-warning{{Method called on moved-from object 'a'}} + // expected-note@-1{{Method called on moved-from object 'a'}} + } } // A declaration statement containing multiple declarations sequences the @@ -566,8 +622,8 @@ void declarationSequenceTest() { } { A a; - A a1 = std::move(a), a2 = a; // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}} - // expected-note@-1 {{'a' became 'moved-from' here}} + A a1 = std::move(a), a2 = a; // expected-warning {{Moved-from object 'a' is copied}} expected-note {{Moved-from object 'a' is copied}} + // expected-note@-1 {{Object 'a' is moved}} } } @@ -593,8 +649,8 @@ void logicalOperatorsSequenceTest() { } { A a; - if (A(std::move(a)).foo() > 0 && a.foo() > 0) { // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} - // expected-note@-1 {{'a' became 'moved-from' here}} expected-note@-1 {{Assuming the condition is true}} expected-note@-1 {{Assuming the condition is false}} + if (A(std::move(a)).foo() > 0 && a.foo() > 0) { // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + // expected-note@-1 {{Object 'a' is moved}} expected-note@-1 {{Assuming the condition is true}} expected-note@-1 {{Assuming the condition is false}} // expected-note@-2 {{Left side of '&&' is false}} expected-note@-2 {{Left side of '&&' is true}} // expected-note@-3 {{Taking false branch}} A().bar(); @@ -610,8 +666,8 @@ void logicalOperatorsSequenceTest() { } { A a; - if (A(std::move(a)).foo() > 0 || a.foo() > 0) { // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} - // expected-note@-1 {{'a' became 'moved-from' here}} expected-note@-1 {{Assuming the condition is false}} expected-note@-1 {{Left side of '||' is false}} + if (A(std::move(a)).foo() > 0 || a.foo() > 0) { // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} + // expected-note@-1 {{Object 'a' is moved}} expected-note@-1 {{Assuming the condition is false}} expected-note@-1 {{Left side of '||' is false}} A().bar(); } } @@ -638,29 +694,43 @@ void ifStmtSequencesDeclAndConditionTest() { } } -class C : public A {}; +struct C : public A { + [[clang::reinitializes]] void reinit(); +}; + void subRegionMoveTest() { { A a; - B b = std::move(a.b); // expected-note {{'b' became 'moved-from' here}} - a.b.foo(); // expected-warning {{Method call on a 'moved-from' object 'b'}} expected-note {{Method call on a 'moved-from' object 'b'}} + B b = std::move(a.b); + a.b.foo(); +#ifdef AGGRESSIVE + // expected-note@-3{{Object 'b' is moved}} + // expected-warning@-3{{Method called on moved-from object 'b'}} + // expected-note@-4 {{Method called on moved-from object 'b'}} +#endif } { A a; - A a1 = std::move(a); // expected-note {{Calling move constructor for 'A'}} expected-note {{Returning from move constructor for 'A'}} - a.b.foo(); // expected-warning {{Method call on a 'moved-from' object 'b'}} expected-note {{Method call on a 'moved-from' object 'b'}} + A a1 = std::move(a); + a.b.foo(); +#ifdef AGGRESSIVE + // expected-note@-3{{Calling move constructor for 'A'}} + // expected-note@-4{{Returning from move constructor for 'A'}} + // expected-warning@-4{{Method called on moved-from object 'b'}} + // expected-note@-5{{Method called on moved-from object 'b'}} +#endif } // Don't report a misuse if any SuperRegion is already reported. { A a; - A a1 = std::move(a); // expected-note {{'a' became 'moved-from' here}} - a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} + A a1 = std::move(a); // expected-note {{Object 'a' is moved}} + a.foo(); // expected-warning {{Method called on moved-from object 'a'}} expected-note {{Method called on moved-from object 'a'}} a.b.foo(); // no-warning } { C c; - C c1 = std::move(c); // expected-note {{'c' became 'moved-from' here}} - c.foo(); // expected-warning {{Method call on a 'moved-from' object 'c'}} expected-note {{Method call on a 'moved-from' object 'c'}} + C c1 = std::move(c); // expected-note {{Object 'c' is moved}} + c.foo(); // expected-warning {{Method called on moved-from object 'c'}} expected-note {{Method called on moved-from object 'c'}} c.b.foo(); // no-warning } } @@ -672,9 +742,88 @@ void resetSuperClass() { C c2 = c; // no-warning } +void resetSuperClass2() { + C c; + C c1 = std::move(c); + c.reinit(); + C c2 = c; // no-warning +} + void reportSuperClass() { C c; - C c1 = std::move(c); // expected-note {{'c' became 'moved-from' here}} - c.foo(); // expected-warning {{Method call on a 'moved-from' object 'c'}} expected-note {{Method call on a 'moved-from' object 'c'}} + C c1 = std::move(c); // expected-note {{Object 'c' is moved}} + c.foo(); // expected-warning {{Method called on moved-from object 'c'}} expected-note {{Method called on moved-from object 'c'}} C c2 = c; // no-warning } + +struct Empty {}; + +Empty inlinedCall() { + // Used to warn because region 'e' failed to be cleaned up because no symbols + // have ever died during the analysis and the checkDeadSymbols callback + // was skipped entirely. + Empty e{}; + return e; // no-warning +} + +void checkInlinedCallZombies() { + while (true) + inlinedCall(); +} + +void checkLoopZombies() { + while (true) { + Empty e{}; + Empty f = std::move(e); // no-warning + } +} + +struct MoveOnlyWithDestructor { + MoveOnlyWithDestructor(); + ~MoveOnlyWithDestructor(); + MoveOnlyWithDestructor(const MoveOnlyWithDestructor &m) = delete; + MoveOnlyWithDestructor(MoveOnlyWithDestructor &&m); +}; + +MoveOnlyWithDestructor foo() { + MoveOnlyWithDestructor m; + return m; +} + +class HasSTLField { + std::vector<int> V; + void testVector() { + // Warn even in non-aggressive mode when it comes to STL, because + // in STL the object is left in "valid but unspecified state" after move. + std::vector<int> W = std::move(V); // expected-note{{Object 'V' of type 'std::vector' is left in a valid but unspecified state after move}} + V.push_back(123); // expected-warning{{Method called on moved-from object 'V'}} + // expected-note@-1{{Method called on moved-from object 'V'}} + } + + std::unique_ptr<int> P; + void testUniquePtr() { + // unique_ptr remains in a well-defined state after move. + std::unique_ptr<int> Q = std::move(P); + P.get(); +#ifdef AGGRESSIVE + // expected-warning@-2{{Method called on moved-from object 'P'}} + // expected-note@-4{{Object 'P' is moved}} + // expected-note@-4{{Method called on moved-from object 'P'}} +#endif + *P += 1; // FIXME: Should warn that the pointer is null. + } +}; + +void localRValueMove(A &&a) { + A b = std::move(a); // expected-note{{Object 'a' is moved}} + a.foo(); // expected-warning{{Method called on moved-from object 'a'}} + // expected-note@-1{{Method called on moved-from object 'a'}} +} + +void localUniquePtr(std::unique_ptr<int> P) { + // Even though unique_ptr is safe to use after move, + // reusing a local variable this way usually indicates a bug. + std::unique_ptr<int> Q = std::move(P); // expected-note{{Object 'P' is moved}} + P.get(); // expected-warning{{Method called on moved-from object 'P'}} + // expected-note@-1{{Method called on moved-from object 'P'}} +} |