[clang] dfc1e31 - Produce warning for performing pointer arithmetic on a null pointer.
Jamie Schmeiser via cfe-commits
cfe-commits at lists.llvm.org
Tue May 11 08:30:57 PDT 2021
Author: Jamie Schmeiser
Date: 2021-05-11T11:29:50-04:00
New Revision: dfc1e31d49fe1380c9bab43373995df5fed15e6d
URL: https://github.com/llvm/llvm-project/commit/dfc1e31d49fe1380c9bab43373995df5fed15e6d
DIFF: https://github.com/llvm/llvm-project/commit/dfc1e31d49fe1380c9bab43373995df5fed15e6d.diff
LOG: Produce warning for performing pointer arithmetic on a null pointer.
Summary:
Test and produce warning for subtracting a pointer from null or subtracting
null from a pointer. Reuse existing warning that this is undefined
behaviour. Also add unit test for both warnings.
Reformat to satisfy clang-format.
Respond to review comments: add additional test.
Respond to review comments: Do not issue warning for nullptr - nullptr
in C++.
Fix indenting to satisfy clang-format.
Respond to review comments: Add C++ tests.
Author: Jamie Schmeiser <schmeise at ca.ibm.com>
Reviewed By: efriedma (Eli Friedman), nickdesaulniers (Nick Desaulniers)
Differential Revision: https://reviews.llvm.org/D98798
Added:
clang/test/Sema/pointer-addition.cpp
Modified:
clang/lib/Sema/SemaExpr.cpp
clang/test/Sema/pointer-addition.c
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 73d7675eb189f..1390c17de9ece 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10779,7 +10779,17 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
LHS.get(), RHS.get()))
return QualType();
- // FIXME: Add warnings for nullptr - ptr.
+ bool LHSIsNullPtr = LHS.get()->IgnoreParenCasts()->isNullPointerConstant(
+ Context, Expr::NPC_ValueDependentIsNotNull);
+ bool RHSIsNullPtr = RHS.get()->IgnoreParenCasts()->isNullPointerConstant(
+ Context, Expr::NPC_ValueDependentIsNotNull);
+
+ // Subtracting nullptr or from nullptr should produce
+ // a warning expect nullptr - nullptr is valid in C++ [expr.add]p7
+ if (LHSIsNullPtr && (!getLangOpts().CPlusPlus || !RHSIsNullPtr))
+ diagnoseArithmeticOnNullPointer(*this, Loc, LHS.get(), false);
+ if (RHSIsNullPtr && (!getLangOpts().CPlusPlus || !LHSIsNullPtr))
+ diagnoseArithmeticOnNullPointer(*this, Loc, RHS.get(), false);
// The pointee type may have zero size. As an extension, a structure or
// union may have zero size or an array may have zero length. In this
diff --git a/clang/test/Sema/pointer-addition.c b/clang/test/Sema/pointer-addition.c
index 562f05340f7cb..ab641bd132363 100644
--- a/clang/test/Sema/pointer-addition.c
+++ b/clang/test/Sema/pointer-addition.c
@@ -29,4 +29,7 @@ void a(S* b, void* c) {
// Cases that don't match the GNU inttoptr idiom get a
diff erent warning.
f = (char*)0 - i; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}}
int *g = (int*)0 + i; // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}}
+ f = (char*)((char*)0 - f); // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}}
+ f = (char*)(f - (char*)0); // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}}
+ f = (char*)((char*)0 - (char*)0); // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}} expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}}
}
diff --git a/clang/test/Sema/pointer-addition.cpp b/clang/test/Sema/pointer-addition.cpp
new file mode 100644
index 0000000000000..5e09034ed9651
--- /dev/null
+++ b/clang/test/Sema/pointer-addition.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -Wextra -std=c++11
+
+void a() {
+ char *f = (char*)0;
+ f = (char*)((char*)0 - f); // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}}
+ f = (char*)(f - (char*)0); // expected-warning {{performing pointer arithmetic on a null pointer has undefined behavior}}
+ f = (char*)((char*)0 - (char*)0); // valid in C++
+}
More information about the cfe-commits
mailing list