| // RUN: %clang_analyze_cc1 \ |
| // RUN: -analyzer-checker=core,apiModeling.llvm.ReturnValue \ |
| // RUN: -analyzer-output=text -verify %s |
| |
| struct Foo { int Field; }; |
| bool problem(); |
| void doSomething(); |
| |
| // Test the normal case when the implementation of MCAsmParser::Error() (one of |
| // the methods modeled by this checker) is opaque. |
| namespace test_normal { |
| struct MCAsmParser { |
| static bool Error(); |
| }; |
| |
| bool parseFoo(Foo &F) { |
| if (problem()) { |
| // expected-note@-1 {{Assuming the condition is false}} |
| // expected-note@-2 {{Taking false branch}} |
| return MCAsmParser::Error(); |
| } |
| |
| F.Field = 0; |
| // expected-note@-1 {{The value 0 is assigned to 'F.Field'}} |
| return false; |
| } |
| |
| bool parseFile() { |
| Foo F; |
| if (parseFoo(F)) { |
| // expected-note@-1 {{Calling 'parseFoo'}} |
| // expected-note@-2 {{Returning from 'parseFoo'}} |
| // expected-note@-3 {{Taking false branch}} |
| return true; |
| } |
| |
| // The following expression would produce the false positive report |
| // "The left operand of '==' is a garbage value" |
| // without the modeling done by apiModeling.llvm.ReturnValue: |
| if (F.Field == 0) { |
| // expected-note@-1 {{Field 'Field' is equal to 0}} |
| // expected-note@-2 {{Taking true branch}} |
| doSomething(); |
| } |
| |
| // Trigger a zero division to get path notes: |
| (void)(1 / F.Field); |
| // expected-warning@-1 {{Division by zero}} |
| // expected-note@-2 {{Division by zero}} |
| return false; |
| } |
| } // namespace test_normal |
| |
| |
| // Sanity check for the highly unlikely case where the implementation of the |
| // method breaks the convention. |
| namespace test_break { |
| struct MCAsmParser { |
| static bool Error() { |
| return false; |
| } |
| }; |
| |
| bool parseFoo(Foo &F) { |
| if (problem()) { |
| // expected-note@-1 {{Assuming the condition is false}} |
| // expected-note@-2 {{Taking false branch}} |
| return !MCAsmParser::Error(); |
| } |
| |
| F.Field = 0; |
| // expected-note@-1 {{The value 0 is assigned to 'F.Field'}} |
| return MCAsmParser::Error(); |
| // expected-note@-1 {{'MCAsmParser::Error' returned false, breaking the convention that it always returns true}} |
| } |
| |
| bool parseFile() { |
| Foo F; |
| if (parseFoo(F)) { |
| // expected-note@-1 {{Calling 'parseFoo'}} |
| // expected-note@-2 {{Returning from 'parseFoo'}} |
| // expected-note@-3 {{Taking false branch}} |
| return true; |
| } |
| |
| (void)(1 / F.Field); |
| // expected-warning@-1 {{Division by zero}} |
| // expected-note@-2 {{Division by zero}} |
| return false; |
| } |
| } // namespace test_break |