r192995 - Consumed analysis: assume that non-const reference parameters are initially

DeLesley Hutchins delesley at google.com
Fri Oct 18 12:25:19 PDT 2013


Author: delesley
Date: Fri Oct 18 14:25:18 2013
New Revision: 192995

URL: http://llvm.org/viewvc/llvm-project?rev=192995&view=rev
Log:
Consumed analysis: assume that non-const reference parameters are initially
in the "uknown" state.  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=192995&r1=192994&r2=192995&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Fri Oct 18 14:25:18 2013
@@ -159,10 +159,20 @@ static bool isKnownState(ConsumedState S
   llvm_unreachable("invalid enum");
 }
 
+static bool isRValueRefish(QualType ParamType) {
+  return ParamType->isRValueReferenceType() ||
+        (ParamType->isLValueReferenceType() &&
+         !cast<LValueReferenceType>(*ParamType).isSpelledAsLValue());
+}
+
 static bool isTestingFunction(const FunctionDecl *FunDecl) {
   return FunDecl->hasAttr<TestsTypestateAttr>();
 }
 
+static bool isValueType(QualType ParamType) {
+  return !(ParamType->isPointerType() || ParamType->isReferenceType());
+}
+
 static ConsumedState mapConsumableAttrState(const QualType QT) {
   assert(isConsumableType(QT));
 
@@ -617,20 +627,15 @@ void ConsumedStmtVisitor::VisitCallExpr(
       
       // Adjust state on the caller side.
       
-      if (ParamType->isRValueReferenceType() ||
-          (ParamType->isLValueReferenceType() &&
-           !cast<LValueReferenceType>(*ParamType).isSpelledAsLValue())) {
-        
+      if (isRValueRefish(ParamType)) {
         StateMap->setState(PInfo.getVar(), consumed::CS_Consumed);
         
       } else if (Param->hasAttr<ReturnTypestateAttr>()) {
         StateMap->setState(PInfo.getVar(),
           mapReturnTypestateAttrState(Param->getAttr<ReturnTypestateAttr>()));
         
-      } else if (!(ParamType.isConstQualified() ||
-                   ((ParamType->isReferenceType() ||
-                     ParamType->isPointerType()) &&
-                    ParamType->getPointeeType().isConstQualified()))) {
+      } else if (!isValueType(ParamType) &&
+                 !ParamType->getPointeeType().isConstQualified()) {
         
         StateMap->setState(PInfo.getVar(), consumed::CS_Unknown);
       }
@@ -856,14 +861,17 @@ void ConsumedStmtVisitor::VisitParmVarDe
   ConsumedState ParamState = consumed::CS_None;
   
   if (Param->hasAttr<ParamTypestateAttr>()) {
-    ParamState =
-      mapParamTypestateAttrState(Param->getAttr<ParamTypestateAttr>());
-    
-  } else if (!(ParamType->isPointerType() || ParamType->isReferenceType()) &&
-             isConsumableType(ParamType)) {
+    const ParamTypestateAttr *PTAttr = Param->getAttr<ParamTypestateAttr>();
+    ParamState = mapParamTypestateAttrState(PTAttr);
     
+  } else if (isValueType(ParamType) && isConsumableType(ParamType)) {
     ParamState = mapConsumableAttrState(ParamType);
     
+  } else if (isRValueRefish(ParamType) &&
+             isConsumableType(ParamType->getPointeeType())) {
+    
+    ParamState = mapConsumableAttrState(ParamType->getPointeeType());
+    
   } else if (ParamType->isReferenceType() &&
              isConsumableType(ParamType->getPointeeType())) {
     ParamState = consumed::CS_Unknown;

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=192995&r1=192994&r2=192995&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp Fri Oct 18 14:25:18 2013
@@ -63,9 +63,10 @@ void baf0(const ConsumableClass<int>  va
 void baf1(const ConsumableClass<int> &var);
 void baf2(const ConsumableClass<int> *var);
 
-void baf3(ConsumableClass<int>  &var);
-void baf4(ConsumableClass<int>  *var);
-void baf5(ConsumableClass<int> &&var);
+void baf3(ConsumableClass<int>   var);
+void baf4(ConsumableClass<int>  &var);
+void baf5(ConsumableClass<int>  *var);
+void baf6(ConsumableClass<int> &&var);
 
 ConsumableClass<int> returnsUnconsumed() {
   return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}}
@@ -268,9 +269,9 @@ void testComplexConditionals1() {
   ConsumableClass<int> var0, var1, var2;
   
   // Coerce all variables into the unknown state.
-  baf3(var0);
-  baf3(var1);
-  baf3(var2);
+  baf4(var0);
+  baf4(var1);
+  baf4(var2);
   
   if (var0 && var1) {
     *var0;
@@ -374,7 +375,7 @@ void testStateChangeInBranch() {
   ConsumableClass<int> var;
   
   // Make var enter the 'unknown' state.
-  baf3(var);
+  baf4(var);
   
   if (!var) {
     var = ConsumableClass<int>(42);
@@ -426,6 +427,18 @@ void testParamTypestateCaller() {
   testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
 }
 
+void baf3(ConsumableClass<int> var) {
+  *var;
+}
+
+void baf4(ConsumableClass<int> &var) {
+  *var;  // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
+}
+
+void baf6(ConsumableClass<int> &&var) {
+  *var;
+}
+
 void testCallingConventions() {
   ConsumableClass<int> var(42);
   
@@ -438,15 +451,15 @@ void testCallingConventions() {
   baf2(&var);  
   *var;
   
-  baf3(var);  
+  baf4(var);  
   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
   
   var = ConsumableClass<int>(42);
-  baf4(&var);  
+  baf5(&var);  
   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
   
   var = ConsumableClass<int>(42);
-  baf5(static_cast<ConsumableClass<int>&&>(var));  
+  baf6(static_cast<ConsumableClass<int>&&>(var));  
   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
 }
 
@@ -483,7 +496,7 @@ void testCallableWhen() {
   
   *var;
   
-  baf3(var);
+  baf4(var);
   
   var.callableWhenUnknown();
 }





More information about the cfe-commits mailing list