[llvm-branch-commits] [clang] 155fca3 - [clang] Fix noderef for array member of deref expr
Leonard Chan via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Dec 7 14:44:38 PST 2020
Author: Leonard Chan
Date: 2020-12-07T14:39:42-08:00
New Revision: 155fca3cae275562e626d3e4fbfac70b4b75d2e7
URL: https://github.com/llvm/llvm-project/commit/155fca3cae275562e626d3e4fbfac70b4b75d2e7
DIFF: https://github.com/llvm/llvm-project/commit/155fca3cae275562e626d3e4fbfac70b4b75d2e7.diff
LOG: [clang] Fix noderef for array member of deref expr
Committing on behalf of thejh (Jann Horn).
Given an attribute((noderef)) pointer "p" to the struct
struct s { int a[2]; };
ensure that the following expressions are treated the same way by the
noderef logic:
p->a
(*p).a
Until now, the first expression would be treated correctly (nothing is
added to PossibleDerefs because CheckMemberAccessOfNoDeref() bails out
on array members), but the second expression would incorrectly warn
because "*p" creates a PossibleDerefs entry.
Handle this case the same way as for the AddrOf operator.
Differential Revision: https://reviews.llvm.org/D92140
Added:
Modified:
clang/lib/Sema/SemaExprMember.cpp
clang/test/Frontend/noderef.c
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 23cfae81df46..3e9d2a056c5c 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1739,12 +1739,23 @@ void Sema::CheckMemberAccessOfNoDeref(const MemberExpr *E) {
QualType ResultTy = E->getType();
- // Do not warn on member accesses to arrays since this returns an array
- // lvalue and does not actually dereference memory.
- if (isa<ArrayType>(ResultTy))
- return;
-
- if (E->isArrow()) {
+ // Member accesses have four cases:
+ // 1: non-array member via "->": dereferences
+ // 2: non-array member via ".": nothing interesting happens
+ // 3: array member access via "->": nothing interesting happens
+ // (this returns an array lvalue and does not actually dereference memory)
+ // 4: array member access via ".": *adds* a layer of indirection
+ if (ResultTy->isArrayType()) {
+ if (!E->isArrow()) {
+ // This might be something like:
+ // (*structPtr).arrayMember
+ // which behaves roughly like:
+ // &(*structPtr).pointerMember
+ // in that the apparent dereference in the base expression does not
+ // actually happen.
+ CheckAddressOfNoDeref(E->getBase());
+ }
+ } else if (E->isArrow()) {
if (const auto *Ptr = dyn_cast<PointerType>(
E->getBase()->getType().getDesugaredType(Context))) {
if (Ptr->getPointeeType()->hasAttr(attr::NoDeref))
diff --git a/clang/test/Frontend/noderef.c b/clang/test/Frontend/noderef.c
index 3388f2a39992..b548ffa13273 100644
--- a/clang/test/Frontend/noderef.c
+++ b/clang/test/Frontend/noderef.c
@@ -73,6 +73,7 @@ int test() {
// 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
+ p = (*s2_noderef).a; // ok since result is an array in a struct
p = s2_noderef->a2; // ok
p = s2_noderef->b; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
p = s2_noderef->b2; // expected-warning{{dereferencing s2_noderef; was declared with a 'noderef' type}}
More information about the llvm-branch-commits
mailing list