summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp50
1 files changed, 32 insertions, 18 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp
index e83dd07..6222e4c 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp
@@ -256,6 +256,7 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
Op.CheckConstCast();
if (Op.SrcExpr.isInvalid())
return ExprError();
+ DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);
}
return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType,
Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
@@ -279,6 +280,7 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
Op.CheckReinterpretCast();
if (Op.SrcExpr.isInvalid())
return ExprError();
+ DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);
}
return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType,
Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
@@ -291,6 +293,7 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
Op.CheckStaticCast();
if (Op.SrcExpr.isInvalid())
return ExprError();
+ DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);
}
return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType,
@@ -980,7 +983,7 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
// C++11 [expr.static.cast]p3:
// A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv2
// T2" if "cv2 T2" is reference-compatible with "cv1 T1".
- tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind,
+ tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind,
BasePath, msg);
if (tcr != TC_NotApplicable)
return tcr;
@@ -1131,12 +1134,12 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
}
/// Tests whether a conversion according to N2844 is valid.
-TryCastResult
-TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
- bool CStyle, CastKind &Kind, CXXCastPath &BasePath,
- unsigned &msg) {
+TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr,
+ QualType DestType, bool CStyle,
+ CastKind &Kind, CXXCastPath &BasePath,
+ unsigned &msg) {
// C++11 [expr.static.cast]p3:
- // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to
+ // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to
// cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
const RValueReferenceType *R = DestType->getAs<RValueReferenceType>();
if (!R)
@@ -1157,15 +1160,18 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
FromType = FromType.getUnqualifiedType();
ToType = ToType.getUnqualifiedType();
}
-
- if (Self.CompareReferenceRelationship(SrcExpr->getLocStart(),
- ToType, FromType,
- DerivedToBase, ObjCConversion,
- ObjCLifetimeConversion)
- < Sema::Ref_Compatible_With_Added_Qualification) {
- if (CStyle)
+
+ Sema::ReferenceCompareResult RefResult = Self.CompareReferenceRelationship(
+ SrcExpr->getLocStart(), ToType, FromType, DerivedToBase, ObjCConversion,
+ ObjCLifetimeConversion);
+ if (RefResult != Sema::Ref_Compatible) {
+ if (CStyle || RefResult == Sema::Ref_Incompatible)
return TC_NotApplicable;
- msg = diag::err_bad_lvalue_to_rvalue_cast;
+ // Diagnose types which are reference-related but not compatible here since
+ // we can provide better diagnostics. In these cases forwarding to
+ // [expr.static.cast]p4 should never result in a well-formed cast.
+ msg = SrcExpr->isLValue() ? diag::err_bad_lvalue_to_rvalue_cast
+ : diag::err_bad_rvalue_to_rvalue_cast;
return TC_Failed;
}
@@ -1511,6 +1517,9 @@ TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
? InitializationKind::CreateFunctionalCast(OpRange, ListInitialization)
: InitializationKind::CreateCast(OpRange);
Expr *SrcExprRaw = SrcExpr.get();
+ // FIXME: Per DR242, we should check for an implicit conversion sequence
+ // or for a constructor that could be invoked by direct-initialization
+ // here, not for an initialization sequence.
InitializationSequence InitSeq(Self, Entity, InitKind, SrcExprRaw);
// At this point of CheckStaticCast, if the destination is a reference,
@@ -1646,7 +1655,8 @@ static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr,
if (NeedToMaterializeTemporary)
// This is a const_cast from a class prvalue to an rvalue reference type.
// Materialize a temporary to store the result of the conversion.
- SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
+ SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcExpr.get()->getType(),
+ SrcExpr.get(),
/*IsLValueReference*/ false);
return TC_Success;
@@ -1910,7 +1920,10 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
switch (SrcExpr.get()->getObjectKind()) {
case OK_Ordinary:
break;
- case OK_BitField: inappropriate = "bit-field"; break;
+ case OK_BitField:
+ msg = diag::err_bad_cxx_cast_bitfield;
+ return TC_NotApplicable;
+ // FIXME: Use a specific diagnostic for the rest of these cases.
case OK_VectorComponent: inappropriate = "vector element"; break;
case OK_ObjCProperty: inappropriate = "property expression"; break;
case OK_ObjCSubscript: inappropriate = "container subscripting expression";
@@ -2435,7 +2448,7 @@ void CastOperation::CheckCStyleCast() {
return;
}
Self.Diag(OpRange.getBegin(),
- diag::error_opencl_cast_non_zero_to_event_t)
+ diag::err_opencl_cast_non_zero_to_event_t)
<< CastInt.toString(10) << SrcExpr.get()->getSourceRange();
SrcExpr = ExprError();
return;
@@ -2516,7 +2529,8 @@ void CastOperation::CheckCStyleCast() {
}
}
- if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().cl_khr_fp16) {
+ if (Self.getLangOpts().OpenCL &&
+ !Self.getOpenCLOptions().isEnabled("cl_khr_fp16")) {
if (DestType->isHalfType()) {
Self.Diag(SrcExpr.get()->getLocStart(), diag::err_opencl_cast_to_half)
<< DestType << SrcExpr.get()->getSourceRange();
OpenPOWER on IntegriCloud