Skip to content

Commit 1a6869c

Browse files
committed
address review comments and add some more test coverage
1 parent 641520a commit 1a6869c

File tree

8 files changed

+48
-36
lines changed

8 files changed

+48
-36
lines changed

clang/include/clang/AST/TypeBase.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9006,10 +9006,9 @@ inline bool Type::isSafePointerType() const {
90069006
}
90079007

90089008
inline bool Type::isImplicitSafePointerType() const {
9009-
if (auto AT = this->getAs<AttributedType>()) {
9009+
if (const auto *AT = this->getAs<AttributedType>()) {
90109010
if (AT->getAttrKind() == attr::PtrAutoAttr) {
9011-
assert(isSafePointerType());
9012-
return true;
9011+
return isSafePointerType();
90139012
}
90149013
return AT->getEquivalentType()->isImplicitSafePointerType();
90159014
}

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,7 @@ class Sema final : public SemaBase {
12031203
bool findMacroSpelling(SourceLocation &loc, StringRef name);
12041204

12051205
/// Calls \c Lexer::getLocForEndOfToken()
1206-
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0) const;
1206+
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0);
12071207

12081208
/// Calls \c Lexer::findNextToken() to find the next token, and if the
12091209
/// locations of both ends of the token can be resolved it return that
@@ -2815,7 +2815,7 @@ class Sema final : public SemaBase {
28152815
/// Emit fix-it updating BTy to have the same CountAttributedType kind as ATy.
28162816
void fixCountAttributedTypeKind(Sema::SemaDiagnosticBuilder &D,
28172817
const CountAttributedType *ATy,
2818-
const CountAttributedType *BTy) const;
2818+
const CountAttributedType *BTy);
28192819

28202820
/// Used to record or retrieve if a VarDecl/FieldDecl has a BoundsSafety FixIt
28212821
/// emitted on it. The primary use case for this is preventing emitting

clang/include/clang/Sema/SemaFixItUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ class BoundsSafetyFixItUtils {
158158

159159
static void fixCountAttributedTypeLocsInFunctionSignature(
160160
Sema &S, Sema::SemaDiagnosticBuilder &D, QualType QA, QualType QB,
161-
FunctionDecl *ADecl, FunctionDecl *BDecl, bool ExprMismatch,
161+
const FunctionDecl *ADecl, FunctionDecl *BDecl, bool ExprMismatch,
162162
bool KindMismatch);
163163

164164
private:

clang/lib/Sema/Sema.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ bool Sema::isCXXSafeBuffersBoundsSafetyInteropEnabledAt(
9494
}
9595
/* TO_UPSTREAM(BoundsSafety) OFF */
9696

97-
SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) const {
97+
SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) {
9898
return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
9999
}
100100

clang/lib/Sema/SemaBoundsSafety.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ bool Sema::CheckCountedByAttrOnField(FieldDecl *FD, Expr *E, bool CountInBytes,
272272

273273
/* TO_UPSTREAM(BoundsSafety) ON*/
274274
static SourceRange SourceRangeFor(const CountAttributedType *CATy,
275-
const Sema &S, bool AttrNameOnly) {
275+
Sema &S, bool AttrNameOnly) {
276276
// Note: This implementation relies on `CountAttributedType` being unique.
277277
// E.g.:
278278
//
@@ -833,7 +833,7 @@ bool Sema::BoundsSafetyCheckCountAttributedTypeHasConstantCountForAssignmentOp(
833833

834834
void Sema::fixCountAttributedTypeKind(Sema::SemaDiagnosticBuilder &D,
835835
const CountAttributedType *ATy,
836-
const CountAttributedType *BTy) const {
836+
const CountAttributedType *BTy) {
837837
SourceRange SR = SourceRangeFor(BTy, *this, /*AttrNameOnly=*/true);
838838
if (SR.isInvalid()) {
839839
return;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3743,9 +3743,9 @@ static void adjustDeclContextForDeclaratorDecl(DeclaratorDecl *NewD,
37433743

37443744
/* TO_UPSTREAM(BoundsSafety) ON*/
37453745
// FIXME: Rename to something more accurate
3746-
struct TransposeDynamicBoundsExpr
3747-
: public TreeTransform<TransposeDynamicBoundsExpr> {
3748-
using BaseClass = TreeTransform<TransposeDynamicBoundsExpr>;
3746+
struct CheckSameParameterNames
3747+
: public TreeTransform<CheckSameParameterNames> {
3748+
using BaseClass = TreeTransform<CheckSameParameterNames>;
37493749

37503750
FunctionDecl *NewFD;
37513751
bool Success = true;
@@ -3761,12 +3761,12 @@ struct TransposeDynamicBoundsExpr
37613761
if (Invalid)
37623762
return false;
37633763

3764-
TransposeDynamicBoundsExpr Checker(SemaRef, NewFD);
3764+
CheckSameParameterNames Checker(SemaRef, NewFD);
37653765
Checker.TransformExpr(E);
37663766
return Checker.Success;
37673767
}
37683768

3769-
TransposeDynamicBoundsExpr(Sema &SemaRef, FunctionDecl *NewFD)
3769+
CheckSameParameterNames(Sema &SemaRef, FunctionDecl *NewFD)
37703770
: BaseClass(SemaRef), NewFD(NewFD) {}
37713771

37723772
ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
@@ -3788,20 +3788,19 @@ struct TransposeDynamicBoundsExpr
37883788
}
37893789
};
37903790

3791-
struct TransposeDynamicBoundsExprForReal
3792-
: public TreeTransform<TransposeDynamicBoundsExprForReal> {
3793-
using BaseClass = TreeTransform<TransposeDynamicBoundsExprForReal>;
3791+
struct TransposeDynamicBoundsExpr
3792+
: public TreeTransform<TransposeDynamicBoundsExpr> {
3793+
using BaseClass = TreeTransform<TransposeDynamicBoundsExpr>;
37943794

37953795
FunctionDecl *NewFD;
3796-
bool Success = true;
37973796

37983797
/// Rewrite the expr `E` in the context of `NewFD`.
37993798
/// If `E` refers to any function parameters, the rewritten version will refer
38003799
/// to the corresponding parameters in `NewFD`.
38013800
static bool Rewrite(Sema &SemaRef, FunctionDecl *NewFD, Expr *E,
38023801
std::string &Result) {
38033802

3804-
TransposeDynamicBoundsExprForReal Rewriter(SemaRef, NewFD);
3803+
TransposeDynamicBoundsExpr Rewriter(SemaRef, NewFD);
38053804
ExprResult ExprRes = Rewriter.TransformExpr(E);
38063805
if (ExprRes.isInvalid())
38073806
return false;
@@ -3812,16 +3811,15 @@ struct TransposeDynamicBoundsExprForReal
38123811
return true;
38133812
}
38143813

3815-
TransposeDynamicBoundsExprForReal(Sema &SemaRef, FunctionDecl *NewFD)
3814+
TransposeDynamicBoundsExpr(Sema &SemaRef, FunctionDecl *NewFD)
38163815
: BaseClass(SemaRef), NewFD(NewFD) {}
38173816

38183817
ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
3819-
ASTContext &ctx = SemaRef.getASTContext();
3820-
assert(isa<ParmVarDecl>(E->getDecl()));
3821-
auto *OldParm = cast<ParmVarDecl>(E->getDecl());
3818+
const ASTContext &ctx = SemaRef.getASTContext();
3819+
const auto *OldParm = cast<ParmVarDecl>(E->getDecl());
38223820
auto *NewParm = NewFD->getParamDecl(OldParm->getFunctionScopeIndex());
38233821
if (!ctx.hasSameType(OldParm->getType(), NewParm->getType()))
3824-
return {};
3822+
return ExprError();
38253823
return DeclRefExpr::Create(ctx, NestedNameSpecifierLoc(), SourceLocation(),
38263824
NewParm, false, SourceLocation(),
38273825
NewParm->getType(), E->getValueKind());
@@ -3893,7 +3891,7 @@ static void fixBoundsSafetyTypeLocs(Sema &S, Sema::SemaDiagnosticBuilder &D,
38933891
KS << "__bidi_indexable";
38943892
} else if (auto DCPTA = QA->getAs<CountAttributedType>()) {
38953893
std::string Rewritten;
3896-
if (!TransposeDynamicBoundsExpr::Check(S, BDecl, DCPTA->getCountExpr(),
3894+
if (!CheckSameParameterNames::Check(S, BDecl, DCPTA->getCountExpr(),
38973895
Rewritten))
38983896
return;
38993897
const char *Keyword =
@@ -3904,7 +3902,7 @@ static void fixBoundsSafetyTypeLocs(Sema &S, Sema::SemaDiagnosticBuilder &D,
39043902
KS << '(' << Rewritten << ')';
39053903
} else if (auto EndPointer = GetEndPointer(QA)) {
39063904
std::string Rewritten;
3907-
if (!TransposeDynamicBoundsExpr::Check(S, BDecl, EndPointer, Rewritten))
3905+
if (!CheckSameParameterNames::Check(S, BDecl, EndPointer, Rewritten))
39083906
return;
39093907
KS << "__ended_by(" << Rewritten << ')';
39103908
} else {
@@ -3931,10 +3929,10 @@ static void fixBoundsSafetyTypeLocs(Sema &S, Sema::SemaDiagnosticBuilder &D,
39313929
/// to be called once for each direction.
39323930
void BoundsSafetyFixItUtils::fixCountAttributedTypeLocsInFunctionSignature(
39333931
Sema &S, Sema::SemaDiagnosticBuilder &D, QualType QA, QualType QB,
3934-
FunctionDecl *ADecl, FunctionDecl *BDecl, bool ExprMismatch,
3932+
const FunctionDecl *ADecl, FunctionDecl *BDecl, bool ExprMismatch,
39353933
bool KindMismatch) {
3936-
auto *ATy = QA->getAs<CountAttributedType>();
3937-
auto *BTy = QB->getAs<CountAttributedType>();
3934+
const auto *ATy = QA->getAs<CountAttributedType>();
3935+
const auto *BTy = QB->getAs<CountAttributedType>();
39383936
assert(ATy && BTy);
39393937
if (!ATy || !BTy)
39403938
return;
@@ -3944,7 +3942,7 @@ void BoundsSafetyFixItUtils::fixCountAttributedTypeLocsInFunctionSignature(
39443942

39453943
if (ExprMismatch) {
39463944
std::string Rewritten;
3947-
if (!TransposeDynamicBoundsExprForReal::Rewrite(
3945+
if (!TransposeDynamicBoundsExpr::Rewrite(
39483946
S, BDecl, ATy->getCountExpr(), Rewritten))
39493947
return; // don't emit a KindMismatch fix-it either if this fails
39503948
D << FixItHint::CreateReplacement(BTy->getCountExpr()->getSourceRange(),
@@ -3979,8 +3977,8 @@ static void fixBoundsSafetyFunctionDecl(Sema &S, Sema::SemaDiagnosticBuilder &D,
39793977
}
39803978
}
39813979

3982-
static bool diagnoseConflictingAllocSizeAttribute(FunctionDecl *New,
3983-
FunctionDecl *Old,
3980+
static bool diagnoseConflictingAllocSizeAttribute(const FunctionDecl *New,
3981+
const FunctionDecl *Old,
39843982
Sema &Self) {
39853983
// System headers that haven't adopted bounds safety are allowed to break
39863984
// the rules for compatibility reasons, since errors there are hard to fix.
@@ -3991,8 +3989,8 @@ static bool diagnoseConflictingAllocSizeAttribute(FunctionDecl *New,
39913989
// return types. Merging of attributes is done after type checking, but we
39923990
// want to emit the root cause of the type error rather than an error for
39933991
// mismatcing (implicit) return types.
3994-
if (auto OldASA = Old->getAttr<AllocSizeAttr>()) {
3995-
if (auto NewASA = New->getAttr<AllocSizeAttr>()) {
3992+
if (const auto *OldASA = Old->getAttr<AllocSizeAttr>()) {
3993+
if (const auto *NewASA = New->getAttr<AllocSizeAttr>()) {
39963994
if (!OldASA->getElemSizeParam().equals(NewASA->getElemSizeParam()) ||
39973995
!OldASA->getNumElemsParam().equals(NewASA->getNumElemsParam())) {
39983996
Self.Diag(NewASA->getLoc(), diag::err_mismatched_alloc_size)

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6559,6 +6559,7 @@ class MakeStartedByPointerType
65596559

65606560
class ConstructDynamicRangePointerType :
65616561
public ConstructDynamicBoundType<ConstructDynamicRangePointerType> {
6562+
using BaseClass = ConstructDynamicBoundType<ConstructDynamicRangePointerType>;
65626563
std::optional<TypeCoupledDeclRefInfo> StartPtrInfo;
65636564

65646565
public:
@@ -6647,7 +6648,7 @@ class ConstructDynamicRangePointerType :
66476648
ConstructedType = RetTy->getAs<BoundsAttributedType>();
66486649
return RetTy;
66496650
}
6650-
return VisitDynamicRangePointerType(T);
6651+
return BaseClass::VisitDynamicRangePointerType(T);
66516652
}
66526653

66536654
QualType DiagnoseConflictingType(const CountAttributedType *T) {

clang/test/BoundsSafety/Sema/ptrs-with-multiple-range-attrs.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
// RUN: %clang_cc1 -fsyntax-only -fexperimental-bounds-safety-attributes -x c++ -verify=expected,cxx %s
55
// RUN: %clang_cc1 -fsyntax-only -fexperimental-bounds-safety-attributes -x objective-c -verify=expected,c %s
66
// RUN: %clang_cc1 -fsyntax-only -fexperimental-bounds-safety-attributes -x objective-c++ -verify=expected,cxx %s
7+
//
8+
// RUN: not %clang_cc1 -fsyntax-only -fbounds-safety -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s --implicit-check-not 'fix-it:"'
9+
// RUN: not %clang_cc1 -fsyntax-only -fexperimental-bounds-safety-attributes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s --implicit-check-not 'fix-it:"'
710

811
#include <ptrcheck.h>
912

@@ -27,33 +30,42 @@ int *__counted_by(4) bazz() {} // ok - same count expr
2730

2831
// expected-note@+1{{previous declaration is here}}
2932
int *bazy();
33+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-1]]:6-[[@LINE-1]]:6}:"__counted_by(4) "
3034
// expected-error@+1{{conflicting '__counted_by' attribute with the previous function declaration}}
3135
int *__counted_by(4) bazy() {} // ok
3236

3337
// expected-note@+1 2{{previous declaration is here}}
3438
int *__counted_by(len) bayz(unsigned len);
3539
// expected-error@+1{{conflicting '__counted_by' attribute with the previous function declaration}}
3640
int *bayz(unsigned len) {}
41+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-1]]:6-[[@LINE-1]]:6}:"__counted_by(len) "
3742
// expected-error@+2{{conflicting '__sized_by' attribute with the previous function declaration}}
3843
// expected-note@+1{{conflicting attributes were '__counted_by(len)' and '__sized_by(len)'}}
3944
int *__sized_by(len) bayz(unsigned len) {}
45+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-7]]:6-[[@LINE-7]]:18}:"__sized_by"
46+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-2]]:6-[[@LINE-2]]:16}:"__counted_by"
4047

4148
// expected-note@+1{{previous declaration is here}}
4249
int *baxz(unsigned len, int **pptr);
50+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-1]]:30-[[@LINE-1]]:30}:"__counted_by(len)"
4351
// expected-error@+1{{conflicting '__counted_by' attribute with the previous function declaration}}
4452
int *baxz(unsigned len, int *__counted_by(len)* pptr) {} // ok
4553

4654
// expected-note@+1{{previous declaration is here}}
4755
int *baxy(unsigned len, int *__counted_by(len)* pptr);
4856
// expected-error@+1{{conflicting '__counted_by' attribute with the previous function declaration}}
4957
int *baxy(unsigned len, int ** pptr) {}
58+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-1]]:30-[[@LINE-1]]:30}:"__counted_by(len)"
5059

60+
typedef int canonically_int_t;
5161
char *__counted_by(len) qux(int len);
5262
// expected-note@+1{{previous declaration is here}}
5363
char *__sized_by(len) qux(int len);
5464
// expected-error@+2{{conflicting '__counted_by' attribute with the previous function declaration}}
5565
// expected-note@+1{{conflicting attributes were '__sized_by(len)' and '__counted_by(4)'}}
56-
char *__counted_by(4) qux(int len) {}
66+
char * _Nonnull __counted_by(4) qux(canonically_int_t len) {}
67+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-4]]:18-[[@LINE-4]]:21}:"4"
68+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-2]]:30-[[@LINE-2]]:31}:"len"
5769

5870
int *__counted_by(len) __counted_by(len) quux(int len) {} // ok - same count expr
5971

@@ -67,6 +79,7 @@ void corge(int *__counted_by(len) ptr, int len) {} // ok
6779

6880
// expected-note@+1{{previous declaration is here}}
6981
int ** grault(int len);
82+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-1]]:8-[[@LINE-1]]:8}:"__counted_by(len) "
7083
// expected-error@+1{{conflicting '__counted_by' attribute with the previous function declaration}}
7184
int *__counted_by(len) grault(int len) {}
7285

@@ -98,6 +111,7 @@ void end1(int *__ended_by(b) a, int *b); // OK redeclaration
98111
void end1(int *__ended_by(b) a, int *b) {} // OK definition over declaration
99112

100113
void end1(int *a, int *b); // expected-error{{conflicting '__ended_by' attribute with the previous function declaration}}
114+
// CHECK: fix-it:{{.*}}ptrs-with-multiple-range-attrs.c":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"__ended_by(b) "
101115
void end1(int *a, int *__ended_by(a) b); // expected-error 2{{conflicting '__ended_by' attribute with the previous function declaration}} mismatch on both a and b
102116
void end1(int *__ended_by(b) a, int *__ended_by(a) b); // expected-error{{conflicting '__ended_by' attribute with the previous function declaration}}
103117

0 commit comments

Comments
 (0)