r192991 - Consumed analysis: All the return_typestate parameter to be attached to the

DeLesley Hutchins delesley at google.com
Fri Oct 18 11:36:21 PDT 2013


Author: delesley
Date: Fri Oct 18 13:36:21 2013
New Revision: 192991

URL: http://llvm.org/viewvc/llvm-project?rev=192991&view=rev
Log:
Consumed analysis: All the return_typestate parameter to be attached to the
default constructor.  Patch by chris.wailes at gmail.com, reviewed by delesley.

Modified:
    cfe/trunk/lib/Analysis/Consumed.cpp
    cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp

Modified: cfe/trunk/lib/Analysis/Consumed.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Consumed.cpp?rev=192991&r1=192990&r2=192991&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Fri Oct 18 13:36:21 2013
@@ -660,38 +660,46 @@ void ConsumedStmtVisitor::VisitCXXConstr
   ASTContext &CurrContext = AC.getASTContext();
   QualType ThisType = Constructor->getThisType(CurrContext)->getPointeeType();
   
-  if (isConsumableType(ThisType)) {
-    if (Constructor->isDefaultConstructor()) {
+  if (!isConsumableType(ThisType))
+    return;
+  
+  // FIXME: What should happen if someone annotates the move constructor?
+  if (Constructor->hasAttr<ReturnTypestateAttr>()) {
+    ReturnTypestateAttr *RTAttr = Constructor->getAttr<ReturnTypestateAttr>();
+    ConsumedState RetState = mapReturnTypestateAttrState(RTAttr);
+    PropagationMap.insert(PairType(Call, PropagationInfo(RetState, ThisType)));
+    
+  } else if (Constructor->isDefaultConstructor()) {
+    
+    PropagationMap.insert(PairType(Call,
+      PropagationInfo(consumed::CS_Consumed, ThisType)));
+    
+  } else if (Constructor->isMoveConstructor()) {
+    
+    PropagationInfo PInfo =
+      PropagationMap.find(Call->getArg(0))->second;
+    
+    if (PInfo.isVar()) {
+      const VarDecl* Var = PInfo.getVar();
       
       PropagationMap.insert(PairType(Call,
-        PropagationInfo(consumed::CS_Consumed, ThisType)));
+        PropagationInfo(StateMap->getState(Var), ThisType)));
       
-    } else if (Constructor->isMoveConstructor()) {
-      
-      PropagationInfo PInfo =
-        PropagationMap.find(Call->getArg(0))->second;
-      
-      if (PInfo.isVar()) {
-        const VarDecl* Var = PInfo.getVar();
-        
-        PropagationMap.insert(PairType(Call,
-          PropagationInfo(StateMap->getState(Var), ThisType)));
-        
-        StateMap->setState(Var, consumed::CS_Consumed);
-        
-      } else {
-        PropagationMap.insert(PairType(Call, PInfo));
-      }
-        
-    } else if (Constructor->isCopyConstructor()) {
-      MapType::iterator Entry = PropagationMap.find(Call->getArg(0));
-    
-      if (Entry != PropagationMap.end())
-        PropagationMap.insert(PairType(Call, Entry->second));
+      StateMap->setState(Var, consumed::CS_Consumed);
       
     } else {
-      propagateReturnType(Call, Constructor, ThisType);
+      PropagationMap.insert(PairType(Call, PInfo));
     }
+      
+  } else if (Constructor->isCopyConstructor()) {
+    MapType::iterator Entry = PropagationMap.find(Call->getArg(0));
+  
+    if (Entry != PropagationMap.end())
+      PropagationMap.insert(PairType(Call, Entry->second));
+    
+  } else {
+    ConsumedState RetState = mapConsumableAttrState(ThisType);
+    PropagationMap.insert(PairType(Call, PropagationInfo(RetState, ThisType)));
   }
 }
 

Modified: cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp?rev=192991&r1=192990&r2=192991&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp Fri Oct 18 13:36:21 2013
@@ -51,9 +51,10 @@ public:
 
 class CONSUMABLE(unconsumed) DestructorTester {
 public:
+  DestructorTester() RETURN_TYPESTATE(unconsumed);
   DestructorTester(int);
   
-  void operator*();
+  void operator*() CALLABLE_WHEN("unconsumed");
   
   ~DestructorTester() CALLABLE_WHEN("consumed");
 };
@@ -101,9 +102,14 @@ void testDestruction() {
   *D0;
   *D1;
   
+  DestructorTester D2;
+  *D2;
+  
   D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
   
-  return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
+  return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \
+             expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} \
+             expected-warning {{invalid invocation of method '~DestructorTester' on object 'D2' while it is in the 'unconsumed' state}}
 }
 
 void testTempValue() {





More information about the cfe-commits mailing list