92 lines · cpp
1// RUN: %clang_analyze_cc1 \2// RUN: -analyzer-checker=core,apiModeling.llvm.ReturnValue \3// RUN: -analyzer-output=text -verify %s4 5struct Foo { int Field; };6bool problem();7void doSomething();8 9// Test the normal case when the implementation of MCAsmParser::Error() (one of10// the methods modeled by this checker) is opaque.11namespace test_normal {12struct MCAsmParser {13 static bool Error();14};15 16bool parseFoo(Foo &F) {17 if (problem()) {18 // expected-note@-1 {{Assuming the condition is false}}19 // expected-note@-2 {{Taking false branch}}20 return MCAsmParser::Error();21 }22 23 F.Field = 0;24 // expected-note@-1 {{The value 0 is assigned to 'F.Field'}}25 return false;26}27 28bool parseFile() {29 Foo F;30 if (parseFoo(F)) {31 // expected-note@-1 {{Calling 'parseFoo'}}32 // expected-note@-2 {{Returning from 'parseFoo'}}33 // expected-note@-3 {{Taking false branch}}34 return true;35 }36 37 // The following expression would produce the false positive report38 // "The left operand of '==' is a garbage value"39 // without the modeling done by apiModeling.llvm.ReturnValue:40 if (F.Field == 0) {41 // expected-note@-1 {{Field 'Field' is equal to 0}}42 // expected-note@-2 {{Taking true branch}}43 doSomething();44 }45 46 // Trigger a zero division to get path notes:47 (void)(1 / F.Field);48 // expected-warning@-1 {{Division by zero}}49 // expected-note@-2 {{Division by zero}}50 return false;51}52} // namespace test_normal53 54 55// Sanity check for the highly unlikely case where the implementation of the56// method breaks the convention.57namespace test_break {58struct MCAsmParser {59 static bool Error() {60 return false;61 }62};63 64bool parseFoo(Foo &F) {65 if (problem()) {66 // expected-note@-1 {{Assuming the condition is false}}67 // expected-note@-2 {{Taking false branch}}68 return !MCAsmParser::Error();69 }70 71 F.Field = 0;72 // expected-note@-1 {{The value 0 is assigned to 'F.Field'}}73 return MCAsmParser::Error();74 // expected-note@-1 {{'MCAsmParser::Error' returned false, breaking the convention that it always returns true}}75}76 77bool parseFile() {78 Foo F;79 if (parseFoo(F)) {80 // expected-note@-1 {{Calling 'parseFoo'}}81 // expected-note@-2 {{Returning from 'parseFoo'}}82 // expected-note@-3 {{Taking false branch}}83 return true;84 }85 86 (void)(1 / F.Field);87 // expected-warning@-1 {{Division by zero}}88 // expected-note@-2 {{Division by zero}}89 return false;90}91} // namespace test_break92