Skip to content

Commit 01b10bc

Browse files
[Diagnostics] Teach -Wnull-dereference about address_space attribute
Summary: Clang should not warn for: > test.c:2:12: warning: indirection of non-volatile null pointer will be deleted, > not trap [-Wnull-dereference] > return *(int __attribute__((address_space(256))) *) 0; > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Solves PR42292. Reviewers: aaron.ballman, rsmith Reviewed By: aaron.ballman Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D69664
1 parent b95bb08 commit 01b10bc

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

clang/lib/Sema/SemaExpr.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -481,16 +481,21 @@ static void CheckForNullPointerDereference(Sema &S, Expr *E) {
481481
// optimizer will delete, so warn about it. People sometimes try to use this
482482
// to get a deterministic trap and are surprised by clang's behavior. This
483483
// only handles the pattern "*null", which is a very syntactic check.
484-
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts()))
485-
if (UO->getOpcode() == UO_Deref &&
486-
UO->getSubExpr()->IgnoreParenCasts()->
487-
isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull) &&
484+
const auto *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts());
485+
if (UO && UO->getOpcode() == UO_Deref) {
486+
const LangAS AS =
487+
UO->getSubExpr()->getType()->getPointeeType().getAddressSpace();
488+
if ((!isTargetAddressSpace(AS) ||
489+
(isTargetAddressSpace(AS) && toTargetAddressSpace(AS) == 0)) &&
490+
UO->getSubExpr()->IgnoreParenCasts()->isNullPointerConstant(
491+
S.Context, Expr::NPC_ValueDependentIsNotNull) &&
488492
!UO->getType().isVolatileQualified()) {
489-
S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO,
490-
S.PDiag(diag::warn_indirection_through_null)
491-
<< UO->getSubExpr()->getSourceRange());
492-
S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO,
493-
S.PDiag(diag::note_indirection_through_null));
493+
S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO,
494+
S.PDiag(diag::warn_indirection_through_null)
495+
<< UO->getSubExpr()->getSourceRange());
496+
S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO,
497+
S.PDiag(diag::note_indirection_through_null));
498+
}
494499
}
495500
}
496501

clang/test/Sema/exprs.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,17 +179,27 @@ void test18(int b) {
179179
test18_e(); // expected-error {{too few arguments to function call, expected at least 2, have 0}}
180180
}
181181

182+
typedef int __attribute__((address_space(256))) int_AS256;
182183
// PR7569
183184
void test19() {
184-
*(int*)0 = 0; // expected-warning {{indirection of non-volatile null pointer}} \
185+
*(int *)0 = 0; // expected-warning {{indirection of non-volatile null pointer}} \
185186
// expected-note {{consider using __builtin_trap}}
186-
*(volatile int*)0 = 0; // Ok.
187+
*(volatile int *)0 = 0; // Ok.
188+
*(int __attribute__((address_space(256))) *)0 = 0; // Ok.
189+
*(int __attribute__((address_space(0))) *)0 = 0; // expected-warning {{indirection of non-volatile null pointer}} \
190+
// expected-note {{consider using __builtin_trap}}
191+
*(int_AS256 *)0 = 0; // Ok.
187192

188193
// rdar://9269271
189-
int x = *(int*)0; // expected-warning {{indirection of non-volatile null pointer}} \
194+
int x = *(int *)0; // expected-warning {{indirection of non-volatile null pointer}} \
195+
// expected-note {{consider using __builtin_trap}}
196+
int x2 = *(volatile int *)0; // Ok.
197+
int x3 = *(int __attribute__((address_space(0))) *)0; // expected-warning {{indirection of non-volatile null pointer}} \
190198
// expected-note {{consider using __builtin_trap}}
191-
int x2 = *(volatile int*)0; // Ok.
192-
int *p = &(*(int*)0); // Ok;
199+
int x4 = *(int_AS256 *)0; // Ok.
200+
int *p = &(*(int *)0); // Ok.
201+
int_AS256 *p1 = &(*(int __attribute__((address_space(256))) *)0); // Ok.
202+
int __attribute__((address_space(0))) *p2 = &(*(int __attribute__((address_space(0))) *)0); // Ok.
193203
}
194204

195205
int test20(int x) {

0 commit comments

Comments
 (0)