Consumed analysis: assume that non-const reference parameters are initially
in the "uknown" state.  Patch by chris.wailes@gmail.com.  Reviewed by delesley.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192995 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/Consumed.cpp b/lib/Analysis/Consumed.cpp
index ef9617a..8358b6b 100644
--- a/lib/Analysis/Consumed.cpp
+++ b/lib/Analysis/Consumed.cpp
@@ -159,10 +159,20 @@
   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 @@
       
       // 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 @@
   ConsumedState ParamState = consumed::CS_None;
   
   if (Param->hasAttr<ParamTypestateAttr>()) {
-    ParamState =
-      mapParamTypestateAttrState(Param->getAttr<ParamTypestateAttr>());
+    const ParamTypestateAttr *PTAttr = Param->getAttr<ParamTypestateAttr>();
+    ParamState = mapParamTypestateAttrState(PTAttr);
     
-  } else if (!(ParamType->isPointerType() || ParamType->isReferenceType()) &&
-             isConsumableType(ParamType)) {
-    
+  } 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;