Refactor the expression class hierarchy for casts. Most importantly:
  - CastExpr is the root of all casts
  - ImplicitCastExpr is (still) used for all explicit casts
  - ExplicitCastExpr is now the root of all *explicit* casts
  - ExplicitCCastExpr (new name needed!?) is a C-style cast in C or C++
  - CXXFunctionalCastExpr inherits from ExplicitCastExpr
  - CXXNamedCastExpr inherits from ExplicitCastExpr and is the root of all
    of the C++ named cast expression types (static_cast, dynamic_cast, etc.)
  - Added classes CXXStaticCastExpr, CXXDynamicCastExpr, 
    CXXReinterpretCastExpr, and CXXConstCastExpr to 

Also, fixed returned-stack-addr.cpp, which broke once when we fixed
reinterpret_cast to diagnose double->int* conversions and again when
we eliminated implicit conversions to reference types. The fix is in
both testcase and SemaChecking.cpp.

Most of this patch is simply support for the renaming. There's very
little actual change in semantics.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58264 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 61ea005..1380264 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -304,7 +304,7 @@
         return E->hasLocalSideEffect();
     return false;
   }
-  case ExplicitCastExprClass:
+  case ExplicitCCastExprClass:
   case CXXFunctionalCastExprClass:
     // If this is a cast to void, check the operand.  Otherwise, the result of
     // the cast is unused.
@@ -628,7 +628,7 @@
     return true;
   }
   case ImplicitCastExprClass:
-  case ExplicitCastExprClass:
+  case ExplicitCCastExprClass:
   case CXXFunctionalCastExprClass: {
     const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr();
     SourceLocation CastLoc = getLocStart();
@@ -946,7 +946,7 @@
     break;
   }
   case ImplicitCastExprClass:
-  case ExplicitCastExprClass:
+  case ExplicitCCastExprClass:
   case CXXFunctionalCastExprClass: {
     const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr();
     SourceLocation CastLoc = getLocStart();
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 0c374ff..82626d8 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -25,10 +25,6 @@
 //===----------------------------------------------------------------------===//
 
 
-// CXXCastExpr
-Stmt::child_iterator CXXCastExpr::child_begin() { return &Op; }
-Stmt::child_iterator CXXCastExpr::child_end() { return &Op+1; }
-
 // CXXBoolLiteralExpr
 Stmt::child_iterator CXXBoolLiteralExpr::child_begin() { 
   return child_iterator();
@@ -67,3 +63,20 @@
 Stmt::child_iterator CXXConditionDeclExpr::child_end() {
   return child_iterator();
 }
+
+//===----------------------------------------------------------------------===//
+//  Named casts
+//===----------------------------------------------------------------------===//
+
+/// getCastName - Get the name of the C++ cast being used, e.g.,
+/// "static_cast", "dynamic_cast", "reinterpret_cast", or
+/// "const_cast". The returned pointer must not be freed.
+const char *CXXNamedCastExpr::getCastName() const {
+  switch (getStmtClass()) {
+  case CXXStaticCastExprClass:      return "static_cast";
+  case CXXDynamicCastExprClass:     return "dynamic_cast";
+  case CXXReinterpretCastExprClass: return "reinterpret_cast";
+  case CXXConstCastExprClass:       return "const_cast";
+  default:                          return "<invalid cast>";
+  }
+}
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 666cad6..349b6fb 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -128,8 +128,9 @@
     void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
 
     // C++
-    void VisitCXXCastExpr(CXXCastExpr *Node);
+    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
     void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
+    void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
 
     // ObjC
     void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
@@ -406,9 +407,10 @@
 // C++ Expressions
 //===----------------------------------------------------------------------===//
 
-void StmtDumper::VisitCXXCastExpr(CXXCastExpr *Node) {
+void StmtDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
   DumpExpr(Node);
-  fprintf(F, " %s", CXXCastExpr::getOpcodeStr(Node->getOpcode()));
+  fprintf(F, " %s<%s>", Node->getCastName(),
+          Node->getTypeAsWritten().getAsString().c_str());
 }
 
 void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
@@ -416,6 +418,12 @@
   fprintf(F, " %s", Node->getValue() ? "true" : "false");
 }
 
+void StmtDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
+  DumpExpr(Node);
+  fprintf(F, " functional cast to %s", 
+          Node->getTypeAsWritten().getAsString().c_str());
+}
+
 //===----------------------------------------------------------------------===//
 // Obj-C Expressions
 //===----------------------------------------------------------------------===//
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index ba67a97..fb6fba3 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -707,7 +707,10 @@
 void StmtPrinter::VisitCastExpr(CastExpr *) {
   assert(0 && "CastExpr is an abstract class");
 }
-void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *Node) {
+void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) {
+  assert(0 && "ExplicitCastExpr is an abstract class");
+}
+void StmtPrinter::VisitExplicitCCastExpr(ExplicitCCastExpr *Node) {
   OS << "(" << Node->getType().getAsString() << ")";
   PrintExpr(Node->getSubExpr());
 }
@@ -809,13 +812,29 @@
 
 // C++
 
-void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
-  OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
-  OS << Node->getDestType().getAsString() << ">(";
+void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
+  OS << Node->getCastName() << '<';
+  OS << Node->getTypeAsWritten().getAsString() << ">(";
   PrintExpr(Node->getSubExpr());
   OS << ")";
 }
 
+void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
 void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
   OS << (Node->getValue() ? "true" : "false");
 }
diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp
index decd9a7..bf7cbc5 100644
--- a/lib/AST/StmtSerialization.cpp
+++ b/lib/AST/StmtSerialization.cpp
@@ -106,8 +106,8 @@
     case ImplicitCastExprClass:
       return ImplicitCastExpr::CreateImpl(D, C);
 
-    case ExplicitCastExprClass:
-      return ExplicitCastExpr::CreateImpl(D, C);
+    case ExplicitCCastExprClass:
+      return ExplicitCCastExpr::CreateImpl(D, C);
       
     case IndirectGotoStmtClass:
       return IndirectGotoStmt::CreateImpl(D, C);
@@ -201,6 +201,18 @@
     case CXXFunctionalCastExprClass:
       return CXXFunctionalCastExpr::CreateImpl(D, C);
 
+    case CXXStaticCastExprClass:
+      return CXXStaticCastExpr::CreateImpl(D, C, SC);
+
+    case CXXDynamicCastExprClass:
+      return CXXDynamicCastExpr::CreateImpl(D, C, SC);
+
+    case CXXReinterpretCastExprClass:
+      return CXXReinterpretCastExpr::CreateImpl(D, C, SC);
+
+    case CXXConstCastExprClass:
+      return CXXConstCastExpr::CreateImpl(D, C, SC);
+      
     case CXXZeroInitValueExprClass:
       return CXXZeroInitValueExpr::CreateImpl(D, C);
   }
@@ -364,19 +376,20 @@
   return stmt;
 }
 
-void ExplicitCastExpr::EmitImpl(Serializer& S) const {
+void ExplicitCCastExpr::EmitImpl(Serializer& S) const {
   S.Emit(getType());
+  S.Emit(getTypeAsWritten());
   S.Emit(Loc);
   S.EmitOwnedPtr(getSubExpr());
 }
 
-ExplicitCastExpr* ExplicitCastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
+ExplicitCCastExpr* ExplicitCCastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
   QualType t = QualType::ReadVal(D);
+  QualType writtenTy = QualType::ReadVal(D);
   SourceLocation Loc = SourceLocation::ReadVal(D);
   Expr* Op = D.ReadOwnedPtr<Expr>(C);
-  return new ExplicitCastExpr(t,Op,Loc);
+  return new ExplicitCCastExpr(t,Op,writtenTy,Loc);
 }
-  
 
 void CharacterLiteral::EmitImpl(Serializer& S) const {
   S.Emit(Value);
@@ -1270,6 +1283,7 @@
 
 void CXXFunctionalCastExpr::EmitImpl(Serializer& S) const {
   S.Emit(getType());
+  S.Emit(getTypeAsWritten());
   S.Emit(TyBeginLoc);
   S.Emit(RParenLoc);
   S.EmitOwnedPtr(getSubExpr());
@@ -1278,10 +1292,39 @@
 CXXFunctionalCastExpr *
 CXXFunctionalCastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
   QualType Ty = QualType::ReadVal(D);
+  QualType WrittenTy = QualType::ReadVal(D);
   SourceLocation TyBeginLoc = SourceLocation::ReadVal(D);
   SourceLocation RParenLoc = SourceLocation::ReadVal(D);
   Expr* SubExpr = D.ReadOwnedPtr<Expr>(C);
-  return new CXXFunctionalCastExpr(Ty, TyBeginLoc, SubExpr, RParenLoc);
+  return new CXXFunctionalCastExpr(Ty, WrittenTy, TyBeginLoc, SubExpr, RParenLoc);
+}
+
+void CXXNamedCastExpr::EmitImpl(Serializer& S) const {
+  S.Emit(getType());
+  S.Emit(getTypeAsWritten());
+  S.Emit(Loc);
+  S.EmitOwnedPtr(getSubExpr());
+}
+
+CXXNamedCastExpr *
+CXXNamedCastExpr::CreateImpl(Deserializer& D, ASTContext& C, StmtClass SC) {
+  QualType Ty = QualType::ReadVal(D);
+  QualType WrittenTy = QualType::ReadVal(D);
+  SourceLocation Loc = SourceLocation::ReadVal(D);
+  Expr* SubExpr = D.ReadOwnedPtr<Expr>(C);
+  switch (SC) {
+  case CXXStaticCastExprClass: 
+    return new CXXStaticCastExpr(Ty, SubExpr, WrittenTy, Loc);
+  case CXXDynamicCastExprClass: 
+    return new CXXDynamicCastExpr(Ty, SubExpr, WrittenTy, Loc);
+  case CXXReinterpretCastExprClass: 
+    return new CXXReinterpretCastExpr(Ty, SubExpr, WrittenTy, Loc);
+  case CXXConstCastExprClass: 
+    return new CXXConstCastExpr(Ty, SubExpr, WrittenTy, Loc);
+  default:
+    assert(false && "Unknown cast type!");
+    return 0;
+  }
 }
 
 void CXXZeroInitValueExpr::EmitImpl(Serializer& S) const {
diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp
index f220ee7..a5f158c 100644
--- a/lib/Analysis/Environment.cpp
+++ b/lib/Analysis/Environment.cpp
@@ -47,7 +47,7 @@
       // subexpression that has a value.
        
       case Stmt::ImplicitCastExprClass:
-      case Stmt::ExplicitCastExprClass: {
+      case Stmt::ExplicitCCastExprClass: {
         CastExpr* C = cast<CastExpr>(E);
         QualType CT = C->getType();
         QualType ST = C->getSubExpr()->getType();
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 2a74311..282a08c 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -345,7 +345,7 @@
       break;
       
     case Stmt::ImplicitCastExprClass:
-    case Stmt::ExplicitCastExprClass: {
+    case Stmt::ExplicitCCastExprClass: {
       CastExpr* C = cast<CastExpr>(S);
       VisitCast(C, C->getSubExpr(), Pred, Dst);
       break;
@@ -1445,6 +1445,9 @@
   QualType T = CastE->getType();
   QualType ExTy = Ex->getType();
 
+  if (const ExplicitCastExpr *ExCast = dyn_cast_or_null<ExplicitCastExpr>(CastE))
+    T = ExCast->getTypeAsWritten();
+
   if (ExTy->isArrayType() || ExTy->isFunctionType() || T->isReferenceType())
     VisitLValue(Ex, Pred, S1);
   else
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 8b4db30..2b9ab55 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -61,9 +61,9 @@
   ExprResult Result = ParseSimpleParenExpression(RParenLoc);
 
   if (!Result.isInvalid)
-    Result = Actions.ActOnCXXCasts(OpLoc, Kind,
-                                   LAngleBracketLoc, CastTy, RAngleBracketLoc,
-                                   LParenLoc, Result.Val, RParenLoc);
+    Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
+                                       LAngleBracketLoc, CastTy, RAngleBracketLoc,
+                                       LParenLoc, Result.Val, RParenLoc);
 
   return Result;
 }
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index a2872a2..f84b5c5 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -695,12 +695,12 @@
                                              SourceLocation *CommaLocs,
                                              SourceLocation RParenLoc);
 
-  /// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
-  virtual ExprResult ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
-                                   SourceLocation LAngleBracketLoc, TypeTy *Ty,
-                                   SourceLocation RAngleBracketLoc,
-                                   SourceLocation LParenLoc, ExprTy *E,
-                                   SourceLocation RParenLoc);
+  /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+  virtual ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
+                                       SourceLocation LAngleBracketLoc, TypeTy *Ty,
+                                       SourceLocation RAngleBracketLoc,
+                                       SourceLocation LParenLoc, ExprTy *E,
+                                       SourceLocation RParenLoc);
 
   // Helpers for ActOnCXXCasts
   bool CastsAwayConstness(QualType SrcType, QualType DestType);
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 27f3abe..3365992 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -736,12 +736,11 @@
   }
   // Perform checking for stack values returned by reference.
   else if (lhsType->isReferenceType()) {
-    // Check for an implicit cast to a reference.
-    if (ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(RetValExp))
-      if (DeclRefExpr *DR = EvalVal(I->getSubExpr()))
-        Diag(DR->getLocStart(), diag::warn_ret_stack_ref,
-             DR->getDecl()->getIdentifier()->getName(),
-             RetValExp->getSourceRange());
+    // Check for a reference to the stack
+    if (DeclRefExpr *DR = EvalVal(RetValExp))
+      Diag(DR->getLocStart(), diag::warn_ret_stack_ref,
+           DR->getDecl()->getIdentifier()->getName(),
+           RetValExp->getSourceRange());
   }
 }
 
@@ -826,9 +825,9 @@
     
   // For casts, we need to handle conversions from arrays to
   // pointer values, and pointer-to-pointer conversions.
-  case Stmt::ExplicitCastExprClass:
-  case Stmt::ImplicitCastExprClass: {
-    
+  case Stmt::ImplicitCastExprClass:
+  case Stmt::ExplicitCCastExprClass:
+  case Stmt::CXXFunctionalCastExprClass: {
     Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
     QualType T = SubExpr->getType();
     
@@ -844,21 +843,21 @@
     
   // C++ casts.  For dynamic casts, static casts, and const casts, we
   // are always converting from a pointer-to-pointer, so we just blow
-  // through the cast.  In the case the dynamic cast doesn't fail
-  // (and return NULL), we take the conservative route and report cases
+  // through the cast.  In the case the dynamic cast doesn't fail (and
+  // return NULL), we take the conservative route and report cases
   // where we return the address of a stack variable.  For Reinterpre
-  case Stmt::CXXCastExprClass: {
-    CXXCastExpr *C = cast<CXXCastExpr>(E);
-    
-    if (C->getOpcode() == CXXCastExpr::ReinterpretCast) {
-      Expr *S = C->getSubExpr();
+  // FIXME: The comment about is wrong; we're not always converting
+  // from pointer to pointer. I'm guessing that this code should also
+  // handle references to objects.  
+  case Stmt::CXXStaticCastExprClass: 
+  case Stmt::CXXDynamicCastExprClass: 
+  case Stmt::CXXConstCastExprClass:
+  case Stmt::CXXReinterpretCastExprClass: {
+      Expr *S = cast<CXXNamedCastExpr>(E)->getSubExpr();
       if (S->getType()->isPointerType() || S->getType()->isBlockPointerType())
         return EvalAddr(S);
       else
         return NULL;
-    }
-    else
-      return EvalAddr(C->getSubExpr());
   }
     
   // Everything else: we simply don't reason about them.
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 624c576..7b88ec2 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1060,7 +1060,7 @@
            CheckArithmeticConstantExpression(IExp);
   }
   case Expr::ImplicitCastExprClass:
-  case Expr::ExplicitCastExprClass: {
+  case Expr::ExplicitCCastExprClass: {
     const Expr* SubExpr = cast<CastExpr>(Init)->getSubExpr();
     if (Init->getStmtClass() == Expr::ImplicitCastExprClass) {
       // Check for implicit promotion
@@ -1190,7 +1190,7 @@
     // if we don't, we'll figure it out later
     return 0;
   }
-  case Expr::ExplicitCastExprClass: {
+  case Expr::ExplicitCCastExprClass: {
     const Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
 
     // Check for pointer->pointer cast
@@ -1310,7 +1310,7 @@
     return true;
   }
   case Expr::ImplicitCastExprClass:
-  case Expr::ExplicitCastExprClass: {
+  case Expr::ExplicitCCastExprClass: {
     const Expr *SubExpr = cast<CastExpr>(Init)->getSubExpr();
     if (SubExpr->getType()->isArithmeticType())
       return CheckArithmeticConstantExpression(SubExpr);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index d1be2a4..a73f0dd 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1333,7 +1333,7 @@
 
   if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr))
     return true;
-  return new ExplicitCastExpr(castType, castExpr, LParenLoc);
+  return new ExplicitCCastExpr(castType, castExpr, castType, LParenLoc);
 }
 
 /// Note that lex is not null here, even if this is the gnu "x ?: y" extension.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index fa81f11..34eff25 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -21,36 +21,39 @@
 #include "llvm/Support/Debug.h"
 using namespace clang;
 
-/// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
+/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
 Action::ExprResult
-Sema::ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
-                    SourceLocation LAngleBracketLoc, TypeTy *Ty,
-                    SourceLocation RAngleBracketLoc,
-                    SourceLocation LParenLoc, ExprTy *E,
-                    SourceLocation RParenLoc) {
-  CXXCastExpr::Opcode Op;
+Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
+                        SourceLocation LAngleBracketLoc, TypeTy *Ty,
+                        SourceLocation RAngleBracketLoc,
+                        SourceLocation LParenLoc, ExprTy *E,
+                        SourceLocation RParenLoc) {
   Expr *Ex = (Expr*)E;
   QualType DestType = QualType::getFromOpaquePtr(Ty);
 
   switch (Kind) {
   default: assert(0 && "Unknown C++ cast!");
+
   case tok::kw_const_cast:
-    Op = CXXCastExpr::ConstCast;
     CheckConstCast(OpLoc, Ex, DestType);
-    break;
+    return new CXXConstCastExpr(DestType.getNonReferenceType(), Ex, 
+                                DestType, OpLoc);
+
   case tok::kw_dynamic_cast:
-    Op = CXXCastExpr::DynamicCast;
-    break;
+    return new CXXDynamicCastExpr(DestType.getNonReferenceType(), Ex, 
+                                  DestType, OpLoc);
+
   case tok::kw_reinterpret_cast:
-    Op = CXXCastExpr::ReinterpretCast;
     CheckReinterpretCast(OpLoc, Ex, DestType);
-    break;
+    return new CXXReinterpretCastExpr(DestType.getNonReferenceType(), Ex, 
+                                      DestType, OpLoc);
+
   case tok::kw_static_cast:
-    Op = CXXCastExpr::StaticCast;
-    break;
+    return new CXXStaticCastExpr(DestType.getNonReferenceType(), Ex, 
+                                 DestType, OpLoc);
   }
   
-  return new CXXCastExpr(Op, DestType, Ex, OpLoc);
+  return true;
 }
 
 /// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid.
@@ -437,7 +440,8 @@
   if (NumExprs == 1) {
     if (CheckCastTypes(TypeRange, Ty, Exprs[0]))
       return true;
-    return new CXXFunctionalCastExpr(Ty, TyBeginLoc, Exprs[0], RParenLoc);
+    return new CXXFunctionalCastExpr(Ty.getNonReferenceType(), Ty, TyBeginLoc, 
+                                     Exprs[0], RParenLoc);
   }
 
   // C++ 5.2.3p1: