Skip to content

Commit 6dad7ec

Browse files
thejhPiJoules
authored andcommitted
[clang] Fix noderef for AddrOf on MemberExpr
Committing on behalf of thejh (Jann Horn). As part of this change, one existing test case has to be adjusted because it accidentally stripped the NoDeref attribute without getting caught. Depends on D92140 Differential Review: https://reviews.llvm.org/D92141
1 parent 641ede9 commit 6dad7ec

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

clang/lib/Sema/SemaExprMember.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,14 @@ Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
18101810
Qualifiers Combined = BaseQuals + MemberQuals;
18111811
if (Combined != MemberQuals)
18121812
MemberType = Context.getQualifiedType(MemberType, Combined);
1813+
1814+
// Pick up NoDeref from the base in case we end up using AddrOf on the
1815+
// result. E.g. the expression
1816+
// &someNoDerefPtr->pointerMember
1817+
// should be a noderef pointer again.
1818+
if (BaseType->hasAttr(attr::NoDeref))
1819+
MemberType =
1820+
Context.getAttributedType(attr::NoDeref, MemberType, MemberType);
18131821
}
18141822

18151823
auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);

clang/test/Frontend/noderef.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ int test() {
7070
x = sizeof(s->a + (s->b)); // ok
7171
x = sizeof(int[++s->a]); // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
7272

73+
// Struct member access should carry NoDeref type information through to an
74+
// enclosing AddrOf.
75+
p2 = &s->a; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
76+
p2 = &(*s).a; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
77+
x = *&s->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
78+
7379
// Nested struct access
7480
struct S2 NODEREF *s2_noderef; // expected-note 5 {{s2_noderef declared here}}
7581
p = s2_noderef->a; // ok since result is an array in a struct
@@ -113,7 +119,7 @@ int test() {
113119

114120
p = s2_arr[1]->a;
115121
p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 'noderef'}}
116-
int **bptr = &s2_arr[1]->b;
122+
int *NODEREF *bptr = &s2_arr[1]->b;
117123

118124
x = s2->s2->a; // expected-warning{{dereferencing expression marked as 'noderef'}}
119125
x = s2_noderef->a[1]; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}

0 commit comments

Comments
 (0)