r199436 - Consumed analysis: bugfix for operator calls. Also fixes some formatting

DeLesley Hutchins delesley at google.com
Thu Jan 16 15:07:16 PST 2014


Author: delesley
Date: Thu Jan 16 17:07:16 2014
New Revision: 199436

URL: http://llvm.org/viewvc/llvm-project?rev=199436&view=rev
Log:
Consumed analysis: bugfix for operator calls.  Also fixes some formatting
issues, a few testcases, and kills fish.

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=199436&r1=199435&r2=199436&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Thu Jan 16 17:07:16 2014
@@ -183,11 +183,8 @@ static bool isKnownState(ConsumedState S
   llvm_unreachable("invalid enum");
 }
 
-static bool isRValueRefish(QualType ParamType) {
-  return ParamType->isRValueReferenceType(); /* ||
-        (ParamType->isLValueReferenceType() &&
-         !cast<LValueReferenceType>(
-           ParamType.getCanonicalType())->isSpelledAsLValue()); */
+static bool isRValueRef(QualType ParamType) {
+  return ParamType->isRValueReferenceType();
 }
 
 static bool isTestingFunction(const FunctionDecl *FunDecl) {
@@ -607,8 +604,8 @@ void ConsumedStmtVisitor::checkCallabili
 bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
                                      const FunctionDecl *FunD) {
   unsigned Offset = 0;
-  if (isa<CXXMethodDecl>(FunD))
-    Offset = 1;  // First argument to call is 'this' parameter
+  if (isa<CXXOperatorCallExpr>(Call) && isa<CXXMethodDecl>(FunD))
+    Offset = 1;  // first argument is 'this'
 
   // check explicit parameters
   for (unsigned Index = Offset; Index < Call->getNumArgs(); ++Index) {
@@ -640,15 +637,14 @@ bool ConsumedStmtVisitor::handleCall(con
       continue;
 
     // Adjust state on the caller side.
-    if (isRValueRefish(ParamType))
+    if (isRValueRef(ParamType))
       setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
     else if (ReturnTypestateAttr *RT = Param->getAttr<ReturnTypestateAttr>())
       setStateForVarOrTmp(StateMap, PInfo, mapReturnTypestateAttrState(RT));
-    else if (isPointerOrRef(ParamType)) {
-      if (!ParamType->getPointeeType().isConstQualified() ||
-          isSetOnReadPtrType(ParamType))
-        setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Unknown);
-    }
+    else if (isPointerOrRef(ParamType) &&
+             (!ParamType->getPointeeType().isConstQualified() ||
+              isSetOnReadPtrType(ParamType)))
+      setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Unknown);
   }
 
   if (!ObjArg)
@@ -885,11 +881,11 @@ void ConsumedStmtVisitor::VisitParmVarDe
     ParamState = mapParamTypestateAttrState(PTA);    
   else if (isConsumableType(ParamType))
     ParamState = mapConsumableAttrState(ParamType);    
-  else if (isRValueRefish(ParamType) &&
-             isConsumableType(ParamType->getPointeeType()))    
+  else if (isRValueRef(ParamType) &&
+           isConsumableType(ParamType->getPointeeType()))
     ParamState = mapConsumableAttrState(ParamType->getPointeeType());    
   else if (ParamType->isReferenceType() &&
-             isConsumableType(ParamType->getPointeeType()))
+           isConsumableType(ParamType->getPointeeType()))
     ParamState = consumed::CS_Unknown;
   
   if (ParamState != CS_None)

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=199436&r1=199435&r2=199436&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp Thu Jan 16 17:07:16 2014
@@ -51,7 +51,7 @@ public:
 
 class CONSUMABLE(unconsumed) DestructorTester {
 public:
-  DestructorTester() RETURN_TYPESTATE(unconsumed);
+  DestructorTester();
   DestructorTester(int);
   
   void operator*() CALLABLE_WHEN("unconsumed");
@@ -82,11 +82,21 @@ ConsumableClass<int> returnsUnknown() RE
 void testInitialization() {
   ConsumableClass<int> var0;
   ConsumableClass<int> var1 = ConsumableClass<int>();
-  
-  var0 = ConsumableClass<int>();
-  
+  ConsumableClass<int> var2(42);
+  ConsumableClass<int> var3(var2);  // copy constructor
+  ConsumableClass<int> var4(var0);  // copy consumed value
+
   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
   *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+  *var2;
+  *var3;
+  *var4; // expected-warning {{invalid invocation of method 'operator*' on object 'var4' while it is in the 'consumed' state}}
+
+  var0 = ConsumableClass<int>(42);
+  *var0;
+  
+  var0 = var1;
+  *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
   
   if (var0.isValid()) {
     *var0;
@@ -98,19 +108,16 @@ void testInitialization() {
 }
 
 void testDestruction() {
-  DestructorTester D0(42), D1(42);
+  DestructorTester D0(42), D1(42), D2;
   
   *D0;
   *D1;
-  
-  DestructorTester D2;
-  *D2;
+  *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}}
   
   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}} \
-             expected-warning {{invalid invocation of method '~DestructorTester' on object 'D2' while it is in the 'unconsumed' state}}
+             expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
 }
 
 void testTempValue() {
@@ -427,6 +434,29 @@ void testParamTypestateCaller() {
   testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
 }
 
+
+void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+struct ParamTest {
+  static void consumeFuncStatic(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+  void consumeFuncMeth(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+  void operator<<(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+};
+
+void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+
+
+void testFunctionParams() {
+  // Make sure we handle the different kinds of functions.
+  ConsumableClass<int> P;
+
+  consumeFunc(P);                   // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+  ParamTest::consumeFuncStatic(P);  // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+  ParamTest pt;
+  pt.consumeFuncMeth(P);            // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+  pt << P;                          // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+  pt >> P;                          // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+}
+
 void baf3(ConsumableClass<int> var) {
   *var;
 }





More information about the cfe-commits mailing list