Skip to content

Commit 0353029

Browse files
[BoundsSafety] Do not merge param/return types if there is no need to
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
1 parent 4e0db49 commit 0353029

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
@@ -3932,21 +3932,6 @@ QualType ASTContext::mergeBoundsSafetyPointerTypes(
39323932
if (OrigDstTy.isNull())
39333933
OrigDstTy = DstTy;
39343934

3935-
// An ugly way to keep va_list typedef in DstTy if the merge type doesn't
3936-
// change.
3937-
// TODO: We need a general way of not stripping sugars.
3938-
QualType DesugaredDstTy;
3939-
if (const auto *TDT = dyn_cast<TypedefType>(DstTy))
3940-
DesugaredDstTy = TDT->desugar();
3941-
else if (const auto *ET = dyn_cast<ElaboratedType>(DstTy))
3942-
DesugaredDstTy = ET->desugar();
3943-
if (!DesugaredDstTy.isNull()) {
3944-
QualType MergeTy = mergeBoundsSafetyPointerTypes(DesugaredDstTy, SrcTy,
3945-
MergeFunctor, OrigDstTy);
3946-
if (MergeTy == DesugaredDstTy)
3947-
return DstTy;
3948-
}
3949-
39503935
// FIXME: a brittle hack to avoid skipping ValueTerminatedType outside
39513936
// this PtrAutoAttr AttributedType.
39523937
bool RecoverPtrAuto = false;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4100,12 +4100,33 @@ static bool mergeFunctionDeclBoundsAttributes(FunctionDecl *New,
41004100
}
41014101
return MergeTy;
41024102
};
4103+
4104+
auto hasBoundsAttributesAtAnyLevel = [](QualType Ty) -> bool {
4105+
while (Ty->isPointerType()) {
4106+
if (!Ty->isUnspecifiedPointerType())
4107+
return true;
4108+
Ty = Ty->getPointeeType();
4109+
}
4110+
return false;
4111+
};
4112+
4113+
auto mergePointersWithAttributes = [&](QualType NewTy,
4114+
QualType OldTy) -> QualType {
4115+
// Do not attempt to merge if there is no need to do so. This will let us
4116+
// keep the sugars used in the new declaration.
4117+
if (!hasBoundsAttributesAtAnyLevel(NewTy) &&
4118+
!hasBoundsAttributesAtAnyLevel(OldTy))
4119+
return NewTy;
4120+
return Self.Context.mergeBoundsSafetyPointerTypes(NewTy, OldTy,
4121+
mergeBoundsAttributes);
4122+
};
4123+
41034124
QualType NewRetTy = New->getReturnType();
41044125
if (NewRetTy->isBoundsAttributedType() ||
41054126
NewRetTy->isValueTerminatedType())
41064127
return false;
4107-
QualType MergeRetTy = Self.Context.mergeBoundsSafetyPointerTypes(
4108-
New->getReturnType(), Old->getReturnType(), mergeBoundsAttributes);
4128+
QualType MergeRetTy =
4129+
mergePointersWithAttributes(New->getReturnType(), Old->getReturnType());
41094130
if (MergeRetTy.isNull())
41104131
return false;
41114132

@@ -4115,9 +4136,8 @@ static bool mergeFunctionDeclBoundsAttributes(FunctionDecl *New,
41154136
if (NewParmTy->isBoundsAttributedType() ||
41164137
NewParmTy->isValueTerminatedType())
41174138
return false;
4118-
QualType MergeParamTy = Self.Context.mergeBoundsSafetyPointerTypes(
4119-
NewParmTy, Old->getParamDecl(i)->getType(),
4120-
mergeBoundsAttributes);
4139+
QualType MergeParamTy =
4140+
mergePointersWithAttributes(NewParmTy, Old->getParamDecl(i)->getType());
41214141
if (MergeParamTy.isNull())
41224142
return false;
41234143
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)