Skip to content

Commit 0f93828

Browse files
Abseil Teamcopybara-github
authored andcommitted
Provide file-scoped pragma behind macro ABSL_POINTERS_DEFAULT_NONNULL to
indicate the default nullability. This is a no-op for now (not understood by checkers), but does communicate intention to human readers. PiperOrigin-RevId: 668448175 Change-Id: I19802d19be9a310aa5f0dacf8b0567dd768fb830
1 parent 40a975f commit 0f93828

File tree

4 files changed

+109
-5
lines changed

4 files changed

+109
-5
lines changed

absl/base/BUILD.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,16 @@ cc_test(
648648
],
649649
)
650650

651+
cc_test(
652+
name = "nullability_default_nonnull_test",
653+
srcs = ["nullability_default_nonnull_test.cc"],
654+
deps = [
655+
":nullability",
656+
"@com_google_googletest//:gtest",
657+
"@com_google_googletest//:gtest_main",
658+
],
659+
)
660+
651661
cc_test(
652662
name = "raw_logging_test",
653663
srcs = ["raw_logging_test.cc"],

absl/base/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ absl_cc_test(
9595
GTest::gtest_main
9696
)
9797

98+
absl_cc_test(
99+
NAME
100+
nullability_default_nonnull_test
101+
SRCS
102+
"nullability_default_nonnull_test.cc"
103+
COPTS
104+
${ABSL_TEST_COPTS}
105+
DEPS
106+
absl::nullability
107+
GTest::gtest_main
108+
)
109+
98110
# Internal-only target, do not depend on directly.
99111
absl_cc_library(
100112
NAME

absl/base/nullability.h

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,47 @@
161161
#include "absl/base/config.h"
162162
#include "absl/base/internal/nullability_impl.h"
163163

164+
// ABSL_POINTERS_DEFAULT_NONNULL
165+
//
166+
// This macro specifies that all unannotated pointer types within the given
167+
// file are designated as nonnull (instead of the default "unknown"). This macro
168+
// exists as a standalone statement and applies default nonnull behavior to all
169+
// subsequent pointers; as a result, place this macro as the first non-comment,
170+
// non-`#include` line in a file.
171+
//
172+
// Example:
173+
//
174+
// #include "absl/base/nullability.h"
175+
//
176+
// ABSL_POINTERS_DEFAULT_NONNULL
177+
//
178+
// void FillMessage(Message *m); // implicitly non-null
179+
// absl::Nullable<T*> GetNullablePtr(); // explicitly nullable
180+
// absl::NullabilityUnknown<T*> GetUnknownPtr(); // explicitly unknown
181+
//
182+
// The macro can be safely used in header files -- it will not affect any files
183+
// that include it.
184+
//
185+
// In files with the macro, plain `T*` syntax means `absl::Nonnull<T*>`, and the
186+
// exceptions (`Nullable` and `NullabilityUnknown`) must be marked
187+
// explicitly. The same holds, correspondingly, for smart pointer types.
188+
//
189+
// For comparison, without the macro, all unannotated pointers would default to
190+
// unknown, and otherwise require explicit annotations to change this behavior:
191+
//
192+
// #include "absl/base/nullability.h"
193+
//
194+
// void FillMessage(absl::Nonnull<Message*> m); // explicitly non-null
195+
// absl::Nullable<T*> GetNullablePtr(); // explicitly nullable
196+
// T* GetUnknownPtr(); // implicitly unknown
197+
//
198+
// No-op except for being a human readable signal.
199+
#define ABSL_POINTERS_DEFAULT_NONNULL
200+
164201
namespace absl {
165202
ABSL_NAMESPACE_BEGIN
166203

167-
// absl::Nonnull
204+
// absl::Nonnull (default with `ABSL_POINTERS_DEFAULT_NONNULL`)
168205
//
169206
// The indicated pointer is never null. It is the responsibility of the provider
170207
// of this pointer across an API boundary to ensure that the pointer is never
@@ -197,7 +234,7 @@ using Nonnull = nullability_internal::NonnullImpl<T>;
197234
template <typename T>
198235
using Nullable = nullability_internal::NullableImpl<T>;
199236

200-
// absl::NullabilityUnknown (default)
237+
// absl::NullabilityUnknown (default without `ABSL_POINTERS_DEFAULT_NONNULL`)
201238
//
202239
// The indicated pointer has not yet been determined to be definitively
203240
// "non-null" or "nullable." Providers of such pointers across API boundaries
@@ -208,9 +245,10 @@ using Nullable = nullability_internal::NullableImpl<T>;
208245
// migrated into one of the above two nullability states: `Nonnull<T>` or
209246
// `Nullable<T>`.
210247
//
211-
// NOTE: Because this annotation is the global default state, unannotated
212-
// pointers are assumed to have "unknown" semantics. This assumption is designed
213-
// to minimize churn and reduce clutter within the codebase.
248+
// NOTE: For files that do not specify `ABSL_POINTERS_DEFAULT_NONNULL`,
249+
// because this annotation is the global default state, unannotated pointers are
250+
// are assumed to have "unknown" semantics. This assumption is designed to
251+
// minimize churn and reduce clutter within the codebase.
214252
//
215253
// Example:
216254
//
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2024 The Abseil Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <cassert>
16+
17+
#include "gtest/gtest.h"
18+
#include "absl/base/nullability.h"
19+
20+
ABSL_POINTERS_DEFAULT_NONNULL
21+
22+
namespace {
23+
24+
void FuncWithDefaultNonnullArg(int* /*arg*/) {}
25+
template <typename T>
26+
void FuncWithDeducedDefaultNonnullArg(T* /*arg*/) {}
27+
28+
TEST(DefaultNonnullTest, NonnullArgument) {
29+
int var = 0;
30+
FuncWithDefaultNonnullArg(&var);
31+
FuncWithDeducedDefaultNonnullArg<int>(&var);
32+
}
33+
34+
int* FuncWithDefaultNonnullReturn() {
35+
static int var = 0;
36+
return &var;
37+
}
38+
39+
TEST(DefaultNonnullTest, NonnullReturn) {
40+
auto var = FuncWithDefaultNonnullReturn();
41+
(void)var;
42+
}
43+
44+
} // namespace

0 commit comments

Comments
 (0)