]> granicus.if.org Git - clang/commitdiff
Consumed analysis: fix assert failure.
authorDeLesley Hutchins <delesley@google.com>
Fri, 18 Oct 2013 23:11:49 +0000 (23:11 +0000)
committerDeLesley Hutchins <delesley@google.com>
Fri, 18 Oct 2013 23:11:49 +0000 (23:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193010 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/Consumed.cpp
test/SemaCXX/warn-consumed-analysis.cpp

index 8358b6b4e1c7d5714783c00384c32b499726d804..ed806ce67118d0d1384c9a8cbd50c375a82cf56e 100644 (file)
@@ -414,6 +414,15 @@ class ConsumedStmtVisitor : public ConstStmtVisitor<ConsumedStmtVisitor> {
   void propagateReturnType(const Stmt *Call, const FunctionDecl *Fun,
                            QualType ReturnType);
   
+  inline ConsumedState getPInfoState(const PropagationInfo& PInfo) {
+    if (PInfo.isVar())
+      return StateMap->getState(PInfo.getVar());
+    else if (PInfo.isState())
+      return PInfo.getState();
+    else
+      return CS_None;
+  }
+
 public:
   void checkCallability(const PropagationInfo &PInfo,
                         const FunctionDecl *FunDecl,
@@ -927,15 +936,18 @@ void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) {
 void ConsumedStmtVisitor::VisitVarDecl(const VarDecl *Var) {
   if (isConsumableType(Var->getType())) {
     if (Var->hasInit()) {
-      PropagationInfo PInfo =
-        PropagationMap.find(Var->getInit())->second;
-      
-      StateMap->setState(Var, PInfo.isVar() ?
-        StateMap->getState(PInfo.getVar()) : PInfo.getState());
-      
-    } else {
-      StateMap->setState(Var, consumed::CS_Unknown);
+      MapType::iterator VIT = PropagationMap.find(Var->getInit());
+      if (VIT != PropagationMap.end()) {
+        PropagationInfo PInfo = VIT->second;
+        ConsumedState St = getPInfoState(PInfo);
+        if (St != consumed::CS_None) {
+          StateMap->setState(Var, St);
+          return;
+        }
+      }
     }
+    // Otherwise
+    StateMap->setState(Var, consumed::CS_Unknown);
   }
 }
 }} // end clang::consumed::ConsumedStmtVisitor
index 14deae58f946c3223aeef25a42465a3a72b17ce1..cf94431ac2605128eedb1f002dc79073aa73428b 100644 (file)
@@ -642,3 +642,46 @@ void read(bool sf) {
 
 } // end namespace ContinueICETest
 
+
+namespace InitializerAssertionFailTest {
+
+class CONSUMABLE(unconsumed) Status {
+  int code;
+
+public:
+  Status() RETURN_TYPESTATE(consumed);
+  Status(int c) RETURN_TYPESTATE(unconsumed);
+
+  Status(const Status &other);
+  //Status(Status &&other);
+
+  Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
+  //Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
+
+  bool check()  const SET_TYPESTATE(consumed);
+  void ignore() const SET_TYPESTATE(consumed);
+  // Status& markAsChecked() { return *this; }
+
+  void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
+
+  ~Status() CALLABLE_WHEN("unknown", "consumed");
+};
+
+
+bool   cond();
+Status doSomething();
+void   handleStatus(const Status& s);
+void   handleStatusPtr(const Status* s);
+
+int a;
+
+
+void test() {
+  if (cond()) {
+    Status s = doSomething();
+    return;                     // Warning: Store it, but don't check.
+  }
+}
+
+} // end namespace InitializerAssertionFailTest
+