Skip to content

Commit a6385a8

Browse files
authored
[Sema] Refactor IsFunctionConversion (#139172)
A bunch of uses of IsFunctionConversion don't use the third argument and just make a dummy QualType to pass. This splits IsFunctionConversion into 2 functions, one that just takes 2 arguments and does the check, and one that does the actual conversion using the 3rd argument. Both functions can be const and replace current uses appropriately.
1 parent c8539f7 commit a6385a8

File tree

6 files changed

+28
-25
lines changed

6 files changed

+28
-25
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10240,8 +10240,13 @@ class Sema final : public SemaBase {
1024010240
/// Determine whether the conversion from FromType to ToType is a valid
1024110241
/// conversion that strips "noexcept" or "noreturn" off the nested function
1024210242
/// type.
10243-
bool IsFunctionConversion(QualType FromType, QualType ToType,
10244-
QualType &ResultTy);
10243+
bool IsFunctionConversion(QualType FromType, QualType ToType) const;
10244+
10245+
/// Same as `IsFunctionConversion`, but if this would return true, it sets
10246+
/// `ResultTy` to `ToType`.
10247+
bool TryFunctionConversion(QualType FromType, QualType ToType,
10248+
QualType &ResultTy) const;
10249+
1024510250
bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
1024610251
void DiagnoseUseOfDeletedFunction(SourceLocation Loc, SourceRange Range,
1024710252
DeclarationName Name,

clang/lib/Sema/SemaExceptionSpec.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,12 +700,11 @@ bool Sema::handlerCanCatch(QualType HandlerType, QualType ExceptionType) {
700700
// -- a qualification conversion
701701
// -- a function pointer conversion
702702
bool LifetimeConv;
703-
QualType Result;
704703
// FIXME: Should we treat the exception as catchable if a lifetime
705704
// conversion is required?
706705
if (IsQualificationConversion(ExceptionType, HandlerType, false,
707706
LifetimeConv) ||
708-
IsFunctionConversion(ExceptionType, HandlerType, Result))
707+
IsFunctionConversion(ExceptionType, HandlerType))
709708
return true;
710709

711710
// -- a standard pointer conversion [...]

clang/lib/Sema/SemaExpr.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9106,7 +9106,7 @@ static AssignConvertType checkPointerTypesForAssignment(Sema &S,
91069106
diag::warn_typecheck_convert_incompatible_function_pointer_strict,
91079107
Loc) &&
91089108
RHSType->isFunctionPointerType() && LHSType->isFunctionPointerType() &&
9109-
!S.IsFunctionConversion(RHSType, LHSType, RHSType))
9109+
!S.TryFunctionConversion(RHSType, LHSType, RHSType))
91109110
return AssignConvertType::IncompatibleFunctionPointerStrict;
91119111

91129112
// C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or
@@ -9170,8 +9170,7 @@ static AssignConvertType checkPointerTypesForAssignment(Sema &S,
91709170
return AssignConvertType::IncompatibleFunctionPointer;
91719171
return AssignConvertType::IncompatiblePointer;
91729172
}
9173-
if (!S.getLangOpts().CPlusPlus &&
9174-
S.IsFunctionConversion(ltrans, rtrans, ltrans))
9173+
if (!S.getLangOpts().CPlusPlus && S.IsFunctionConversion(ltrans, rtrans))
91759174
return AssignConvertType::IncompatibleFunctionPointer;
91769175
if (IsInvalidCmseNSCallConversion(S, ltrans, rtrans))
91779176
return AssignConvertType::IncompatibleFunctionPointer;

clang/lib/Sema/SemaOverload.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,8 +1881,15 @@ ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType,
18811881
return PerformImplicitConversion(From, ToType, ICS, Action);
18821882
}
18831883

1884-
bool Sema::IsFunctionConversion(QualType FromType, QualType ToType,
1885-
QualType &ResultTy) {
1884+
bool Sema::TryFunctionConversion(QualType FromType, QualType ToType,
1885+
QualType &ResultTy) const {
1886+
bool Changed = IsFunctionConversion(FromType, ToType);
1887+
if (Changed)
1888+
ResultTy = ToType;
1889+
return Changed;
1890+
}
1891+
1892+
bool Sema::IsFunctionConversion(QualType FromType, QualType ToType) const {
18861893
if (Context.hasSameUnqualifiedType(FromType, ToType))
18871894
return false;
18881895

@@ -1993,7 +2000,6 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType,
19932000
assert(QualType(FromFn, 0).isCanonical());
19942001
if (QualType(FromFn, 0) != CanTo) return false;
19952002

1996-
ResultTy = ToType;
19972003
return true;
19982004
}
19992005

@@ -2232,11 +2238,10 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
22322238
// we can sometimes resolve &foo<int> regardless of ToType, so check
22332239
// if the type matches (identity) or we are converting to bool
22342240
if (!S.Context.hasSameUnqualifiedType(
2235-
S.ExtractUnqualifiedFunctionType(ToType), FromType)) {
2236-
QualType resultTy;
2241+
S.ExtractUnqualifiedFunctionType(ToType), FromType)) {
22372242
// if the function type matches except for [[noreturn]], it's ok
22382243
if (!S.IsFunctionConversion(FromType,
2239-
S.ExtractUnqualifiedFunctionType(ToType), resultTy))
2244+
S.ExtractUnqualifiedFunctionType(ToType)))
22402245
// otherwise, only a boolean conversion is standard
22412246
if (!ToType->isBooleanType())
22422247
return false;
@@ -2476,7 +2481,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
24762481
// The third conversion can be a function pointer conversion or a
24772482
// qualification conversion (C++ [conv.fctptr], [conv.qual]).
24782483
bool ObjCLifetimeConversion;
2479-
if (S.IsFunctionConversion(FromType, ToType, FromType)) {
2484+
if (S.TryFunctionConversion(FromType, ToType, FromType)) {
24802485
// Function pointer conversions (removing 'noexcept') including removal of
24812486
// 'noreturn' (Clang extension).
24822487
SCS.Third = ICK_Function_Conversion;
@@ -5033,7 +5038,6 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
50335038
// Check for standard conversions we can apply to pointers: derived-to-base
50345039
// conversions, ObjC pointer conversions, and function pointer conversions.
50355040
// (Qualification conversions are checked last.)
5036-
QualType ConvertedT2;
50375041
if (UnqualT1 == UnqualT2) {
50385042
// Nothing to do.
50395043
} else if (isCompleteType(Loc, OrigT2) &&
@@ -5044,7 +5048,7 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
50445048
Context.canBindObjCObjectType(UnqualT1, UnqualT2))
50455049
Conv |= ReferenceConversions::ObjC;
50465050
else if (UnqualT2->isFunctionType() &&
5047-
IsFunctionConversion(UnqualT2, UnqualT1, ConvertedT2)) {
5051+
IsFunctionConversion(UnqualT2, UnqualT1)) {
50485052
Conv |= ReferenceConversions::Function;
50495053
// No need to check qualifiers; function types don't have them.
50505054
return Ref_Compatible;
@@ -13426,9 +13430,8 @@ class AddressOfFunctionResolver {
1342613430

1342713431
private:
1342813432
bool candidateHasExactlyCorrectType(const FunctionDecl *FD) {
13429-
QualType Discard;
1343013433
return Context.hasSameUnqualifiedType(TargetFunctionType, FD->getType()) ||
13431-
S.IsFunctionConversion(FD->getType(), TargetFunctionType, Discard);
13434+
S.IsFunctionConversion(FD->getType(), TargetFunctionType);
1343213435
}
1343313436

1343413437
/// \return true if A is considered a better overload candidate for the

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7665,9 +7665,8 @@ ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
76657665
QualType DestExprType = ParamType.getNonLValueExprType(Context);
76667666
if (!Context.hasSameType(RefExpr.get()->getType(), DestExprType)) {
76677667
CastKind CK;
7668-
QualType Ignored;
76697668
if (Context.hasSimilarType(RefExpr.get()->getType(), DestExprType) ||
7670-
IsFunctionConversion(RefExpr.get()->getType(), DestExprType, Ignored)) {
7669+
IsFunctionConversion(RefExpr.get()->getType(), DestExprType)) {
76717670
CK = CK_NoOp;
76727671
} else if (ParamType->isVoidPointerType() &&
76737672
RefExpr.get()->getType()->isPointerType()) {

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,7 +1333,7 @@ bool Sema::isSameOrCompatibleFunctionType(QualType P, QualType A) {
13331333
return Context.hasSameType(P, A);
13341334

13351335
// Noreturn and noexcept adjustment.
1336-
if (QualType AdjustedParam; IsFunctionConversion(P, A, AdjustedParam))
1336+
if (QualType AdjustedParam; TryFunctionConversion(P, A, AdjustedParam))
13371337
P = AdjustedParam;
13381338

13391339
// FIXME: Compatible calling conventions.
@@ -3732,8 +3732,7 @@ CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info,
37323732
// FIXME: Resolve core issue (no number yet): if the original P is a
37333733
// reference type and the transformed A is function type "noexcept F",
37343734
// the deduced A can be F.
3735-
QualType Tmp;
3736-
if (A->isFunctionType() && S.IsFunctionConversion(A, DeducedA, Tmp))
3735+
if (A->isFunctionType() && S.IsFunctionConversion(A, DeducedA))
37373736
return TemplateDeductionResult::Success;
37383737

37393738
Qualifiers AQuals = A.getQualifiers();
@@ -3770,11 +3769,10 @@ CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info,
37703769
// Also allow conversions which merely strip __attribute__((noreturn)) from
37713770
// function types (recursively).
37723771
bool ObjCLifetimeConversion = false;
3773-
QualType ResultTy;
37743772
if ((A->isAnyPointerType() || A->isMemberPointerType()) &&
37753773
(S.IsQualificationConversion(A, DeducedA, false,
37763774
ObjCLifetimeConversion) ||
3777-
S.IsFunctionConversion(A, DeducedA, ResultTy)))
3775+
S.IsFunctionConversion(A, DeducedA)))
37783776
return TemplateDeductionResult::Success;
37793777

37803778
// - If P is a class and P has the form simple-template-id, then the

0 commit comments

Comments
 (0)