[PATCH] [analyzer] Fix FP warnings when binding a temporary to a local static variable
Pavel Labath
labath at google.com
Tue Jul 16 05:01:21 PDT 2013
================
Comment at: lib/StaticAnalyzer/Core/ExprEngine.cpp:214
@@ +213,3 @@
+ dyn_cast<MaterializeTemporaryExpr>(Result)) {
+ if (MT->getStorageDuration() == SD_Static)
+ TR = MRMgr.getCXXExtendedTempObjectRegion(Inner);
----------------
Jordan Rose wrote:
> What about SD_Thread? The analyzer currently assumes non-parallel execution, so SD_Thread could behave like SD_Static for now.
SD_Thread added.
================
Comment at: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp:150-163
@@ -149,2 +149,16 @@
}
+ // Or a constructor for a temporary variable bound to a static
+ // reference?
+ } else if (isa<ImplicitCastExpr>(StmtElem->getStmt()) &&
+ currStmtIdx + 2 < B->size()) {
+ CFGElement NNext = (*B)[currStmtIdx+2];
+ if (Optional<CFGStmt> NStmtElem = NNext.getAs<CFGStmt>()) {
+ if (const MaterializeTemporaryExpr *MT =
+ dyn_cast<MaterializeTemporaryExpr>(NStmtElem->getStmt())) {
+ if (MT->getStorageDuration() == SD_Static) {
+ MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
+ Target = MRMgr.getCXXExtendedTempObjectRegion(CE);
+ }
+ }
+ }
}
----------------
Jordan Rose wrote:
> The `currStmtIdx + 2` seems really brittle. We use that for local variables because we synthesize DeclStmts that don't appear in the parent map, and because at one point I was concerned about the overhead of ParentMap lookup. In this case, though, there may be an arbitrary number of layers between the CXXTemporaryObjectExpr and the enclosing MaterializeTemporaryExpr.
>
> For now, it might be easier to just tweak CreateCXXTemporaryObject to not reuse the temp region if the storage duration is different.
I have completely removed this fragment and just kept the code in CreateCXXTemporaryObject. I can't say I know what is going on here (I still find the analyzer to be a pretty big black box), but it seems to work just fine without this. I have added some tests and they should prove that the reference actually ends up pointing to the right object.
================
Comment at: lib/StaticAnalyzer/Core/MemRegion.cpp:868
@@ +867,3 @@
+const CXXTempObjectRegion *
+MemRegionManager::getCXXExtendedTempObjectRegion(Expr const *Ex) {
+ return getSubRegion<CXXTempObjectRegion>(
----------------
Jordan Rose wrote:
> Not sure about this name. How about `getStaticTempObjectRegion`?
>
> Also, `const Expr *Ex`, please. I don't know why the other one has it reversed. (I know they're both correct, but const-first is by far the convention in Clang.)
Done. Renamed.
================
Comment at: test/Analysis/stack-addr-ps.cpp:23-25
@@ -22,1 +22,5 @@
+void g4() {
+ static const int &x = 3; // no warning
+}
+
----------------
Jordan Rose wrote:
> Please add several more tests, and actually test that we inline the constructor and store the right values into the temporary reference. In this case there isn't a constructor at all, so you're only testing one of your modifications.
Tests added to temporaries.cpp.
http://llvm-reviews.chandlerc.com/D1133
More information about the cfe-commits
mailing list