diff options
author | George Burgess IV <george.burgess.iv@gmail.com> | 2015-10-11 20:13:20 +0000 |
---|---|---|
committer | George Burgess IV <george.burgess.iv@gmail.com> | 2015-10-11 20:13:20 +0000 |
commit | 4546181e12c89c92e37f6da5cfb800b5b0fea755 (patch) | |
tree | 6f901c23b3940dc51b225f77650585c4bd7ecae3 /clang/lib/Sema/SemaExpr.cpp | |
parent | fcc34bdee0da68ffe520316fc8e369cce21f8466 (diff) | |
download | bcm5719-llvm-4546181e12c89c92e37f6da5cfb800b5b0fea755.tar.gz bcm5719-llvm-4546181e12c89c92e37f6da5cfb800b5b0fea755.zip |
[Sema] Allow C conversions in C overload logic
C allows for some implicit conversions that C++ does not, e.g. void* ->
char*. This patch teaches clang that these conversions are okay when
dealing with overloads in C.
Differential Revision: http://reviews.llvm.org/D13604
llvm-svn: 249995
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 801709c17db..3c916a30d17 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5376,13 +5376,13 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { return CK_IntegralToFloating; case Type::STK_IntegralComplex: Src = ImpCastExprToType(Src.get(), - DestTy->castAs<ComplexType>()->getElementType(), - CK_IntegralCast); + DestTy->castAs<ComplexType>()->getElementType(), + CK_IntegralCast); return CK_IntegralRealToComplex; case Type::STK_FloatingComplex: Src = ImpCastExprToType(Src.get(), - DestTy->castAs<ComplexType>()->getElementType(), - CK_IntegralToFloating); + DestTy->castAs<ComplexType>()->getElementType(), + CK_IntegralToFloating); return CK_FloatingRealToComplex; case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); @@ -6867,7 +6867,7 @@ Sema::CheckAssignmentConstraints(SourceLocation Loc, ExprResult RHSPtr = &RHSExpr; CastKind K = CK_Invalid; - return CheckAssignmentConstraints(LHSType, RHSPtr, K); + return CheckAssignmentConstraints(LHSType, RHSPtr, K, /*ConvertRHS=*/false); } /// CheckAssignmentConstraints (C99 6.5.16) - This routine currently @@ -6889,7 +6889,7 @@ Sema::CheckAssignmentConstraints(SourceLocation Loc, /// Sets 'Kind' for any result kind except Incompatible. Sema::AssignConvertType Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, - CastKind &Kind) { + CastKind &Kind, bool ConvertRHS) { QualType RHSType = RHS.get()->getType(); QualType OrigLHSType = LHSType; @@ -6911,7 +6911,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, CheckAssignmentConstraints(AtomicTy->getValueType(), RHS, Kind); if (result != Compatible) return result; - if (Kind != CK_NoOp) + if (Kind != CK_NoOp && ConvertRHS) RHS = ImpCastExprToType(RHS.get(), AtomicTy->getValueType(), Kind); Kind = CK_NonAtomicToAtomic; return Compatible; @@ -6941,7 +6941,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // CK_VectorSplat does T -> vector T, so first cast to the // element type. QualType elType = cast<ExtVectorType>(LHSType)->getElementType(); - if (elType != RHSType) { + if (elType != RHSType && ConvertRHS) { Kind = PrepareScalarCast(RHS, elType); RHS = ImpCastExprToType(RHS.get(), elType, Kind); } @@ -6974,7 +6974,8 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // Arithmetic conversions. if (LHSType->isArithmeticType() && RHSType->isArithmeticType() && !(getLangOpts().CPlusPlus && LHSType->isEnumeralType())) { - Kind = PrepareScalarCast(RHS, LHSType); + if (ConvertRHS) + Kind = PrepareScalarCast(RHS, LHSType); return Compatible; } @@ -7099,7 +7100,8 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // Only under strict condition T^ is compatible with an Objective-C pointer. if (RHSType->isBlockPointerType() && LHSType->isBlockCompatibleObjCPointerType(Context)) { - maybeExtendBlockObject(RHS); + if (ConvertRHS) + maybeExtendBlockObject(RHS); Kind = CK_BlockPointerToObjCPointerCast; return Compatible; } @@ -7225,9 +7227,16 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, } Sema::AssignConvertType -Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, +Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, bool Diagnose, - bool DiagnoseCFAudited) { + bool DiagnoseCFAudited, + bool ConvertRHS) { + // If ConvertRHS is false, we want to leave the caller's RHS untouched. Sadly, + // we can't avoid *all* modifications at the moment, so we need some somewhere + // to put the updated value. + ExprResult LocalRHS = CallerRHS; + ExprResult &RHS = ConvertRHS ? CallerRHS : LocalRHS; + if (getLangOpts().CPlusPlus) { if (!LHSType->isRecordType() && !LHSType->isAtomicType()) { // C++ 5.17p3: If the left operand is not of class type, the @@ -7276,7 +7285,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, CastKind Kind; CXXCastPath Path; CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false); - RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path); + if (ConvertRHS) + RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path); return Compatible; } @@ -7287,6 +7297,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, // // Suppress this for references: C++ 8.5.3p5. if (!LHSType->isReferenceType()) { + // FIXME: We potentially allocate here even if ConvertRHS is false. RHS = DefaultFunctionArrayLvalueConversion(RHS.get()); if (RHS.isInvalid()) return Incompatible; @@ -7303,7 +7314,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, CastKind Kind = CK_Invalid; Sema::AssignConvertType result = - CheckAssignmentConstraints(LHSType, RHS, Kind); + CheckAssignmentConstraints(LHSType, RHS, Kind, ConvertRHS); // C99 6.5.16.1p2: The value of the right operand is converted to the // type of the assignment expression. @@ -7325,7 +7336,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, return Compatible; } - RHS = ImpCastExprToType(E, Ty, Kind); + if (ConvertRHS) + RHS = ImpCastExprToType(E, Ty, Kind); } return result; } |