diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-04-26 17:41:22 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-04-26 17:41:22 +0000 |
commit | 8a285ae6fc4926cc4e419025eec63e2d6696e13f (patch) | |
tree | 61c9dbc68e4c0cf38ab9f1f9836dcb37110e9ef9 /lib/Sema/SemaExpr.cpp | |
parent | 0cd7be4c4d330aa4f8918986b59e104411bf107d (diff) |
Emit a -Wnull-dereference warning for "*null" not just "*null = something". Addresses rdar://9269271.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130207 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 6d46127d7d..c90c513250 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -282,6 +282,25 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E) { return Owned(E); } +static void CheckForNullPointerDereference(Sema &S, Expr *E) { + // Check to see if we are dereferencing a null pointer. If so, + // and if not volatile-qualified, this is undefined behavior that the + // optimizer will delete, so warn about it. People sometimes try to use this + // to get a deterministic trap and are surprised by clang's behavior. This + // only handles the pattern "*null", which is a very syntactic check. + if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts())) + if (UO->getOpcode() == UO_Deref && + UO->getSubExpr()->IgnoreParenCasts()-> + isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull) && + !UO->getType().isVolatileQualified()) { + S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO, + S.PDiag(diag::warn_indirection_through_null) + << UO->getSubExpr()->getSourceRange()); + S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO, + S.PDiag(diag::note_indirection_through_null)); + } +} + ExprResult Sema::DefaultLvalueConversion(Expr *E) { // C++ [conv.lval]p1: // A glvalue of a non-function, non-array type T can be @@ -317,6 +336,8 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { if (T->isVoidType()) return Owned(E); + CheckForNullPointerDereference(*this, E); + // C++ [conv.lval]p1: // [...] If T is a non-class type, the type of the prvalue is the // cv-unqualified version of T. Otherwise, the type of the @@ -7993,25 +8014,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, ExprResult &RHS, RHS.get(), AA_Assigning)) return QualType(); - - // Check to see if the destination operand is a dereferenced null pointer. If - // so, and if not volatile-qualified, this is undefined behavior that the - // optimizer will delete, so warn about it. People sometimes try to use this - // to get a deterministic trap and are surprised by clang's behavior. This - // only handles the pattern "*null = whatever", which is a very syntactic - // check. - if (UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS->IgnoreParenCasts())) - if (UO->getOpcode() == UO_Deref && - UO->getSubExpr()->IgnoreParenCasts()-> - isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) && - !UO->getType().isVolatileQualified()) { - DiagRuntimeBehavior(UO->getOperatorLoc(), UO, - PDiag(diag::warn_indirection_through_null) - << UO->getSubExpr()->getSourceRange()); - DiagRuntimeBehavior(UO->getOperatorLoc(), UO, - PDiag(diag::note_indirection_through_null)); - } - + CheckForNullPointerDereference(*this, LHS); // Check for trivial buffer overflows. CheckArrayAccess(LHS->IgnoreParenCasts()); |