Skip to content

Commit 8835b75

Browse files
[BoundsSafety] Do not merge param/return types if there is no need to (#10934)
If pointers don't have any interesting attributes, there is no need to attempt to merge the types, and we can keep the type unchanged. This will let us keep the sugars used in the new declaration. rdar://153579566 (cherry picked from commit 0353029)
1 parent db18f41 commit 8835b75

File tree

4 files changed

+36
-20
lines changed

4 files changed

+36
-20
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3707,21 +3707,6 @@ QualType ASTContext::mergeBoundsSafetyPointerTypes(
37073707
if (OrigDstTy.isNull())
37083708
OrigDstTy = DstTy;
37093709

3710-
// An ugly way to keep va_list typedef in DstTy if the merge type doesn't
3711-
// change.
3712-
// TODO: We need a general way of not stripping sugars.
3713-
QualType DesugaredDstTy;
3714-
if (const auto *TDT = dyn_cast<TypedefType>(DstTy))
3715-
DesugaredDstTy = TDT->desugar();
3716-
else if (const auto *ET = dyn_cast<ElaboratedType>(DstTy))
3717-
DesugaredDstTy = ET->desugar();
3718-
if (!DesugaredDstTy.isNull()) {
3719-
QualType MergeTy = mergeBoundsSafetyPointerTypes(DesugaredDstTy, SrcTy,
3720-
MergeFunctor, OrigDstTy);
3721-
if (MergeTy == DesugaredDstTy)
3722-
return DstTy;
3723-
}
3724-
37253710
// FIXME: a brittle hack to avoid skipping ValueTerminatedType outside
37263711
// this PtrAutoAttr AttributedType.
37273712
bool RecoverPtrAuto = false;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4040,12 +4040,33 @@ static bool mergeFunctionDeclBoundsAttributes(FunctionDecl *New,
40404040
}
40414041
return MergeTy;
40424042
};
4043+
4044+
auto hasBoundsAttributesAtAnyLevel = [](QualType Ty) -> bool {
4045+
while (Ty->isPointerType()) {
4046+
if (!Ty->isUnspecifiedPointerType())
4047+
return true;
4048+
Ty = Ty->getPointeeType();
4049+
}
4050+
return false;
4051+
};
4052+
4053+
auto mergePointersWithAttributes = [&](QualType NewTy,
4054+
QualType OldTy) -> QualType {
4055+
// Do not attempt to merge if there is no need to do so. This will let us
4056+
// keep the sugars used in the new declaration.
4057+
if (!hasBoundsAttributesAtAnyLevel(NewTy) &&
4058+
!hasBoundsAttributesAtAnyLevel(OldTy))
4059+
return NewTy;
4060+
return Self.Context.mergeBoundsSafetyPointerTypes(NewTy, OldTy,
4061+
mergeBoundsAttributes);
4062+
};
4063+
40434064
QualType NewRetTy = New->getReturnType();
40444065
if (NewRetTy->isBoundsAttributedType() ||
40454066
NewRetTy->isValueTerminatedType())
40464067
return false;
4047-
QualType MergeRetTy = Self.Context.mergeBoundsSafetyPointerTypes(
4048-
New->getReturnType(), Old->getReturnType(), mergeBoundsAttributes);
4068+
QualType MergeRetTy =
4069+
mergePointersWithAttributes(New->getReturnType(), Old->getReturnType());
40494070
if (MergeRetTy.isNull())
40504071
return false;
40514072

@@ -4055,9 +4076,8 @@ static bool mergeFunctionDeclBoundsAttributes(FunctionDecl *New,
40554076
if (NewParmTy->isBoundsAttributedType() ||
40564077
NewParmTy->isValueTerminatedType())
40574078
return false;
4058-
QualType MergeParamTy = Self.Context.mergeBoundsSafetyPointerTypes(
4059-
NewParmTy, Old->getParamDecl(i)->getType(),
4060-
mergeBoundsAttributes);
4079+
QualType MergeParamTy =
4080+
mergePointersWithAttributes(NewParmTy, Old->getParamDecl(i)->getType());
40614081
if (MergeParamTy.isNull())
40624082
return false;
40634083
if (const auto *CATy = MergeParamTy->getAs<CountAttributedType>()) {

clang/test/BoundsSafety/AST/system-header-merge-bounds-attributed.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
// CHECK: FunctionDecl {{.+}} eb
3030
// CHECK: |-ParmVarDecl {{.+}} eb_p 'void *'
3131
// CHECK: `-ParmVarDecl {{.+}} end 'void *'
32+
// CHECK: FunctionDecl {{.+}} cb_array
33+
// CHECK: |-ParmVarDecl {{.+}} array 'int *'
34+
// CHECK: `-ParmVarDecl {{.+}} len 'int'
3235

3336

3437
// Check if we can override them.
@@ -39,6 +42,7 @@ void cb_out_count(int *__counted_by(*len) cb_out_len_p, int *len);
3942
void cbn(int *__counted_by_or_null(len) cbn_p, int len);
4043
void sb(void *__sized_by(size) sb_p, int size);
4144
void eb(void *__ended_by(end) eb_p, void *end);
45+
void cb_array(int array[__counted_by(len)], int len);
4246

4347
// CHECK: FunctionDecl {{.+}} prev {{.+}} cb_in
4448
// CHECK: |-ParmVarDecl {{.+}} cb_in_p 'int *{{.*}} __counted_by(len)'
@@ -58,6 +62,9 @@ void eb(void *__ended_by(end) eb_p, void *end);
5862
// CHECK: FunctionDecl {{.+}} prev {{.+}} eb
5963
// CHECK: |-ParmVarDecl {{.+}} used eb_p 'void *{{.*}} __ended_by(end)'
6064
// CHECK: `-ParmVarDecl {{.+}} used end 'void *{{.*}} /* __started_by(eb_p) */ '
65+
// CHECK: FunctionDecl {{.+}} prev {{.+}} cb_array
66+
// CHECK: |-ParmVarDecl {{.+}} array 'int *{{.*}} __counted_by(len)'
67+
// CHECK: `-ParmVarDecl {{.+}} used len 'int'
6168

6269

6370
// Check if the attributes are merged.
@@ -82,3 +89,6 @@ void eb(void *__ended_by(end) eb_p, void *end);
8289
// CHECK: FunctionDecl {{.+}} prev {{.+}} eb
8390
// CHECK: |-ParmVarDecl {{.+}} used eb_p 'void *{{.*}} __ended_by(end)'
8491
// CHECK: `-ParmVarDecl {{.+}} used end 'void *{{.*}} /* __started_by(eb_p) */ '
92+
// CHECK: FunctionDecl {{.+}} prev {{.+}} cb_array
93+
// CHECK: |-ParmVarDecl {{.+}} array 'int *{{.*}} __counted_by(len)'
94+
// CHECK: `-ParmVarDecl {{.+}} used len 'int'

clang/test/BoundsSafety/AST/system-header-merge-bounds-attributed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ void cb_out_count(int *cb_out_len_p, int *len);
66
void cbn(int *cbn_p, int len);
77
void sb(void *sb_p, int size);
88
void eb(void *eb_p, void *end);
9+
void cb_array(int array[], int len);

0 commit comments

Comments
 (0)