[analyzer] CastValueChecker: Provide DynamicTypeMap with pointer types only.

The idea to drop this requirement is good, but for now every other user
of DynamicTypeInfo expects pointer types.

Fixes a crash.

llvm-svn: 369728
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
index cd3b70d..a0cebd6 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
@@ -92,18 +92,6 @@
 };
 } // namespace
 
-static QualType getRecordType(QualType Ty) {
-  Ty = Ty.getCanonicalType();
-
-  if (Ty->isPointerType())
-    Ty = Ty->getPointeeType();
-
-  if (Ty->isReferenceType())
-    Ty = Ty.getNonReferenceType();
-
-  return Ty.getUnqualifiedType();
-}
-
 static bool isInfeasibleCast(const DynamicCastInfo *CastInfo,
                              bool CastSucceeds) {
   if (!CastInfo)
@@ -117,8 +105,8 @@
                                  QualType CastToTy, const Expr *Object,
                                  bool CastSucceeds, bool IsKnownCast) {
   std::string CastToName =
-      CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
-               : CastToTy->getAsCXXRecordDecl()->getNameAsString();
+      CastInfo ? CastInfo->to()->getPointeeCXXRecordDecl()->getNameAsString()
+               : CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
   Object = Object->IgnoreParenImpCasts();
 
   return C.getNoteTag(
@@ -160,14 +148,14 @@
 
   const Expr *Object;
   QualType CastFromTy;
-  QualType CastToTy = getRecordType(Call.getResultType());
+  QualType CastToTy = Call.getResultType();
 
   if (Call.getNumArgs() > 0) {
     Object = Call.getArgExpr(0);
-    CastFromTy = getRecordType(Call.parameters()[0]->getType());
+    CastFromTy = Call.parameters()[0]->getType();
   } else {
     Object = cast<CXXInstanceCall>(&Call)->getCXXThisExpr();
-    CastFromTy = getRecordType(Object->getType());
+    CastFromTy = Object->getType();
   }
 
   const MemRegion *MR = DV.getAsRegion();
@@ -193,7 +181,7 @@
   bool IsKnownCast = CastInfo || IsCheckedCast || CastFromTy == CastToTy;
   if (!IsKnownCast || IsCheckedCast)
     State = setDynamicTypeAndCastInfo(State, MR, CastFromTy, CastToTy,
-                                      Call.getResultType(), CastSucceeds);
+                                      CastSucceeds);
 
   SVal V = CastSucceeds ? DV : C.getSValBuilder().makeNull();
   C.addTransition(
@@ -206,8 +194,20 @@
                                     ProgramStateRef State, CheckerContext &C,
                                     bool IsInstanceOf) {
   const FunctionDecl *FD = Call.getDecl()->getAsFunction();
+  QualType CastFromTy = Call.parameters()[0]->getType();
   QualType CastToTy = FD->getTemplateSpecializationArgs()->get(0).getAsType();
-  QualType CastFromTy = getRecordType(Call.parameters()[0]->getType());
+  if (CastFromTy->isPointerType())
+    CastToTy = C.getASTContext().getPointerType(CastToTy);
+  else if (CastFromTy->isLValueReferenceType() &&
+           CastFromTy.isConstQualified()) {
+    CastToTy.addConst();
+    CastToTy = C.getASTContext().getLValueReferenceType(CastToTy);
+  } else if (CastFromTy->isLValueReferenceType())
+    CastToTy = C.getASTContext().getLValueReferenceType(CastToTy);
+  else if (CastFromTy->isRValueReferenceType())
+    CastToTy = C.getASTContext().getRValueReferenceType(CastToTy);
+  else
+    return;
 
   const MemRegion *MR = DV.getAsRegion();
   const DynamicCastInfo *CastInfo =
@@ -228,7 +228,7 @@
   bool IsKnownCast = CastInfo || CastFromTy == CastToTy;
   if (!IsKnownCast)
     State = setDynamicTypeAndCastInfo(State, MR, CastFromTy, CastToTy,
-                                      Call.getResultType(), IsInstanceOf);
+                                      IsInstanceOf);
 
   C.addTransition(
       State->BindExpr(Call.getOriginExpr(), C.getLocationContext(),
@@ -373,11 +373,6 @@
   const CastCheck &Check = Lookup->first;
   CallKind Kind = Lookup->second;
 
-  // We need to obtain the record type of the call's result to model it.
-  if (Kind != CallKind::InstanceOf &&
-      !getRecordType(Call.getResultType())->isRecordType())
-    return false;
-
   Optional<DefinedOrUnknownSVal> DV;
 
   switch (Kind) {