aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-04-26 17:41:22 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-04-26 17:41:22 +0000
commit8a285ae6fc4926cc4e419025eec63e2d6696e13f (patch)
tree61c9dbc68e4c0cf38ab9f1f9836dcb37110e9ef9 /lib/Sema/SemaExpr.cpp
parent0cd7be4c4d330aa4f8918986b59e104411bf107d (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.cpp41
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());