1 // RUN: %clang_analyze_cc1 \ 2 // RUN: -analyzer-checker=core,apiModeling.llvm.ReturnValue \ 3 // RUN: -analyzer-output=text -verify=class %s 4 5 struct Foo { int Field; }; 6 bool problem(); 7 void doSomething(); 8 9 // We predefined the return value of 'MCAsmParser::Error' as true and we cannot 10 // take the false-branches which leads to a "garbage value" false positive. 11 namespace test_classes { 12 struct MCAsmParser { 13 static bool Error(); 14 }; 15 16 bool parseFoo(Foo &F) { 17 if (problem()) { 18 // class-note@-1 {{Assuming the condition is false}} 19 // class-note@-2 {{Taking false branch}} 20 return MCAsmParser::Error(); 21 } 22 23 F.Field = 0; 24 // class-note@-1 {{The value 0 is assigned to 'F.Field'}} 25 return !MCAsmParser::Error(); 26 // class-note@-1 {{'MCAsmParser::Error' returns true}} 27 } 28 29 bool parseFile() { 30 Foo F; 31 if (parseFoo(F)) { 32 // class-note@-1 {{Calling 'parseFoo'}} 33 // class-note@-2 {{Returning from 'parseFoo'}} 34 // class-note@-3 {{Taking false branch}} 35 return true; 36 } 37 38 if (F.Field == 0) { 39 // class-note@-1 {{Field 'Field' is equal to 0}} 40 // class-note@-2 {{Taking true branch}} 41 42 // no-warning: "The left operand of '==' is a garbage value" was here. 43 doSomething(); 44 } 45 46 (void)(1 / F.Field); 47 // class-warning@-1 {{Division by zero}} 48 // class-note@-2 {{Division by zero}} 49 return false; 50 } 51 } // namespace test_classes 52 53 54 // We predefined 'MCAsmParser::Error' as returning true, but now it returns 55 // false, which breaks our invariant. Test the notes. 56 namespace test_break { 57 struct MCAsmParser { 58 static bool Error() { 59 return false; // class-note {{'MCAsmParser::Error' returns false}} 60 } 61 }; 62 63 bool parseFoo(Foo &F) { 64 if (problem()) { 65 // class-note@-1 {{Assuming the condition is false}} 66 // class-note@-2 {{Taking false branch}} 67 return !MCAsmParser::Error(); 68 } 69 70 F.Field = 0; 71 // class-note@-1 {{The value 0 is assigned to 'F.Field'}} 72 return MCAsmParser::Error(); 73 // class-note@-1 {{Calling 'MCAsmParser::Error'}} 74 // class-note@-2 {{Returning from 'MCAsmParser::Error'}} 75 } 76 77 bool parseFile() { 78 Foo F; 79 if (parseFoo(F)) { 80 // class-note@-1 {{Calling 'parseFoo'}} 81 // class-note@-2 {{Returning from 'parseFoo'}} 82 // class-note@-3 {{Taking false branch}} 83 return true; 84 } 85 86 (void)(1 / F.Field); 87 // class-warning@-1 {{Division by zero}} 88 // class-note@-2 {{Division by zero}} 89 return false; 90 } 91 } // namespace test_classes 92