thejh created this revision.
thejh added reviewers: leonardchan, aaron.ballman.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
thejh requested review of this revision.

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 <https://reviews.llvm.org/D92140>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D92141

Files:
  clang/lib/Sema/SemaExprMember.cpp
  clang/test/Frontend/noderef.c


Index: clang/test/Frontend/noderef.c
===================================================================
--- clang/test/Frontend/noderef.c
+++ clang/test/Frontend/noderef.c
@@ -70,6 +70,14 @@
   x = sizeof(s->a + (s->b)); // ok
   x = sizeof(int[++s->a]);   // expected-warning{{dereferencing s; was 
declared with a 'noderef' type}}
 
+  // Struct member access should carry NoDeref type information through to an
+  // enclosing AddrOf.
+  p = &s->a;    // ok
+  p = &(*s).a;  // ok
+  p2 = &s->a;   // expected-warning{{casting to dereferenceable pointer 
removes 'noderef' attribute}}
+  p2 = &(*s).a; // expected-warning{{casting to dereferenceable pointer 
removes 'noderef' attribute}}
+  x = *&s->a;   // expected-warning{{dereferencing expression marked as 
'noderef'}}
+
   // Nested struct access
   struct S2 NODEREF *s2_noderef;    // expected-note 5 {{s2_noderef declared 
here}}
   p = s2_noderef->a;  // ok since result is an array in a struct
@@ -113,7 +121,7 @@
 
   p = s2_arr[1]->a;
   p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 
'noderef'}}
-  int **bptr = &s2_arr[1]->b;
+  int *NODEREF *bptr = &s2_arr[1]->b;
 
   x = s2->s2->a;        // expected-warning{{dereferencing expression marked 
as 'noderef'}}
   x = s2_noderef->a[1]; // expected-warning{{dereferencing s2_noderef; was 
declared with a 'noderef' type}}
Index: clang/lib/Sema/SemaExprMember.cpp
===================================================================
--- clang/lib/Sema/SemaExprMember.cpp
+++ clang/lib/Sema/SemaExprMember.cpp
@@ -1810,6 +1810,14 @@
     Qualifiers Combined = BaseQuals + MemberQuals;
     if (Combined != MemberQuals)
       MemberType = Context.getQualifiedType(MemberType, Combined);
+
+    // Pick up NoDeref from the base in case we end up using AddrOf on the
+    // result. E.g. the expression
+    //     &someNoDerefPtr->pointerMember
+    // should be a noderef pointer again.
+    if (BaseType->hasAttr(attr::NoDeref))
+      MemberType =
+          Context.getAttributedType(attr::NoDeref, MemberType, MemberType);
   }
 
   auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);


Index: clang/test/Frontend/noderef.c
===================================================================
--- clang/test/Frontend/noderef.c
+++ clang/test/Frontend/noderef.c
@@ -70,6 +70,14 @@
   x = sizeof(s->a + (s->b)); // ok
   x = sizeof(int[++s->a]);   // expected-warning{{dereferencing s; was declared with a 'noderef' type}}
 
+  // Struct member access should carry NoDeref type information through to an
+  // enclosing AddrOf.
+  p = &s->a;    // ok
+  p = &(*s).a;  // ok
+  p2 = &s->a;   // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
+  p2 = &(*s).a; // expected-warning{{casting to dereferenceable pointer removes 'noderef' attribute}}
+  x = *&s->a;   // expected-warning{{dereferencing expression marked as 'noderef'}}
+
   // Nested struct access
   struct S2 NODEREF *s2_noderef;    // expected-note 5 {{s2_noderef declared here}}
   p = s2_noderef->a;  // ok since result is an array in a struct
@@ -113,7 +121,7 @@
 
   p = s2_arr[1]->a;
   p = s2_arr[1]->b; // expected-warning{{dereferencing expression marked as 'noderef'}}
-  int **bptr = &s2_arr[1]->b;
+  int *NODEREF *bptr = &s2_arr[1]->b;
 
   x = s2->s2->a;        // expected-warning{{dereferencing expression marked as 'noderef'}}
   x = s2_noderef->a[1]; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
Index: clang/lib/Sema/SemaExprMember.cpp
===================================================================
--- clang/lib/Sema/SemaExprMember.cpp
+++ clang/lib/Sema/SemaExprMember.cpp
@@ -1810,6 +1810,14 @@
     Qualifiers Combined = BaseQuals + MemberQuals;
     if (Combined != MemberQuals)
       MemberType = Context.getQualifiedType(MemberType, Combined);
+
+    // Pick up NoDeref from the base in case we end up using AddrOf on the
+    // result. E.g. the expression
+    //     &someNoDerefPtr->pointerMember
+    // should be a noderef pointer again.
+    if (BaseType->hasAttr(attr::NoDeref))
+      MemberType =
+          Context.getAttributedType(attr::NoDeref, MemberType, MemberType);
   }
 
   auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to