r176042 - [analyzer] Handle reference parameters with default values.

Jordan Rose jordan_rose at apple.com
Mon Feb 25 11:45:34 PST 2013


Author: jrose
Date: Mon Feb 25 13:45:34 2013
New Revision: 176042

URL: http://llvm.org/viewvc/llvm-project?rev=176042&view=rev
Log:
[analyzer] Handle reference parameters with default values.

r175026 added support for default values, but didn't take reference
parameters into account, which expect the default argument to be an
lvalue. Use createTemporaryRegionIfNeeded if we can evaluate the default
expr as an rvalue but the expected result is an lvalue.

Fixes the most recent report of PR12915. The original report predates
default argument support, so that can't be it.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
    cfe/trunk/test/Analysis/global_region_invalidation.mm
    cfe/trunk/test/Analysis/inline.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=176042&r1=176041&r2=176042&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Feb 25 13:45:34 2013
@@ -685,7 +685,8 @@ void ExprEngine::Visit(const Stmt *S, Ex
       StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
 
       const LocationContext *LCtx = Pred->getLocationContext();
-      const Expr *ArgE = cast<CXXDefaultArgExpr>(S)->getExpr();
+      const CXXDefaultArgExpr *DefaultE = cast<CXXDefaultArgExpr>(S);
+      const Expr *ArgE = DefaultE->getExpr();
 
       // Avoid creating and destroying a lot of APSInts.
       SVal V;
@@ -700,7 +701,9 @@ void ExprEngine::Visit(const Stmt *S, Ex
         else
           V = State->getSVal(ArgE, LCtx);
 
-        State = State->BindExpr(S, LCtx, V);
+        State = State->BindExpr(DefaultE, LCtx, V);
+        if (DefaultE->isGLValue())
+          State = createTemporaryRegionIfNeeded(State, LCtx, DefaultE);
         Bldr2.generateNode(S, *I, State);
       }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=176042&r1=176041&r2=176042&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Mon Feb 25 13:45:34 2013
@@ -1578,7 +1578,7 @@ static Optional<SVal> getConstValue(SVal
     return None;
 
   llvm::APSInt Result;
-  if (Init->EvaluateAsInt(Result, Ctx))
+  if (!Init->isGLValue() && Init->EvaluateAsInt(Result, Ctx))
     return SVB.makeIntVal(Result);
 
   if (Init->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull))

Modified: cfe/trunk/test/Analysis/global_region_invalidation.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/global_region_invalidation.mm?rev=176042&r1=176041&r2=176042&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/global_region_invalidation.mm (original)
+++ cfe/trunk/test/Analysis/global_region_invalidation.mm Mon Feb 25 13:45:34 2013
@@ -9,4 +9,11 @@ id foo(int x) {
   static id p = foo(1); 
     clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
   return p;
-}
\ No newline at end of file
+}
+
+const int &globalInt = 42;
+
+void testGlobal() {
+  // FIXME: Should be TRUE, but should at least not crash.
+  clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
+}

Modified: cfe/trunk/test/Analysis/inline.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.cpp?rev=176042&r1=176041&r2=176042&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline.cpp (original)
+++ cfe/trunk/test/Analysis/inline.cpp Mon Feb 25 13:45:34 2013
@@ -260,6 +260,15 @@ namespace DefaultArgs {
     clang_analyzer_eval(complicatedExprUser(1) == 1); // expected-warning{{TRUE}}
     clang_analyzer_eval(complicatedExprUser() == 84); // expected-warning{{TRUE}}
   }
+
+  int defaultReference(const int &input = 42) {
+    return input;
+  }
+
+  void testReference() {
+    clang_analyzer_eval(defaultReference(1) == 1); // expected-warning{{TRUE}}
+    clang_analyzer_eval(defaultReference() == 42); // expected-warning{{TRUE}}
+  }
 }
 
 namespace OperatorNew {





More information about the cfe-commits mailing list