Author: labath Date: Fri Jul 26 06:50:42 2013 New Revision: 187196 URL: http://llvm.org/viewvc/llvm-project?rev=187196&view=rev Log: [analyzer] Fix FP warnings when binding a temporary to a local static variable
Summary: When binding a temporary object to a static local variable, the analyzer would complain about a dangling reference even though the temporary's lifetime should be extended past the end of the function. This commit tries to detect these cases and construct them in a global memory region instead of a local one. Reviewers: jordan_rose CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1133 Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp cfe/trunk/test/Analysis/stack-addr-ps.cpp cfe/trunk/test/Analysis/temporaries.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h?rev=187196&r1=187195&r2=187196&view=diff ============================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h Fri Jul 26 06:50:42 2013 @@ -1272,6 +1272,11 @@ public: const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc = NULL); + /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended + /// by static references. This differs from getCXXTempObjectRegion in the + /// super-region used. + const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex); + private: template <typename RegionTy, typename A1> RegionTy* getRegion(const A1 a1); Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=187196&r1=187195&r2=187196&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Jul 26 06:50:42 2013 @@ -209,7 +209,18 @@ ExprEngine::createTemporaryRegionIfNeede // Create a temporary object region for the inner expression (which may have // a more derived type) and bind the value into it. - const TypedValueRegion *TR = MRMgr.getCXXTempObjectRegion(Inner, LC); + const TypedValueRegion *TR = NULL; + if (const MaterializeTemporaryExpr *MT = + dyn_cast<MaterializeTemporaryExpr>(Result)) { + StorageDuration SD = MT->getStorageDuration(); + // If this object is bound to a reference with static storage duration, we + // put it in a different region to prevent "address leakage" warnings. + if (SD == SD_Static || SD == SD_Thread) + TR = MRMgr.getCXXStaticTempObjectRegion(Inner); + } + if (!TR) + TR = MRMgr.getCXXTempObjectRegion(Inner, LC); + SVal Reg = loc::MemRegionVal(TR); if (V.isUnknown()) Modified: cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp?rev=187196&r1=187195&r2=187196&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp Fri Jul 26 06:50:42 2013 @@ -864,6 +864,12 @@ MemRegionManager::getBlockDataRegion(con return getSubRegion<BlockDataRegion>(BC, LC, sReg); } +const CXXTempObjectRegion * +MemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) { + return getSubRegion<CXXTempObjectRegion>( + Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, NULL)); +} + const CompoundLiteralRegion* MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL, const LocationContext *LC) { Modified: cfe/trunk/test/Analysis/stack-addr-ps.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/stack-addr-ps.cpp?rev=187196&r1=187195&r2=187196&view=diff ============================================================================== --- cfe/trunk/test/Analysis/stack-addr-ps.cpp (original) +++ cfe/trunk/test/Analysis/stack-addr-ps.cpp Fri Jul 26 06:50:42 2013 @@ -20,6 +20,10 @@ const int& g3() { return s3; // expected-warning{{Address of stack memory associated with local variable 's1' returned}} expected-warning {{reference to stack memory associated with local variable 's1' returned}} } +void g4() { + static const int &x = 3; // no warning +} + int get_value(); const int &get_reference1() { return get_value(); } // expected-warning{{Address of stack memory associated with temporary object of type 'int' returned}} expected-warning {{returning reference to local temporary}} Modified: cfe/trunk/test/Analysis/temporaries.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temporaries.cpp?rev=187196&r1=187195&r2=187196&view=diff ============================================================================== --- cfe/trunk/test/Analysis/temporaries.cpp (original) +++ cfe/trunk/test/Analysis/temporaries.cpp Fri Jul 26 06:50:42 2013 @@ -141,3 +141,19 @@ namespace destructors { } } } + +void testStaticMaterializeTemporaryExpr() { + static const Trivial &ref = getTrivial(); + clang_analyzer_eval(ref.value == 42); // expected-warning{{TRUE}} + + static const Trivial &directRef = Trivial(42); + clang_analyzer_eval(directRef.value == 42); // expected-warning{{TRUE}} + +#if __cplusplus >= 201103L + thread_local static const Trivial &threadRef = getTrivial(); + clang_analyzer_eval(threadRef.value == 42); // expected-warning{{TRUE}} + + thread_local static const Trivial &threadDirectRef = Trivial(42); + clang_analyzer_eval(threadDirectRef.value == 42); // expected-warning{{TRUE}} +#endif +} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
