diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 53 |
2 files changed, 39 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index f49d2663953..a0bf324a714 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3705,6 +3705,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, case ICK_Qualification: case ICK_Num_Conversion_Kinds: case ICK_C_Only_Conversion: + case ICK_Incompatible_Pointer_Conversion: llvm_unreachable("Improper second standard conversion"); } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 7b03a62be12..38144a94a14 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -136,7 +136,8 @@ ImplicitConversionRank clang::GetConversionRank(ImplicitConversionKind Kind) { ICR_Exact_Match, // NOTE(gbiv): This may not be completely right -- // it was omitted by the patch that added // ICK_Zero_Event_Conversion - ICR_C_Conversion + ICR_C_Conversion, + ICR_C_Conversion_Extension }; return Rank[(int)Kind]; } @@ -170,7 +171,8 @@ static const char* GetImplicitConversionName(ImplicitConversionKind Kind) { "Transparent Union Conversion", "Writeback conversion", "OpenCL Zero Event Conversion", - "C specific type conversion" + "C specific type conversion", + "Incompatible pointer conversion" }; return Name[Kind]; } @@ -1783,22 +1785,37 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, return false; ExprResult ER = ExprResult{From}; - auto Conv = S.CheckSingleAssignmentConstraints(ToType, ER, - /*Diagnose=*/false, - /*DiagnoseCFAudited=*/false, - /*ConvertRHS=*/false); - if (Conv != Sema::Compatible) + Sema::AssignConvertType Conv = + S.CheckSingleAssignmentConstraints(ToType, ER, + /*Diagnose=*/false, + /*DiagnoseCFAudited=*/false, + /*ConvertRHS=*/false); + ImplicitConversionKind ImplicitConv; + switch (Conv) { + case Sema::Compatible: + ImplicitConv = ICK_C_Only_Conversion; + break; + // For our purposes, discarding qualifiers is just as bad as using an + // incompatible pointer. Note that an IncompatiblePointer conversion can drop + // qualifiers, as well. + case Sema::CompatiblePointerDiscardsQualifiers: + case Sema::IncompatiblePointer: + case Sema::IncompatiblePointerSign: + ImplicitConv = ICK_Incompatible_Pointer_Conversion; + break; + default: return false; + } SCS.setAllToTypes(ToType); // We need to set all three because we want this conversion to rank terribly, // and we don't know what conversions it may overlap with. - SCS.First = ICK_C_Only_Conversion; - SCS.Second = ICK_C_Only_Conversion; - SCS.Third = ICK_C_Only_Conversion; + SCS.First = ImplicitConv; + SCS.Second = ImplicitConv; + SCS.Third = ImplicitConv; return true; } - + static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From, QualType &ToType, @@ -5105,6 +5122,7 @@ static bool CheckConvertedConstantConversions(Sema &S, case ICK_Writeback_Conversion: case ICK_Zero_Event_Conversion: case ICK_C_Only_Conversion: + case ICK_Incompatible_Pointer_Conversion: return false; case ICK_Lvalue_To_Rvalue: @@ -5906,10 +5924,15 @@ Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, /*AllowExplicit*/false); - if (ConversionState.isBad()) { - Match = false; - break; - } + // This function looks for a reasonably-exact match, so we consider + // incompatible pointer conversions to be a failure here. + if (ConversionState.isBad() || + (ConversionState.isStandard() && + ConversionState.Standard.Second == + ICK_Incompatible_Pointer_Conversion)) { + Match = false; + break; + } } // Promote additional arguments to variadic methods. if (Match && Method->isVariadic()) { |