diff --git a/upstream_utils/update_drake.py b/upstream_utils/update_drake.py index c52c05ffbc..4f7fa6b467 100755 --- a/upstream_utils/update_drake.py +++ b/upstream_utils/update_drake.py @@ -7,9 +7,8 @@ from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, wa def main(): - root, repo = setup_upstream_repo( - "https://github.com/RobotLocomotion/drake", - "8b72428dce6959d077e17c3c3a7a5ef4a17107ee") + root, repo = setup_upstream_repo("https://github.com/RobotLocomotion/drake", + "v0.33.0") wpimath = os.path.join(root, "wpimath") # Delete old install diff --git a/wpimath/src/main/native/include/drake/common/drake_copyable.h b/wpimath/src/main/native/include/drake/common/drake_copyable.h index f8949cc46b..2fb63e96f6 100644 --- a/wpimath/src/main/native/include/drake/common/drake_copyable.h +++ b/wpimath/src/main/native/include/drake/common/drake_copyable.h @@ -19,8 +19,8 @@ Code that needs custom copy or move functions should not use these macros. /** DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN deletes the special member functions for copy-construction, copy-assignment, move-construction, and move-assignment. Drake's Doxygen is customized to render the deletions in detail, with -appropriate comments. Invoke this this macro in the public section of the -class declaration, e.g.: +appropriate comments. Invoke this macro in the public section of the class +declaration, e.g.:
 class Foo {
  public:
@@ -43,8 +43,8 @@ copy-assignment defaults are well-formed.  Note that the defaulted move
 functions could conceivably still be ill-formed, in which case they will
 effectively not be declared or used -- but because the copy constructor exists
 the type will still be MoveConstructible.  Drake's Doxygen is customized to
-render the functions in detail, with appropriate comments.  Invoke this this
-macro in the public section of the class declaration, e.g.:
+render the functions in detail, with appropriate comments.  Invoke this macro
+in the public section of the class declaration, e.g.:
 
 class Foo {
  public:
diff --git a/wpimath/src/main/native/include/drake/common/drake_throw.h b/wpimath/src/main/native/include/drake/common/drake_throw.h
index 9833d8b62a..bb4bae8926 100644
--- a/wpimath/src/main/native/include/drake/common/drake_throw.h
+++ b/wpimath/src/main/native/include/drake/common/drake_throw.h
@@ -14,17 +14,40 @@ namespace internal {
 // Throw an error message.
 [[noreturn]] void Throw(const char* condition, const char* func,
                         const char* file, int line);
+
+template 
+constexpr void DrakeThrowUnlessWasUsedWithRawPointer() {}
+template<>
+[[deprecated("\nDRAKE DEPRECATED: When using DRAKE_THROW_UNLESS on a raw"
+" pointer, always write out DRAKE_THROW_UNLESS(foo != nullptr), do not write"
+" DRAKE_THROW_UNLESS(foo) and rely on implicit pointer-to-bool conversion."
+"\nThe deprecated code will be removed from Drake on or after 2021-12-01.")]]
+constexpr void DrakeThrowUnlessWasUsedWithRawPointer() {}
+
 }  // namespace internal
 }  // namespace drake
 
 /// Evaluates @p condition and iff the value is false will throw an exception
 /// with a message showing at least the condition text, function name, file,
 /// and line.
+///
+/// The condition must not be a pointer, where we'd implicitly rely on its
+/// nullness. Instead, always write out "!= nullptr" to be precise.
+///
+/// Correct: `DRAKE_THROW_UNLESS(foo != nullptr);`
+/// Incorrect: `DRAKE_THROW_UNLESS(foo);`
+///
+/// Because this macro is intended to provide a useful exception message to
+/// users, we should err on the side of extra detail about the failure. The
+/// meaning of "foo" isolated within error message text does not make it
+/// clear that a null pointer is the proximate cause of the problem.
 #define DRAKE_THROW_UNLESS(condition)                                        \
   do {                                                                       \
     typedef ::drake::assert::ConditionTraits<                                \
         typename std::remove_cv_t> Trait;               \
     static_assert(Trait::is_valid, "Condition should be bool-convertible."); \
+    ::drake::internal::DrakeThrowUnlessWasUsedWithRawPointer<                \
+        std::is_pointer_v>();                           \
     if (!Trait::Evaluate(condition)) {                                       \
       ::drake::internal::Throw(#condition, __func__, __FILE__, __LINE__);    \
     }                                                                        \