Skip to content

Commit f9dcba2

Browse files
committed
SemaExpr: further tweaks to checkPointerTypesForAssignment
- Don't transform both ltrans and rtrans when one transform could suffice. - Further simplify unneeded code checks that were added to work around the invalid invocation. - Fix formatting in test case.
1 parent ef33bff commit f9dcba2

File tree

2 files changed

+8
-32
lines changed

2 files changed

+8
-32
lines changed

clang/lib/Sema/SemaExpr.cpp

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9014,24 +9014,6 @@ bool Sema::IsInvalidSMECallConversion(QualType FromType, QualType ToType) {
90149014
return FromAttributes != ToAttributes;
90159015
}
90169016

9017-
// Check if we have a conversion between incompatible cmse function pointer
9018-
// types, that is, a conversion between a function pointer with the
9019-
// cmse_nonsecure_call attribute and one without.
9020-
static bool IsInvalidCmseNSCallConversion(Sema &S, QualType FromType,
9021-
QualType ToType) {
9022-
if (const auto *ToFn =
9023-
dyn_cast<FunctionType>(S.Context.getCanonicalType(ToType))) {
9024-
if (const auto *FromFn =
9025-
dyn_cast<FunctionType>(S.Context.getCanonicalType(FromType))) {
9026-
FunctionType::ExtInfo ToEInfo = ToFn->getExtInfo();
9027-
FunctionType::ExtInfo FromEInfo = FromFn->getExtInfo();
9028-
9029-
return ToEInfo.getCmseNSCall() != FromEInfo.getCmseNSCall();
9030-
}
9031-
}
9032-
return false;
9033-
}
9034-
90359017
// checkPointerTypesForAssignment - This is a very tricky routine (despite
90369018
// being closely modeled after the C99 spec:-). The odd characteristic of this
90379019
// routine is it effectively iqnores the qualifiers on the top level pointee.
@@ -9187,15 +9169,17 @@ static AssignConvertType checkPointerTypesForAssignment(Sema &S,
91879169
return AssignConvertType::IncompatibleFunctionPointer;
91889170
return AssignConvertType::IncompatiblePointer;
91899171
}
9172+
// Note: in C++, typesAreCompatible(ltrans, rtrans) will have guaranteed
9173+
// hasSameType, so we can skip further checks.
91909174
const auto *LFT = ltrans->getAs<FunctionType>();
91919175
const auto *RFT = rtrans->getAs<FunctionType>();
91929176
if (!S.getLangOpts().CPlusPlus && LFT && RFT) {
91939177
// The invocation of IsFunctionConversion below will try to transform rtrans
91949178
// to obtain an exact match for ltrans. This should not fail because of
91959179
// mismatches in result type and parameter types, they were already checked
9196-
// by typesAreCompatible above. So we will recreate rtrans using the result
9197-
// type and parameter types from ltrans, but keeping its
9198-
// ExtInfo/ExtProtoInfo.
9180+
// by typesAreCompatible above. So we will recreate rtrans (or where
9181+
// appropriate ltrans) using the result type and parameter types from ltrans
9182+
// (respectively rtrans), but keeping its ExtInfo/ExtProtoInfo.
91999183
const auto *LFPT = dyn_cast<FunctionProtoType>(LFT);
92009184
const auto *RFPT = dyn_cast<FunctionProtoType>(RFT);
92019185
if (LFPT && RFPT) {
@@ -9209,15 +9193,11 @@ static AssignConvertType checkPointerTypesForAssignment(Sema &S,
92099193
LFPT->getParamTypes(), EPI);
92109194
} else if (RFPT) {
92119195
// In this case, we want to retain rtrans as a FunctionProtoType, to keep
9212-
// all of its ExtProtoInfo. To enable an exact match, we recreate ltrans
9213-
// as a FunctionProtoType, using its own info but filling in the parameter
9214-
// types from rtrans.
9196+
// all of its ExtProtoInfo. Transform ltrans instead.
92159197
FunctionProtoType::ExtProtoInfo EPI;
92169198
EPI.ExtInfo = LFT->getExtInfo();
9217-
ltrans = S.Context.getFunctionType(LFT->getReturnType(),
9199+
ltrans = S.Context.getFunctionType(RFPT->getReturnType(),
92189200
RFPT->getParamTypes(), EPI);
9219-
rtrans = S.Context.getFunctionType(
9220-
LFT->getReturnType(), RFPT->getParamTypes(), RFPT->getExtProtoInfo());
92219201
} else {
92229202
rtrans = S.Context.getFunctionNoProtoType(LFT->getReturnType(),
92239203
RFT->getExtInfo());
@@ -9226,10 +9206,6 @@ static AssignConvertType checkPointerTypesForAssignment(Sema &S,
92269206
!S.IsFunctionConversion(rtrans, ltrans))
92279207
return AssignConvertType::IncompatibleFunctionPointer;
92289208
}
9229-
if (IsInvalidCmseNSCallConversion(S, ltrans, rtrans))
9230-
return AssignConvertType::IncompatibleFunctionPointer;
9231-
if (S.IsInvalidSMECallConversion(rtrans, ltrans))
9232-
return AssignConvertType::IncompatibleFunctionPointer;
92339209
return ConvTy;
92349210
}
92359211

clang/test/Sema/incompatible-function-pointer-types-extinfo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ int (*fp3e)(int* __attribute__((noescape))) __attribute__((noreturn,cfi_unchecke
3434

3535
// Case 4: assignment to function with no prototype
3636

37-
int f4 (int);
37+
int f4 (int);
3838
int (*fp4a)(int) = &f4;
3939
int (*fp4b)() = &f4; // proto-error {{incompatible function pointer types}}

0 commit comments

Comments
 (0)