[clang] a6385a8 - [Sema] Refactor IsFunctionConversion (#139172)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 9 10:19:55 PDT 2025
Author: PiJoules
Date: 2025-05-09T10:19:52-07:00
New Revision: a6385a87a2e5537f0790494ebe8bb4c3cc9506b9
URL: https://github.com/llvm/llvm-project/commit/a6385a87a2e5537f0790494ebe8bb4c3cc9506b9
DIFF: https://github.com/llvm/llvm-project/commit/a6385a87a2e5537f0790494ebe8bb4c3cc9506b9.diff
LOG: [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.
Added:
Modified:
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaExceptionSpec.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaTemplateDeduction.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index c02e827773341..6ea7ee281e14d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10240,8 +10240,13 @@ class Sema final : public SemaBase {
/// Determine whether the conversion from FromType to ToType is a valid
/// conversion that strips "noexcept" or "noreturn" off the nested function
/// type.
- bool IsFunctionConversion(QualType FromType, QualType ToType,
- QualType &ResultTy);
+ bool IsFunctionConversion(QualType FromType, QualType ToType) const;
+
+ /// Same as `IsFunctionConversion`, but if this would return true, it sets
+ /// `ResultTy` to `ToType`.
+ bool TryFunctionConversion(QualType FromType, QualType ToType,
+ QualType &ResultTy) const;
+
bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
void DiagnoseUseOfDeletedFunction(SourceLocation Loc, SourceRange Range,
DeclarationName Name,
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index aaa2bb22565e4..c83eab53891ca 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -700,12 +700,11 @@ bool Sema::handlerCanCatch(QualType HandlerType, QualType ExceptionType) {
// -- a qualification conversion
// -- a function pointer conversion
bool LifetimeConv;
- QualType Result;
// FIXME: Should we treat the exception as catchable if a lifetime
// conversion is required?
if (IsQualificationConversion(ExceptionType, HandlerType, false,
LifetimeConv) ||
- IsFunctionConversion(ExceptionType, HandlerType, Result))
+ IsFunctionConversion(ExceptionType, HandlerType))
return true;
// -- a standard pointer conversion [...]
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index deb8d2edfc5c9..18d822c41bd37 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -9106,7 +9106,7 @@ static AssignConvertType checkPointerTypesForAssignment(Sema &S,
diag::warn_typecheck_convert_incompatible_function_pointer_strict,
Loc) &&
RHSType->isFunctionPointerType() && LHSType->isFunctionPointerType() &&
- !S.IsFunctionConversion(RHSType, LHSType, RHSType))
+ !S.TryFunctionConversion(RHSType, LHSType, RHSType))
return AssignConvertType::IncompatibleFunctionPointerStrict;
// C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or
@@ -9170,8 +9170,7 @@ static AssignConvertType checkPointerTypesForAssignment(Sema &S,
return AssignConvertType::IncompatibleFunctionPointer;
return AssignConvertType::IncompatiblePointer;
}
- if (!S.getLangOpts().CPlusPlus &&
- S.IsFunctionConversion(ltrans, rtrans, ltrans))
+ if (!S.getLangOpts().CPlusPlus && S.IsFunctionConversion(ltrans, rtrans))
return AssignConvertType::IncompatibleFunctionPointer;
if (IsInvalidCmseNSCallConversion(S, ltrans, rtrans))
return AssignConvertType::IncompatibleFunctionPointer;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index d3ee9989c73ed..e20a41c10ccaa 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1881,8 +1881,15 @@ ExprResult Sema::PerformImplicitConversion(Expr *From, QualType ToType,
return PerformImplicitConversion(From, ToType, ICS, Action);
}
-bool Sema::IsFunctionConversion(QualType FromType, QualType ToType,
- QualType &ResultTy) {
+bool Sema::TryFunctionConversion(QualType FromType, QualType ToType,
+ QualType &ResultTy) const {
+ bool Changed = IsFunctionConversion(FromType, ToType);
+ if (Changed)
+ ResultTy = ToType;
+ return Changed;
+}
+
+bool Sema::IsFunctionConversion(QualType FromType, QualType ToType) const {
if (Context.hasSameUnqualifiedType(FromType, ToType))
return false;
@@ -1993,7 +2000,6 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType,
assert(QualType(FromFn, 0).isCanonical());
if (QualType(FromFn, 0) != CanTo) return false;
- ResultTy = ToType;
return true;
}
@@ -2232,11 +2238,10 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
// we can sometimes resolve &foo<int> regardless of ToType, so check
// if the type matches (identity) or we are converting to bool
if (!S.Context.hasSameUnqualifiedType(
- S.ExtractUnqualifiedFunctionType(ToType), FromType)) {
- QualType resultTy;
+ S.ExtractUnqualifiedFunctionType(ToType), FromType)) {
// if the function type matches except for [[noreturn]], it's ok
if (!S.IsFunctionConversion(FromType,
- S.ExtractUnqualifiedFunctionType(ToType), resultTy))
+ S.ExtractUnqualifiedFunctionType(ToType)))
// otherwise, only a boolean conversion is standard
if (!ToType->isBooleanType())
return false;
@@ -2476,7 +2481,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
// The third conversion can be a function pointer conversion or a
// qualification conversion (C++ [conv.fctptr], [conv.qual]).
bool ObjCLifetimeConversion;
- if (S.IsFunctionConversion(FromType, ToType, FromType)) {
+ if (S.TryFunctionConversion(FromType, ToType, FromType)) {
// Function pointer conversions (removing 'noexcept') including removal of
// 'noreturn' (Clang extension).
SCS.Third = ICK_Function_Conversion;
@@ -5033,7 +5038,6 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
// Check for standard conversions we can apply to pointers: derived-to-base
// conversions, ObjC pointer conversions, and function pointer conversions.
// (Qualification conversions are checked last.)
- QualType ConvertedT2;
if (UnqualT1 == UnqualT2) {
// Nothing to do.
} else if (isCompleteType(Loc, OrigT2) &&
@@ -5044,7 +5048,7 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
Context.canBindObjCObjectType(UnqualT1, UnqualT2))
Conv |= ReferenceConversions::ObjC;
else if (UnqualT2->isFunctionType() &&
- IsFunctionConversion(UnqualT2, UnqualT1, ConvertedT2)) {
+ IsFunctionConversion(UnqualT2, UnqualT1)) {
Conv |= ReferenceConversions::Function;
// No need to check qualifiers; function types don't have them.
return Ref_Compatible;
@@ -13426,9 +13430,8 @@ class AddressOfFunctionResolver {
private:
bool candidateHasExactlyCorrectType(const FunctionDecl *FD) {
- QualType Discard;
return Context.hasSameUnqualifiedType(TargetFunctionType, FD->getType()) ||
- S.IsFunctionConversion(FD->getType(), TargetFunctionType, Discard);
+ S.IsFunctionConversion(FD->getType(), TargetFunctionType);
}
/// \return true if A is considered a better overload candidate for the
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 94f4c1c46c1fb..2ba69c87d95e3 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7665,9 +7665,8 @@ ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
QualType DestExprType = ParamType.getNonLValueExprType(Context);
if (!Context.hasSameType(RefExpr.get()->getType(), DestExprType)) {
CastKind CK;
- QualType Ignored;
if (Context.hasSimilarType(RefExpr.get()->getType(), DestExprType) ||
- IsFunctionConversion(RefExpr.get()->getType(), DestExprType, Ignored)) {
+ IsFunctionConversion(RefExpr.get()->getType(), DestExprType)) {
CK = CK_NoOp;
} else if (ParamType->isVoidPointerType() &&
RefExpr.get()->getType()->isPointerType()) {
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index ee1ef84fa4fbd..5dc06ebc2a235 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -1333,7 +1333,7 @@ bool Sema::isSameOrCompatibleFunctionType(QualType P, QualType A) {
return Context.hasSameType(P, A);
// Noreturn and noexcept adjustment.
- if (QualType AdjustedParam; IsFunctionConversion(P, A, AdjustedParam))
+ if (QualType AdjustedParam; TryFunctionConversion(P, A, AdjustedParam))
P = AdjustedParam;
// FIXME: Compatible calling conventions.
@@ -3732,8 +3732,7 @@ CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info,
// FIXME: Resolve core issue (no number yet): if the original P is a
// reference type and the transformed A is function type "noexcept F",
// the deduced A can be F.
- QualType Tmp;
- if (A->isFunctionType() && S.IsFunctionConversion(A, DeducedA, Tmp))
+ if (A->isFunctionType() && S.IsFunctionConversion(A, DeducedA))
return TemplateDeductionResult::Success;
Qualifiers AQuals = A.getQualifiers();
@@ -3770,11 +3769,10 @@ CheckOriginalCallArgDeduction(Sema &S, TemplateDeductionInfo &Info,
// Also allow conversions which merely strip __attribute__((noreturn)) from
// function types (recursively).
bool ObjCLifetimeConversion = false;
- QualType ResultTy;
if ((A->isAnyPointerType() || A->isMemberPointerType()) &&
(S.IsQualificationConversion(A, DeducedA, false,
ObjCLifetimeConversion) ||
- S.IsFunctionConversion(A, DeducedA, ResultTy)))
+ S.IsFunctionConversion(A, DeducedA)))
return TemplateDeductionResult::Success;
// - If P is a class and P has the form simple-template-id, then the
More information about the cfe-commits
mailing list