]> granicus.if.org Git - clang/commitdiff
Use the correct cast kinds for bit casts and function to pointer decay. Fixes PR4827.
authorAnders Carlsson <andersca@mac.com>
Tue, 1 Sep 2009 20:52:42 +0000 (20:52 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 1 Sep 2009 20:52:42 +0000 (20:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80720 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprScalar.cpp
lib/Sema/SemaCXXCast.cpp
test/CodeGenCXX/PR4827-cast.cpp [new file with mode: 0644]

index f3a841dbb2ff30a44368e195609eb7839f4ced60..4496c538d3c05efda6fe6585bc57fb3205284682 100644 (file)
@@ -627,6 +627,10 @@ Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy,
   switch (Kind) {
   default:
     break;
+  case CastExpr::CK_BitCast: {
+    Value *Src = Visit(const_cast<Expr*>(E));
+    return Builder.CreateBitCast(Src, ConvertType(DestTy));
+  }
   case CastExpr::CK_ArrayToPointerDecay: {
     assert(E->getType()->isArrayType() &&
            "Array to pointer decay must have array source type!");
index 52ebdef6f11a61692cc83fff3b5ae94333488ee4..d88bbebec13176c01665c17f6013ce48dc34b21d 100644 (file)
@@ -89,13 +89,15 @@ static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *SrcExpr,
                                            CXXMethodDecl *&ConversionDecl);
 static TryCastResult TryStaticCast(Sema &Self, Expr *SrcExpr,
                                    QualType DestType, bool CStyle,
+                                   CastExpr::CastKind &Kind, 
                                    const SourceRange &OpRange,
-                                   CastExpr::CastKind &Kind, unsigned &msg,
+                                   unsigned &msg,
                                    CXXMethodDecl *&ConversionDecl);
 static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
                                   bool CStyle, unsigned &msg);
 static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
                                         QualType DestType, bool CStyle,
+                                        CastExpr::CastKind &Kind, 
                                         const SourceRange &OpRange,
                                         unsigned &msg);
 
@@ -347,8 +349,10 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
   if (!DestType->isLValueReferenceType())
     Self.DefaultFunctionArrayConversion(SrcExpr);
 
+  CastExpr::CastKind Kind = CastExpr::CK_Unknown;
   unsigned msg = diag::err_bad_cxx_cast_generic;
-  if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange, msg)
+  if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, Kind,
+                         OpRange, msg)
       != TC_Success && msg != 0)
     Self.Diag(OpRange.getBegin(), msg) << CT_Reinterpret
       << SrcExpr->getType() << DestType << OpRange;
@@ -374,9 +378,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
 
   unsigned msg = diag::err_bad_cxx_cast_generic;
   CXXMethodDecl *ConversionDecl = 0;
-  if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange, 
-                    Kind, msg,
-                    ConversionDecl)
+  if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, Kind, 
+                    OpRange, msg, ConversionDecl)
       != TC_Success && msg != 0)
     Self.Diag(OpRange.getBegin(), msg) << CT_Static
       << SrcExpr->getType() << DestType << OpRange;
@@ -387,8 +390,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
 /// and casting away constness.
 static TryCastResult TryStaticCast(Sema &Self, Expr *SrcExpr,
                                    QualType DestType, bool CStyle,
-                                   const SourceRange &OpRange,
-                                   CastExpr::CastKind &Kind, unsigned &msg,
+                                   CastExpr::CastKind &Kind, 
+                                   const SourceRange &OpRange, unsigned &msg,
                                    CXXMethodDecl *&ConversionDecl)
 {
   // The order the tests is not entirely arbitrary. There is one conversion
@@ -864,6 +867,7 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
 
 static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
                                         QualType DestType, bool CStyle,
+                                        CastExpr::CastKind &Kind,
                                         const SourceRange &OpRange,
                                         unsigned &msg) {
   QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType();
@@ -1014,6 +1018,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
   // Void pointers are not specified, but supported by every compiler out there.
   // So we finish by allowing everything that remains - it's got to be two
   // object pointers.
+  Kind = CastExpr::CK_BitCast;
   return TC_Success;
 }
 
@@ -1046,14 +1051,16 @@ bool Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
   //   even if a cast resulting from that interpretation is ill-formed.
   // In plain language, this means trying a const_cast ...
   unsigned msg = diag::err_bad_cxx_cast_generic;
-  TryCastResult tcr = TryConstCast(*this, CastExpr, CastTy, /*CStyle*/true,msg);
+  TryCastResult tcr = TryConstCast(*this, CastExpr, CastTy, /*CStyle*/true,
+                                   msg);
   if (tcr == TC_NotApplicable) {
     // ... or if that is not possible, a static_cast, ignoring const, ...
-    tcr = TryStaticCast(*this, CastExpr, CastTy, /*CStyle*/true, R, Kind, msg,
+    tcr = TryStaticCast(*this, CastExpr, CastTy, /*CStyle*/true, Kind, R, msg,
                         ConversionDecl);
     if (tcr == TC_NotApplicable) {
       // ... and finally a reinterpret_cast, ignoring const.
-      tcr = TryReinterpretCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg);
+      tcr = TryReinterpretCast(*this, CastExpr, CastTy, /*CStyle*/true, Kind, 
+                               R, msg);
     }
   }
 
diff --git a/test/CodeGenCXX/PR4827-cast.cpp b/test/CodeGenCXX/PR4827-cast.cpp
new file mode 100644 (file)
index 0000000..958798d
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: clang-cc -emit-llvm -o - %s
+struct A;
+struct B;
+extern A *f();
+void a() { (B *) f(); }