зеркало из https://github.com/microsoft/clang-1.git
More detailed analysis of typecast to an objective-c pointer
in objective-c++ mode without being too lenient. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90895 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
fead20c1de
Коммит
92ef5d7572
|
@ -1571,7 +1571,11 @@ public:
|
||||||
CK_FloatingCast,
|
CK_FloatingCast,
|
||||||
|
|
||||||
/// CK_MemberPointerToBoolean - Member pointer to boolean
|
/// CK_MemberPointerToBoolean - Member pointer to boolean
|
||||||
CK_MemberPointerToBoolean
|
CK_MemberPointerToBoolean,
|
||||||
|
|
||||||
|
/// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c
|
||||||
|
/// pointer
|
||||||
|
CK_AnyPointerToObjCPointerCast
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -798,6 +798,7 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
|
||||||
//assert(0 && "Unknown cast kind!");
|
//assert(0 && "Unknown cast kind!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CastExpr::CK_AnyPointerToObjCPointerCast:
|
||||||
case CastExpr::CK_BitCast: {
|
case CastExpr::CK_BitCast: {
|
||||||
Value *Src = Visit(const_cast<Expr*>(E));
|
Value *Src = Visit(const_cast<Expr*>(E));
|
||||||
return Builder.CreateBitCast(Src, ConvertType(DestTy));
|
return Builder.CreateBitCast(Src, ConvertType(DestTy));
|
||||||
|
|
|
@ -539,6 +539,11 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
|
||||||
return TC_Success;
|
return TC_Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (CStyle && DestType->isObjCObjectPointerType()) {
|
||||||
|
// allow c-style cast of objective-c pointers as they are pervasive.
|
||||||
|
Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
|
||||||
|
return TC_Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,8 +1058,10 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
|
||||||
return TC_Failed;
|
return TC_Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool destIsPtr = DestType->isPointerType();
|
bool destIsPtr =
|
||||||
bool srcIsPtr = SrcType->isPointerType();
|
CStyle? DestType->isAnyPointerType() : DestType->isPointerType();
|
||||||
|
bool srcIsPtr =
|
||||||
|
CStyle ? SrcType->isAnyPointerType() : SrcType->isPointerType();
|
||||||
if (!destIsPtr && !srcIsPtr) {
|
if (!destIsPtr && !srcIsPtr) {
|
||||||
// Except for std::nullptr_t->integer and lvalue->reference, which are
|
// Except for std::nullptr_t->integer and lvalue->reference, which are
|
||||||
// handled above, at least one of the two arguments must be a pointer.
|
// handled above, at least one of the two arguments must be a pointer.
|
||||||
|
@ -1106,7 +1113,11 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
|
||||||
msg = diag::err_bad_cxx_cast_const_away;
|
msg = diag::err_bad_cxx_cast_const_away;
|
||||||
return TC_Failed;
|
return TC_Failed;
|
||||||
}
|
}
|
||||||
|
if (CStyle && DestType->isObjCObjectPointerType()) {
|
||||||
|
Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
|
||||||
|
return TC_Success;
|
||||||
|
}
|
||||||
|
|
||||||
// Not casting away constness, so the only remaining check is for compatible
|
// Not casting away constness, so the only remaining check is for compatible
|
||||||
// pointer categories.
|
// pointer categories.
|
||||||
Kind = CastExpr::CK_BitCast;
|
Kind = CastExpr::CK_BitCast;
|
||||||
|
@ -1141,7 +1152,6 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
|
||||||
// Void pointers are not specified, but supported by every compiler out there.
|
// 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
|
// So we finish by allowing everything that remains - it's got to be two
|
||||||
// object pointers.
|
// object pointers.
|
||||||
Kind = CastExpr::CK_BitCast;
|
|
||||||
return TC_Success;
|
return TC_Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1160,10 +1170,6 @@ bool Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
|
||||||
if (CastTy->isDependentType() || CastExpr->isTypeDependent())
|
if (CastTy->isDependentType() || CastExpr->isTypeDependent())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// allow c-style cast of objective-c pointers as they are pervasive.
|
|
||||||
if (CastTy->isObjCObjectPointerType())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!CastTy->isLValueReferenceType() && !CastTy->isRecordType())
|
if (!CastTy->isLValueReferenceType() && !CastTy->isRecordType())
|
||||||
DefaultFunctionArrayConversion(CastExpr);
|
DefaultFunctionArrayConversion(CastExpr);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
@protocol P @end
|
@protocol P @end
|
||||||
@interface I @end
|
@interface I @end
|
||||||
|
|
||||||
int main() {
|
struct X { X(); };
|
||||||
|
|
||||||
|
void test1(X x) {
|
||||||
void *cft;
|
void *cft;
|
||||||
id oct = (id)cft;
|
id oct = (id)cft;
|
||||||
|
|
||||||
|
@ -12,9 +14,27 @@ int main() {
|
||||||
|
|
||||||
I* iict = (I*)cft;
|
I* iict = (I*)cft;
|
||||||
|
|
||||||
id<P> pid = (id<P>)cft;
|
id<P> qid = (id<P>)cft;
|
||||||
|
|
||||||
I<P> *ip = (I<P>*)cft;
|
I<P> *ip = (I<P>*)cft;
|
||||||
|
|
||||||
|
(id)x; // expected-error {{C-style cast from 'struct X' to 'id' is not allowed}}
|
||||||
|
|
||||||
|
id *pid = (id*)ccct;
|
||||||
|
|
||||||
|
id<P> *qpid = (id<P>*)ccct;
|
||||||
|
|
||||||
|
int **pii;
|
||||||
|
|
||||||
|
ccct = (Class)pii;
|
||||||
|
|
||||||
|
qpid = (id<P>*)pii;
|
||||||
|
|
||||||
|
iict = (I*)pii;
|
||||||
|
|
||||||
|
pii = (int **)ccct;
|
||||||
|
|
||||||
|
pii = (int **)qpid;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче