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
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index fa3719d..06cd361 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel
@@ -649,6 +649,16 @@ ) cc_test( + name = "nullability_default_nonnull_test", + srcs = ["nullability_default_nonnull_test.cc"], + deps = [ + ":nullability", + "@com_google_googletest//:gtest", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( name = "raw_logging_test", srcs = ["raw_logging_test.cc"], copts = ABSL_TEST_COPTS,
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index eed0afc..feb3e01 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt
@@ -95,6 +95,18 @@ GTest::gtest_main ) +absl_cc_test( + NAME + nullability_default_nonnull_test + SRCS + "nullability_default_nonnull_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::nullability + GTest::gtest_main +) + # Internal-only target, do not depend on directly. absl_cc_library( NAME
diff --git a/absl/base/nullability.h b/absl/base/nullability.h index 34dc083..6322c1d 100644 --- a/absl/base/nullability.h +++ b/absl/base/nullability.h
@@ -161,10 +161,47 @@ #include "absl/base/config.h" #include "absl/base/internal/nullability_impl.h" +// ABSL_POINTERS_DEFAULT_NONNULL +// +// This macro specifies that all unannotated pointer types within the given +// file are designated as nonnull (instead of the default "unknown"). This macro +// exists as a standalone statement and applies default nonnull behavior to all +// subsequent pointers; as a result, place this macro as the first non-comment, +// non-`#include` line in a file. +// +// Example: +// +// #include "absl/base/nullability.h" +// +// ABSL_POINTERS_DEFAULT_NONNULL +// +// void FillMessage(Message *m); // implicitly non-null +// absl::Nullable<T*> GetNullablePtr(); // explicitly nullable +// absl::NullabilityUnknown<T*> GetUnknownPtr(); // explicitly unknown +// +// The macro can be safely used in header files -- it will not affect any files +// that include it. +// +// In files with the macro, plain `T*` syntax means `absl::Nonnull<T*>`, and the +// exceptions (`Nullable` and `NullabilityUnknown`) must be marked +// explicitly. The same holds, correspondingly, for smart pointer types. +// +// For comparison, without the macro, all unannotated pointers would default to +// unknown, and otherwise require explicit annotations to change this behavior: +// +// #include "absl/base/nullability.h" +// +// void FillMessage(absl::Nonnull<Message*> m); // explicitly non-null +// absl::Nullable<T*> GetNullablePtr(); // explicitly nullable +// T* GetUnknownPtr(); // implicitly unknown +// +// No-op except for being a human readable signal. +#define ABSL_POINTERS_DEFAULT_NONNULL + namespace absl { ABSL_NAMESPACE_BEGIN -// absl::Nonnull +// absl::Nonnull (default with `ABSL_POINTERS_DEFAULT_NONNULL`) // // The indicated pointer is never null. It is the responsibility of the provider // of this pointer across an API boundary to ensure that the pointer is never @@ -197,7 +234,7 @@ template <typename T> using Nullable = nullability_internal::NullableImpl<T>; -// absl::NullabilityUnknown (default) +// absl::NullabilityUnknown (default without `ABSL_POINTERS_DEFAULT_NONNULL`) // // The indicated pointer has not yet been determined to be definitively // "non-null" or "nullable." Providers of such pointers across API boundaries @@ -208,9 +245,10 @@ // migrated into one of the above two nullability states: `Nonnull<T>` or // `Nullable<T>`. // -// NOTE: Because this annotation is the global default state, unannotated -// pointers are assumed to have "unknown" semantics. This assumption is designed -// to minimize churn and reduce clutter within the codebase. +// NOTE: For files that do not specify `ABSL_POINTERS_DEFAULT_NONNULL`, +// because this annotation is the global default state, unannotated pointers are +// are assumed to have "unknown" semantics. This assumption is designed to +// minimize churn and reduce clutter within the codebase. // // Example: //
diff --git a/absl/base/nullability_default_nonnull_test.cc b/absl/base/nullability_default_nonnull_test.cc new file mode 100644 index 0000000..bd5b483 --- /dev/null +++ b/absl/base/nullability_default_nonnull_test.cc
@@ -0,0 +1,44 @@ +// Copyright 2024 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cassert> + +#include "gtest/gtest.h" +#include "absl/base/nullability.h" + +ABSL_POINTERS_DEFAULT_NONNULL + +namespace { + +void FuncWithDefaultNonnullArg(int* /*arg*/) {} +template <typename T> +void FuncWithDeducedDefaultNonnullArg(T* /*arg*/) {} + +TEST(DefaultNonnullTest, NonnullArgument) { + int var = 0; + FuncWithDefaultNonnullArg(&var); + FuncWithDeducedDefaultNonnullArg<int>(&var); +} + +int* FuncWithDefaultNonnullReturn() { + static int var = 0; + return &var; +} + +TEST(DefaultNonnullTest, NonnullReturn) { + auto var = FuncWithDefaultNonnullReturn(); + (void)var; +} + +} // namespace