From: Artem Dergachev Date: Wed, 15 May 2019 18:41:32 +0000 (+0000) Subject: [analyzer] RetainCount: Fix os_returns_retained_on_zero with weird return types. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fbfd4cc0b44e4acc5036d7f1d1601e0253518d49;p=clang [analyzer] RetainCount: Fix os_returns_retained_on_zero with weird return types. The checker was crashing when it was trying to assume a structure to be null or non-null so that to evaluate the effect of the annotation. Differential Revision: https://reviews.llvm.org/D61958 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360790 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp index 1ccf382953..b7cbcc7d53 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp @@ -537,6 +537,11 @@ updateOutParameters(ProgramStateRef State, const RetainSummary &Summ, ProgramStateRef AssumeZeroReturn = State; if (SplitNecessary) { + if (!CE.getResultType()->isScalarType()) { + // Structures cannot be assumed. This probably deserves + // a compiler warning for invalid annotations. + return {State}; + } if (auto DL = L.getAs()) { AssumeNonZeroReturn = AssumeNonZeroReturn->assume(*DL, true); AssumeZeroReturn = AssumeZeroReturn->assume(*DL, false); diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp index 35d91add1a..98b3e95abf 100644 --- a/test/Analysis/osobject-retain-release.cpp +++ b/test/Analysis/osobject-retain-release.cpp @@ -702,3 +702,16 @@ OSObject *testSuppressionForMethodsEndingWithMatching(IOService *svc, // returning from it at +0. return table; // no-warning } + +namespace weird_result { +struct WeirdResult { + int x, y, z; +}; + +WeirdResult outParamWithWeirdResult(OS_RETURNS_RETAINED_ON_ZERO OSObject **obj); + +WeirdResult testOutParamWithWeirdResult() { + OSObject *obj; + return outParamWithWeirdResult(&obj); // no-warning +} +} // namespace weird_result