diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 3c1c412af536..5b88a4549549 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -137,6 +137,8 @@ static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy, return V; // If the types already match, don't do any unnecessary work. + ExpectedTy = ExpectedTy.getCanonicalType(); + ActualTy = ActualTy.getCanonicalType(); if (ExpectedTy == ActualTy) return V; diff --git a/clang/test/Analysis/retain-release-inline.m b/clang/test/Analysis/retain-release-inline.m index a06b3531fea7..6ff9e9a55264 100644 --- a/clang/test/Analysis/retain-release-inline.m +++ b/clang/test/Analysis/retain-release-inline.m @@ -343,5 +343,21 @@ void test_test_return_inline_2(char *bytes) { CFRelease(str); } +extern CFStringRef getString(void); +CFStringRef testCovariantReturnType(void) __attribute__((cf_returns_retained)); +void usetestCovariantReturnType() { + CFStringRef S = ((void*)0); + S = testCovariantReturnType(); + if (S) + CFRelease(S); +} +CFStringRef testCovariantReturnType() { + CFStringRef Str = ((void*)0); + Str = getString(); + if (Str) { + CFRetain(Str); + } + return Str; +}