diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-27 00:58:17 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-27 00:58:17 +0000 |
commit | 14d0aee957f11b9613fa4312919bec3cc5456a1c (patch) | |
tree | b54c89ea196f1db30a542516edcf1f51543ab982 /lib/Sema/SemaInit.cpp | |
parent | 52a80e19ad688091723a52ad53337767bb0ac684 (diff) |
Fix a horrible bug in our handling of C-style casting, where a C-style
derived-to-base cast that also casts away constness (one of the cases
for static_cast followed by const_cast) would be treated as a bit-cast
rather than a derived-to-base class, causing miscompiles and
heartburn.
Fixes <rdar://problem/8913298>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124340 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 00a13b54cf..b34fe2ff28 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2519,7 +2519,9 @@ static void TryReferenceInitialization(Sema &S, bool T1Function = T1->isFunctionType(); if (isLValueRef || T1Function) { if (InitCategory.isLValue() && - RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) { + (RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification || + (Kind.isCStyleOrFunctionalCast() && + RefRelationship == Sema::Ref_Related))) { // - is an lvalue (but is not a bit-field), and "cv1 T1" is // reference-compatible with "cv2 T2," or // @@ -2593,7 +2595,9 @@ static void TryReferenceInitialization(Sema &S, // "cv1 T1" is reference-compatible with "cv2 T2" // Note: functions are handled below. if (!T1Function && - RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification && + (RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification || + (Kind.isCStyleOrFunctionalCast() && + RefRelationship == Sema::Ref_Related)) && (InitCategory.isXValue() || (InitCategory.isPRValue() && T2->isRecordType()) || (InitCategory.isPRValue() && T2->isArrayType()))) { @@ -2630,9 +2634,6 @@ static void TryReferenceInitialization(Sema &S, // reference-related to T2, and can be implicitly converted to an // xvalue, class prvalue, or function lvalue of type "cv3 T3", // where "cv1 T1" is reference-compatible with "cv3 T3", - // - // FIXME: Need to handle xvalue, class prvalue, etc. cases in - // TryRefInitWithConversionFunction. if (T2->isRecordType()) { if (RefRelationship == Sema::Ref_Incompatible) { ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, @@ -2665,7 +2666,8 @@ static void TryReferenceInitialization(Sema &S, if (S.TryImplicitConversion(Sequence, TempEntity, Initializer, /*SuppressUserConversions*/ false, AllowExplicit, - /*FIXME:InOverloadResolution=*/false)) { + /*FIXME:InOverloadResolution=*/false, + /*CStyle=*/Kind.isCStyleOrFunctionalCast())) { // FIXME: Use the conversion function set stored in ICS to turn // this into an overloading ambiguity diagnostic. However, we need // to keep that set as an OverloadCandidateSet rather than as some @@ -3184,7 +3186,8 @@ InitializationSequence::InitializationSequence(Sema &S, if (S.TryImplicitConversion(*this, Entity, Initializer, /*SuppressUserConversions*/ true, /*AllowExplicitConversions*/ false, - /*InOverloadResolution*/ false)) + /*InOverloadResolution*/ false, + /*CStyle=*/Kind.isCStyleOrFunctionalCast())) { if (Initializer->getType() == Context.OverloadTy) SetFailed(InitializationSequence::FK_AddressOfOverloadFailed); @@ -3844,11 +3847,9 @@ InitializationSequence::Perform(Sema &S, } case SK_ConversionSequence: { - bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast(); - if (S.PerformImplicitConversion(CurInitExpr, Step->Type, *Step->ICS, getAssignmentAction(Entity), - IgnoreBaseAccess)) + Kind.isCStyleOrFunctionalCast())) return ExprError(); CurInit.release(); |