Skip to content

Commit a80b4ba

Browse files
committed
We can't handle '&ptr->array' like Exprs.
1 parent a2d7659 commit a80b4ba

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,10 +1068,17 @@ namespace {
10681068
struct StructFieldAccess
10691069
: public ConstStmtVisitor<StructFieldAccess, const MemberExpr *> {
10701070
const ArraySubscriptExpr *ASE = nullptr;
1071+
bool AddrOfSeen = false;
10711072

1072-
const MemberExpr *VisitMemberExpr(const MemberExpr *E) { return E; }
1073+
const MemberExpr *VisitMemberExpr(const MemberExpr *E) {
1074+
if (AddrOfSeen && E->getType()->isArrayType())
1075+
// Avoid forms like '&ptr->array'.
1076+
return nullptr;
1077+
return E;
1078+
}
10731079

10741080
const MemberExpr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
1081+
AddrOfSeen = false; // '&ptr->array[idx]' is okay.
10751082
ASE = E;
10761083
return Visit(E->getBase());
10771084
}
@@ -1082,9 +1089,11 @@ struct StructFieldAccess
10821089
return Visit(E->getSubExpr());
10831090
}
10841091
const MemberExpr *VisitUnaryAddrOf(const clang::UnaryOperator *E) {
1092+
AddrOfSeen = true;
10851093
return Visit(E->getSubExpr());
10861094
}
10871095
const MemberExpr *VisitUnaryDeref(const clang::UnaryOperator *E) {
1096+
AddrOfSeen = false;
10881097
return Visit(E->getSubExpr());
10891098
}
10901099
};

clang/test/CodeGen/attr-counted-by.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,3 +2058,28 @@ void test32(struct annotated_with_array *ptr, int idx1, int idx2) {
20582058
size_t test32_bdos(struct annotated_with_array *ptr, int index) {
20592059
return __bdos(&ptr->flags[index]);
20602060
}
2061+
2062+
// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test33(
2063+
// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]]) local_unnamed_addr #[[ATTR0]] {
2064+
// SANITIZE-WITH-ATTR-NEXT: entry:
2065+
// SANITIZE-WITH-ATTR-NEXT: ret i64 -1
2066+
//
2067+
// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test33(
2068+
// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[PTR:%.*]]) local_unnamed_addr #[[ATTR3]] {
2069+
// NO-SANITIZE-WITH-ATTR-NEXT: entry:
2070+
// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1
2071+
//
2072+
// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test33(
2073+
// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]]) local_unnamed_addr #[[ATTR0]] {
2074+
// SANITIZE-WITHOUT-ATTR-NEXT: entry:
2075+
// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
2076+
//
2077+
// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test33(
2078+
// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[PTR:%.*]]) local_unnamed_addr #[[ATTR1]] {
2079+
// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
2080+
// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1
2081+
//
2082+
size_t test33(struct annotated *ptr) {
2083+
// Don't handle '&ptr->array' like normal.
2084+
return __bdos(&*&*&*&ptr->array);
2085+
}

0 commit comments

Comments
 (0)