Normalize assert checking of clipBehavior (#38568)

I noticed that we were pretty inconsistent with the way that we checked the value of clipBehavior in the framework, so I normalized the usages and updated docs where necessary.

This is a breaking change if you used to pass null explicitly to FlatButton, OutlineButton or RaisedButton constructors, expecting to get Clip.none. It will now assert if you do that. Existing implementations that pass null implicitly by not specifying clipBehavior won't need to change their call sites. It always implicitly defaulted to Clip.none before, and it will continue to do that, it's only places where it was explicitly set to null in order to get the implicit default that it will fail.
diff --git a/packages/flutter/lib/src/material/bottom_app_bar.dart b/packages/flutter/lib/src/material/bottom_app_bar.dart
index 682dc04..6a05e59 100644
--- a/packages/flutter/lib/src/material/bottom_app_bar.dart
+++ b/packages/flutter/lib/src/material/bottom_app_bar.dart
@@ -42,7 +42,7 @@
 class BottomAppBar extends StatefulWidget {
   /// Creates a bottom application bar.
   ///
-  /// The [clipBehavior] argument must not be null.
+  /// The [clipBehavior] argument defaults to [Clip.none] and must not be null.
   /// Additionally, [elevation] must be non-negative.
   ///
   /// If [color], [elevation], or [shape] are null, their [BottomAppBarTheme] values will be used.
@@ -56,9 +56,9 @@
     this.clipBehavior = Clip.none,
     this.notchMargin = 4.0,
     this.child,
-  }) : assert(clipBehavior != null),
-       assert(elevation == null || elevation >= 0.0),
+  }) : assert(elevation == null || elevation >= 0.0),
        assert(notchMargin != null),
+       assert(clipBehavior != null),
        super(key: key);
 
   /// The widget below this widget in the tree.
@@ -92,6 +92,8 @@
   final NotchedShape shape;
 
   /// {@macro flutter.widgets.Clip}
+  ///
+  /// Defaults to [Clip.none], and must not be null.
   final Clip clipBehavior;
 
   /// The margin between the [FloatingActionButton] and the [BottomAppBar]'s
diff --git a/packages/flutter/lib/src/material/button.dart b/packages/flutter/lib/src/material/button.dart
index 95e03c5..0fad096 100644
--- a/packages/flutter/lib/src/material/button.dart
+++ b/packages/flutter/lib/src/material/button.dart
@@ -241,6 +241,8 @@
   final bool autofocus;
 
   /// {@macro flutter.widgets.Clip}
+  ///
+  /// Defaults to [Clip.none], and must not be null.
   final Clip clipBehavior;
 
   @override
diff --git a/packages/flutter/lib/src/material/card.dart b/packages/flutter/lib/src/material/card.dart
index 1ff6aa0..0dcc455 100644
--- a/packages/flutter/lib/src/material/card.dart
+++ b/packages/flutter/lib/src/material/card.dart
@@ -145,6 +145,7 @@
   final bool borderOnForeground;
 
   /// {@macro flutter.widgets.Clip}
+  ///
   /// If this property is null then [ThemeData.cardTheme.clipBehavior] is used.
   /// If that's null then the behavior will be [Clip.none].
   final Clip clipBehavior;
@@ -177,7 +178,6 @@
   final Widget child;
 
   static const double _defaultElevation = 1.0;
-  static const Clip _defaultClipBehavior = Clip.none;
 
   @override
   Widget build(BuildContext context) {
@@ -195,7 +195,7 @@
             borderRadius: BorderRadius.all(Radius.circular(4.0)),
           ),
           borderOnForeground: borderOnForeground,
-          clipBehavior: clipBehavior ?? cardTheme.clipBehavior ?? _defaultClipBehavior,
+          clipBehavior: clipBehavior ?? cardTheme.clipBehavior ?? Clip.none,
           child: Semantics(
             explicitChildNodes: !semanticContainer,
             child: child,
diff --git a/packages/flutter/lib/src/material/chip.dart b/packages/flutter/lib/src/material/chip.dart
index 4cefe3a..6755cb9 100644
--- a/packages/flutter/lib/src/material/chip.dart
+++ b/packages/flutter/lib/src/material/chip.dart
@@ -96,6 +96,8 @@
   ShapeBorder get shape;
 
   /// {@macro flutter.widgets.Clip}
+  ///
+  /// Defaults to [Clip.none], and must not be null.
   Clip get clipBehavior;
 
   /// {@macro flutter.widgets.Focus.focusNode}
@@ -1227,6 +1229,7 @@
     this.elevation,
     this.shadowColor,
   }) : assert(label != null),
+       assert(clipBehavior != null),
        assert(autofocus != null),
        assert(
          onPressed != null,
diff --git a/packages/flutter/lib/src/material/flat_button.dart b/packages/flutter/lib/src/material/flat_button.dart
index 9dec828..bd84a66 100644
--- a/packages/flutter/lib/src/material/flat_button.dart
+++ b/packages/flutter/lib/src/material/flat_button.dart
@@ -115,12 +115,13 @@
     Brightness colorBrightness,
     EdgeInsetsGeometry padding,
     ShapeBorder shape,
-    Clip clipBehavior,
+    Clip clipBehavior = Clip.none,
     FocusNode focusNode,
     bool autofocus = false,
     MaterialTapTargetSize materialTapTargetSize,
     @required Widget child,
-  }) : assert(autofocus != null),
+  }) : assert(clipBehavior != null),
+       assert(autofocus != null),
        super(
          key: key,
          onPressed: onPressed,
@@ -196,7 +197,7 @@
       padding: buttonTheme.getPadding(this),
       constraints: buttonTheme.getConstraints(this),
       shape: buttonTheme.getShape(this),
-      clipBehavior: clipBehavior ?? Clip.none,
+      clipBehavior: clipBehavior,
       focusNode: focusNode,
       autofocus: autofocus,
       materialTapTargetSize: buttonTheme.getMaterialTapTargetSize(this),
@@ -227,7 +228,7 @@
     Brightness colorBrightness,
     EdgeInsetsGeometry padding,
     ShapeBorder shape,
-    Clip clipBehavior,
+    Clip clipBehavior = Clip.none,
     FocusNode focusNode,
     bool autofocus = false,
     MaterialTapTargetSize materialTapTargetSize,
@@ -235,6 +236,7 @@
     @required Widget label,
   }) : assert(icon != null),
        assert(label != null),
+       assert(clipBehavior != null),
        assert(autofocus != null),
        super(
          key: key,
diff --git a/packages/flutter/lib/src/material/floating_action_button.dart b/packages/flutter/lib/src/material/floating_action_button.dart
index 31f32ed..4910f95 100644
--- a/packages/flutter/lib/src/material/floating_action_button.dart
+++ b/packages/flutter/lib/src/material/floating_action_button.dart
@@ -122,7 +122,7 @@
 class FloatingActionButton extends StatelessWidget {
   /// Creates a circular floating action button.
   ///
-  /// The [mini] and [clipBehavior] arguments must be non-null. Additionally,
+  /// The [mini] and [clipBehavior] arguments must not be null. Additionally,
   /// [elevation], [highlightElevation], and [disabledElevation] (if specified)
   /// must be non-negative.
   const FloatingActionButton({
@@ -154,6 +154,7 @@
        assert(highlightElevation == null || highlightElevation >= 0.0),
        assert(disabledElevation == null || disabledElevation >= 0.0),
        assert(mini != null),
+       assert(clipBehavior != null),
        assert(isExtended != null),
        assert(autofocus != null),
        _sizeConstraints = mini ? _kMiniSizeConstraints : _kSizeConstraints,
@@ -162,7 +163,7 @@
   /// Creates a wider [StadiumBorder]-shaped floating action button with
   /// an optional [icon] and a [label].
   ///
-  /// The [label], [autofocus], and [clipBehavior] arguments must non-null.
+  /// The [label], [autofocus], and [clipBehavior] arguments must not be null.
   /// Additionally, [elevation], [highlightElevation], and [disabledElevation]
   /// (if specified) must be non-negative.
   FloatingActionButton.extended({
@@ -194,6 +195,7 @@
        assert(highlightElevation == null || highlightElevation >= 0.0),
        assert(disabledElevation == null || disabledElevation >= 0.0),
        assert(isExtended != null),
+       assert(clipBehavior != null),
        assert(autofocus != null),
        _sizeConstraints = _kExtendedSizeConstraints,
        mini = false,
@@ -363,6 +365,8 @@
   final ShapeBorder shape;
 
   /// {@macro flutter.widgets.Clip}
+  ///
+  /// Defaults to [Clip.none], and must not be null.
   final Clip clipBehavior;
 
   /// True if this is an "extended" floating action button.
@@ -463,7 +467,7 @@
       splashColor: splashColor,
       textStyle: textStyle,
       shape: shape,
-      clipBehavior: clipBehavior ?? Clip.none,
+      clipBehavior: clipBehavior,
       focusNode: focusNode,
       autofocus: autofocus,
       child: child,
diff --git a/packages/flutter/lib/src/material/material.dart b/packages/flutter/lib/src/material/material.dart
index 293d1fc..3ef5c75 100644
--- a/packages/flutter/lib/src/material/material.dart
+++ b/packages/flutter/lib/src/material/material.dart
@@ -157,9 +157,9 @@
 class Material extends StatefulWidget {
   /// Creates a piece of material.
   ///
-  /// The [type], [elevation], [shadowColor], [borderOnForeground] and
-  /// [animationDuration] arguments must not be null. Additionally, [elevation]
-  /// must be non-negative.
+  /// The [type], [elevation], [shadowColor], [borderOnForeground],
+  /// [clipBehavior], and [animationDuration] arguments must not be null.
+  /// Additionally, [elevation] must be non-negative.
   ///
   /// If a [shape] is specified, then the [borderRadius] property must be
   /// null and the [type] property must not be [MaterialType.circle]. If the
@@ -185,8 +185,8 @@
        assert(!(shape != null && borderRadius != null)),
        assert(animationDuration != null),
        assert(!(identical(type, MaterialType.circle) && (borderRadius != null || shape != null))),
-       assert(clipBehavior != null),
        assert(borderOnForeground != null),
+       assert(clipBehavior != null),
        super(key: key);
 
   /// The widget below this widget in the tree.
@@ -264,6 +264,8 @@
   /// See the enum [Clip] for details of all possible options and their common
   /// use cases.
   /// {@endtemplate}
+  ///
+  /// Defaults to [Clip.none], and must not be null.
   final Clip clipBehavior;
 
   /// Defines the duration of animated changes for [shape], [elevation],
@@ -670,6 +672,11 @@
 ///
 /// Animates [elevation], [shadowColor], and [shape].
 class _MaterialInterior extends ImplicitlyAnimatedWidget {
+  /// Creates a const instance of [_MaterialInterior].
+  ///
+  /// The [child], [shape], [clipBehavior], [color], and [shadowColor] arguments
+  /// must not be null. The [elevation] must be specified and greater than or
+  /// equal to zero.
   const _MaterialInterior({
     Key key,
     @required this.child,
@@ -707,6 +714,8 @@
   final bool borderOnForeground;
 
   /// {@macro flutter.widgets.Clip}
+  ///
+  /// Defaults to [Clip.none], and must not be null.
   final Clip clipBehavior;
 
   /// The target z-coordinate at which to place this physical object relative
diff --git a/packages/flutter/lib/src/material/material_button.dart b/packages/flutter/lib/src/material/material_button.dart
index 600050a..461b20d 100644
--- a/packages/flutter/lib/src/material/material_button.dart
+++ b/packages/flutter/lib/src/material/material_button.dart
@@ -77,7 +77,8 @@
     this.minWidth,
     this.height,
     this.child,
-  }) : assert(autofocus != null),
+  }) : assert(clipBehavior != null),
+       assert(autofocus != null),
        assert(elevation == null || elevation >= 0.0),
        assert(focusElevation == null || focusElevation >= 0.0),
        assert(hoverElevation == null || hoverElevation >= 0.0),
@@ -306,6 +307,8 @@
   final ShapeBorder shape;
 
   /// {@macro flutter.widgets.Clip}
+  ///
+  /// Defaults to [Clip.none], and must not be null.
   final Clip clipBehavior;
 
   /// {@macro flutter.widgets.Focus.focusNode}
@@ -362,7 +365,7 @@
         minHeight: height,
       ),
       shape: buttonTheme.getShape(this),
-      clipBehavior: clipBehavior ?? Clip.none,
+      clipBehavior: clipBehavior,
       focusNode: focusNode,
       animationDuration: buttonTheme.getAnimationDuration(this),
       child: child,
diff --git a/packages/flutter/lib/src/material/outline_button.dart b/packages/flutter/lib/src/material/outline_button.dart
index fda1ab9..4e672d1 100644
--- a/packages/flutter/lib/src/material/outline_button.dart
+++ b/packages/flutter/lib/src/material/outline_button.dart
@@ -75,11 +75,12 @@
     this.highlightedBorderColor,
     EdgeInsetsGeometry padding,
     ShapeBorder shape,
-    Clip clipBehavior,
+    Clip clipBehavior = Clip.none,
     FocusNode focusNode,
     bool autofocus = false,
     Widget child,
   }) : assert(highlightElevation == null || highlightElevation >= 0.0),
+       assert(clipBehavior != null),
        assert(autofocus != null),
        super(
          key: key,
@@ -220,12 +221,13 @@
     BorderSide borderSide,
     EdgeInsetsGeometry padding,
     ShapeBorder shape,
-    Clip clipBehavior,
+    Clip clipBehavior = Clip.none,
     FocusNode focusNode,
     bool autofocus = false,
     @required Widget icon,
     @required Widget label,
   }) : assert(highlightElevation == null || highlightElevation >= 0.0),
+       assert(clipBehavior != null),
        assert(autofocus != null),
        assert(icon != null),
        assert(label != null),
@@ -279,12 +281,13 @@
     @required this.highlightedBorderColor,
     this.padding,
     this.shape,
-    this.clipBehavior,
+    this.clipBehavior = Clip.none,
     this.focusNode,
     this.autofocus = false,
     this.child,
   }) : assert(highlightElevation != null && highlightElevation >= 0.0),
        assert(highlightedBorderColor != null),
+       assert(clipBehavior != null),
        assert(autofocus != null),
        super(key: key);
 
diff --git a/packages/flutter/lib/src/material/raised_button.dart b/packages/flutter/lib/src/material/raised_button.dart
index dfb4cc5..17cd6f6 100644
--- a/packages/flutter/lib/src/material/raised_button.dart
+++ b/packages/flutter/lib/src/material/raised_button.dart
@@ -126,7 +126,7 @@
     double disabledElevation,
     EdgeInsetsGeometry padding,
     ShapeBorder shape,
-    Clip clipBehavior,
+    Clip clipBehavior = Clip.none,
     FocusNode focusNode,
     bool autofocus = false,
     MaterialTapTargetSize materialTapTargetSize,
@@ -138,6 +138,7 @@
        assert(hoverElevation == null || hoverElevation >= 0.0),
        assert(highlightElevation == null || highlightElevation >= 0.0),
        assert(disabledElevation == null || disabledElevation >= 0.0),
+       assert(clipBehavior != null),
        super(
          key: key,
          onPressed: onPressed,
@@ -209,7 +210,7 @@
     return RawMaterialButton(
       onPressed: onPressed,
       onHighlightChanged: onHighlightChanged,
-      clipBehavior: clipBehavior ?? Clip.none,
+      clipBehavior: clipBehavior,
       fillColor: buttonTheme.getFillColor(this),
       textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)),
       focusColor: buttonTheme.getFocusColor(this),
@@ -276,6 +277,7 @@
   }) : assert(elevation == null || elevation >= 0.0),
        assert(highlightElevation == null || highlightElevation >= 0.0),
        assert(disabledElevation == null || disabledElevation >= 0.0),
+       assert(clipBehavior != null),
        assert(icon != null),
        assert(label != null),
        assert(autofocus != null),
diff --git a/packages/flutter/lib/src/rendering/layer.dart b/packages/flutter/lib/src/rendering/layer.dart
index 32c324d..8321b0f 100644
--- a/packages/flutter/lib/src/rendering/layer.dart
+++ b/packages/flutter/lib/src/rendering/layer.dart
@@ -1058,8 +1058,10 @@
 class ClipRectLayer extends ContainerLayer {
   /// Creates a layer with a rectangular clip.
   ///
-  /// The [clipRect] and [clipBehavior] properties must be non-null before the
-  /// compositing phase of the pipeline.
+  /// The [clipRect] argument must not be null before the compositing phase of
+  /// the pipeline.
+  ///
+  /// The [clipBehavior] argument must not be null, and must not be [Clip.none].
   ClipRectLayer({
     Rect clipRect,
     Clip clipBehavior = Clip.hardEdge,
@@ -1082,10 +1084,12 @@
   }
 
   /// {@template flutter.clipper.clipBehavior}
-  /// Controls how to clip (defaults to [Clip.hardEdge]).
+  /// Controls how to clip.
   ///
-  /// [Clip.none] is not allowed here.
+  /// Must not be set to null or [Clip.none].
   /// {@endtemplate}
+  ///
+  /// Defaults to [Clip.hardEdge].
   Clip get clipBehavior => _clipBehavior;
   Clip _clipBehavior;
   set clipBehavior(Clip value) {
@@ -1170,6 +1174,8 @@
   }
 
   /// {@macro flutter.clipper.clipBehavior}
+  ///
+  /// Defaults to [Clip.antiAlias].
   Clip get clipBehavior => _clipBehavior;
   Clip _clipBehavior;
   set clipBehavior(Clip value) {
@@ -1254,6 +1260,8 @@
   }
 
   /// {@macro flutter.clipper.clipBehavior}
+  ///
+  /// Defaults to [Clip.antiAlias].
   Clip get clipBehavior => _clipBehavior;
   Clip _clipBehavior;
   set clipBehavior(Clip value) {
diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart
index 308ec1f..a54c7d9 100644
--- a/packages/flutter/lib/src/rendering/proxy_box.dart
+++ b/packages/flutter/lib/src/rendering/proxy_box.dart
@@ -1285,12 +1285,14 @@
   /// If [clipper] is null, the clip will match the layout size and position of
   /// the child.
   ///
-  /// The [clipBehavior] cannot be [Clip.none].
+  /// The [clipBehavior] must not be null or [Clip.none].
   RenderClipRect({
     RenderBox child,
     CustomClipper<Rect> clipper,
     Clip clipBehavior = Clip.antiAlias,
-  }) : super(child: child, clipper: clipper, clipBehavior: clipBehavior);
+  }) : assert(clipBehavior != null),
+       assert(clipBehavior != Clip.none),
+       super(child: child, clipper: clipper, clipBehavior: clipBehavior);
 
   @override
   Rect get _defaultClip => Offset.zero & size;
@@ -1342,13 +1344,14 @@
   ///
   /// If [clipper] is non-null, then [borderRadius] is ignored.
   ///
-  /// The [clipBehavior] cannot be [Clip.none].
+  /// The [clipBehavior] argument must not be null or [Clip.none].
   RenderClipRRect({
     RenderBox child,
     BorderRadius borderRadius = BorderRadius.zero,
     CustomClipper<RRect> clipper,
     Clip clipBehavior = Clip.antiAlias,
-  }) : assert(clipBehavior != Clip.none),
+  }) : assert(clipBehavior != null),
+       assert(clipBehavior != Clip.none),
        _borderRadius = borderRadius,
        super(child: child, clipper: clipper, clipBehavior: clipBehavior) {
     assert(_borderRadius != null || clipper != null);
@@ -1418,12 +1421,13 @@
   /// If [clipper] is null, the oval will be inscribed into the layout size and
   /// position of the child.
   ///
-  /// The [clipBehavior] cannot be [Clip.none].
+  /// The [clipBehavior] argument must not be null or [Clip.none].
   RenderClipOval({
     RenderBox child,
     CustomClipper<Rect> clipper,
     Clip clipBehavior = Clip.antiAlias,
-  }) : assert(clipBehavior != Clip.none),
+  }) : assert(clipBehavior != null),
+       assert(clipBehavior != Clip.none),
        super(child: child, clipper: clipper, clipBehavior: clipBehavior);
 
   Rect _cachedRect;
@@ -1496,12 +1500,13 @@
   /// consider using a [RenderClipRect], which can achieve the same effect more
   /// efficiently.
   ///
-  /// The [clipBehavior] cannot be [Clip.none].
+  /// The [clipBehavior] argument must not be null or [Clip.none].
   RenderClipPath({
     RenderBox child,
     CustomClipper<Path> clipper,
     Clip clipBehavior = Clip.antiAlias,
-  }) : assert(clipBehavior != Clip.none),
+  }) : assert(clipBehavior != null),
+       assert(clipBehavior != Clip.none),
        super(child: child, clipper: clipper, clipBehavior: clipBehavior);
 
   @override
@@ -1632,8 +1637,9 @@
   ///
   /// The [color] is required.
   ///
-  /// The [shape], [elevation], [color], and [shadowColor] must not be null.
-  /// Additionally, the [elevation] must be non-negative.
+  /// The [shape], [elevation], [color], [clipBehavior], and [shadowColor]
+  /// arguments must not be null. Additionally, the [elevation] must be
+  /// non-negative.
   RenderPhysicalModel({
     RenderBox child,
     BoxShape shape = BoxShape.rectangle,
diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart
index c06e93c..d606c95 100644
--- a/packages/flutter/lib/src/widgets/basic.dart
+++ b/packages/flutter/lib/src/widgets/basic.dart
@@ -582,19 +582,29 @@
   ///
   /// If [clipper] is null, the clip will match the layout size and position of
   /// the child.
-  const ClipRect({ Key key, this.clipper, this.clipBehavior = Clip.hardEdge, Widget child }) : super(key: key, child: child);
+  ///
+  /// The [clipBehavior] argument must not be null or [Clip.none].
+  const ClipRect({ Key key, this.clipper, this.clipBehavior = Clip.hardEdge, Widget child })
+      : assert(clipBehavior != null),
+        super(key: key, child: child);
 
   /// If non-null, determines which clip to use.
   final CustomClipper<Rect> clipper;
 
   /// {@macro flutter.clipper.clipBehavior}
+  ///
+  /// Defaults to [Clip.hardEdge].
   final Clip clipBehavior;
 
   @override
-  RenderClipRect createRenderObject(BuildContext context) => RenderClipRect(clipper: clipper, clipBehavior: clipBehavior);
+  RenderClipRect createRenderObject(BuildContext context) {
+    assert(clipBehavior != Clip.none);
+    return RenderClipRect(clipper: clipper, clipBehavior: clipBehavior);
+  }
 
   @override
   void updateRenderObject(BuildContext context, RenderClipRect renderObject) {
+    assert(clipBehavior != Clip.none);
     renderObject
       ..clipper = clipper
       ..clipBehavior = clipBehavior;
@@ -633,6 +643,8 @@
   /// right-angled corners.
   ///
   /// If [clipper] is non-null, then [borderRadius] is ignored.
+  ///
+  /// The [clipBehavior] argument must not be null or [Clip.none].
   const ClipRRect({
     Key key,
     this.borderRadius,
@@ -655,13 +667,19 @@
   final CustomClipper<RRect> clipper;
 
   /// {@macro flutter.clipper.clipBehavior}
+  ///
+  /// Defaults to [Clip.antiAlias].
   final Clip clipBehavior;
 
   @override
-  RenderClipRRect createRenderObject(BuildContext context) => RenderClipRRect(borderRadius: borderRadius, clipper: clipper, clipBehavior: clipBehavior);
+  RenderClipRRect createRenderObject(BuildContext context) {
+    assert(clipBehavior != Clip.none);
+    return RenderClipRRect(borderRadius: borderRadius, clipper: clipper, clipBehavior: clipBehavior);
+  }
 
   @override
   void updateRenderObject(BuildContext context, RenderClipRRect renderObject) {
+    assert(clipBehavior != Clip.none);
     renderObject
       ..borderRadius = borderRadius
       ..clipBehavior = clipBehavior
@@ -693,7 +711,11 @@
   ///
   /// If [clipper] is null, the oval will be inscribed into the layout size and
   /// position of the child.
-  const ClipOval({ Key key, this.clipper, this.clipBehavior = Clip.antiAlias, Widget child }) : super(key: key, child: child);
+  ///
+  /// The [clipBehavior] argument must not be null or [Clip.none].
+  const ClipOval({Key key, this.clipper, this.clipBehavior = Clip.antiAlias, Widget child})
+      : assert(clipBehavior != null),
+        super(key: key, child: child);
 
   /// If non-null, determines which clip to use.
   ///
@@ -707,13 +729,19 @@
   final CustomClipper<Rect> clipper;
 
   /// {@macro flutter.clipper.clipBehavior}
+  ///
+  /// Defaults to [Clip.antiAlias].
   final Clip clipBehavior;
 
   @override
-  RenderClipOval createRenderObject(BuildContext context) => RenderClipOval(clipper: clipper, clipBehavior: clipBehavior);
+  RenderClipOval createRenderObject(BuildContext context) {
+    assert(clipBehavior != Clip.none);
+    return RenderClipOval(clipper: clipper, clipBehavior: clipBehavior);
+  }
 
   @override
   void updateRenderObject(BuildContext context, RenderClipOval renderObject) {
+    assert(clipBehavior != Clip.none);
     renderObject
       ..clipper = clipper
       ..clipBehavior = clipBehavior;
@@ -754,12 +782,15 @@
   /// size and location of the child. However, rather than use this default,
   /// consider using a [ClipRect], which can achieve the same effect more
   /// efficiently.
+  ///
+  /// The [clipBehavior] argument must not be null or [Clip.none].
   const ClipPath({
     Key key,
     this.clipper,
     this.clipBehavior = Clip.antiAlias,
     Widget child,
-  }) : super(key: key, child: child);
+  }) : assert(clipBehavior != null),
+       super(key: key, child: child);
 
   /// Creates a shape clip.
   ///
@@ -771,6 +802,8 @@
     Clip clipBehavior = Clip.antiAlias,
     Widget child,
   }) {
+    assert(clipBehavior != null);
+    assert(clipBehavior != Clip.none);
     assert(shape != null);
     return Builder(
       key: key,
@@ -795,13 +828,19 @@
   final CustomClipper<Path> clipper;
 
   /// {@macro flutter.clipper.clipBehavior}
+  ///
+  /// Defaults to [Clip.antiAlias].
   final Clip clipBehavior;
 
   @override
-  RenderClipPath createRenderObject(BuildContext context) => RenderClipPath(clipper: clipper, clipBehavior: clipBehavior);
+  RenderClipPath createRenderObject(BuildContext context) {
+    assert(clipBehavior != Clip.none);
+    return RenderClipPath(clipper: clipper, clipBehavior: clipBehavior);
+  }
 
   @override
   void updateRenderObject(BuildContext context, RenderClipPath renderObject) {
+    assert(clipBehavior != Clip.none);
     renderObject
       ..clipper = clipper
       ..clipBehavior = clipBehavior;
@@ -838,8 +877,8 @@
   ///
   /// The [color] is required; physical things have a color.
   ///
-  /// The [shape], [elevation], [color], and [shadowColor] must not be null.
-  /// Additionally, the [elevation] must be non-negative.
+  /// The [shape], [elevation], [color], [clipBehavior], and [shadowColor] must
+  /// not be null. Additionally, the [elevation] must be non-negative.
   const PhysicalModel({
     Key key,
     this.shape = BoxShape.rectangle,
@@ -853,12 +892,15 @@
        assert(elevation != null && elevation >= 0.0),
        assert(color != null),
        assert(shadowColor != null),
+       assert(clipBehavior != null),
        super(key: key, child: child);
 
   /// The type of shape.
   final BoxShape shape;
 
   /// {@macro flutter.widgets.Clip}
+  ///
+  /// Defaults to [Clip.none].
   final Clip clipBehavior;
 
   /// The border radius of the rounded corners.
@@ -931,8 +973,8 @@
   ///
   /// The [color] is required; physical things have a color.
   ///
-  /// The [clipper], [elevation], [color], and [shadowColor] must not be null.
-  /// Additionally, the [elevation] must be non-negative.
+  /// The [clipper], [elevation], [color], [clipBehavior], and [shadowColor]
+  /// must not be null. Additionally, the [elevation] must be non-negative.
   const PhysicalShape({
     Key key,
     @required this.clipper,
@@ -956,6 +998,8 @@
   final CustomClipper<Path> clipper;
 
   /// {@macro flutter.widgets.Clip}
+  ///
+  /// Defaults to [Clip.none].
   final Clip clipBehavior;
 
   /// The z-coordinate relative to the parent at which to place this physical
diff --git a/packages/flutter/lib/src/widgets/implicit_animations.dart b/packages/flutter/lib/src/widgets/implicit_animations.dart
index 0667368..4631ce4 100644
--- a/packages/flutter/lib/src/widgets/implicit_animations.dart
+++ b/packages/flutter/lib/src/widgets/implicit_animations.dart
@@ -1450,9 +1450,9 @@
 class AnimatedPhysicalModel extends ImplicitlyAnimatedWidget {
   /// Creates a widget that animates the properties of a [PhysicalModel].
   ///
-  /// The [child], [shape], [borderRadius], [elevation], [color], [shadowColor], [curve], and
-  /// [duration] arguments must not be null. Additionally, [elevation] must be
-  /// non-negative.
+  /// The [child], [shape], [borderRadius], [elevation], [color], [shadowColor],
+  /// [curve], [clipBehavior], and [duration] arguments must not be null.
+  /// Additionally, [elevation] must be non-negative.
   ///
   /// Animating [color] is optional and is controlled by the [animateColor] flag.
   ///
@@ -1492,6 +1492,8 @@
   final BoxShape shape;
 
   /// {@macro flutter.widgets.Clip}
+  ///
+  /// Defaults to [Clip.none].
   final Clip clipBehavior;
 
   /// The target border radius of the rounded corners for a rectangle shape.
diff --git a/packages/flutter/test/material/card_test.dart b/packages/flutter/test/material/card_test.dart
index 0e9e73c..e021d45 100644
--- a/packages/flutter/test/material/card_test.dart
+++ b/packages/flutter/test/material/card_test.dart
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'package:flutter/painting.dart';
 import 'package:flutter/rendering.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/widgets.dart';
@@ -171,4 +172,19 @@
     await tester.pumpWidget(const Card(clipBehavior: Clip.antiAlias));
     expect(tester.widget<Material>(find.byType(Material)).clipBehavior, Clip.antiAlias);
   });
+
+  testWidgets('Card clipBehavior property defers to theme when null', (WidgetTester tester) async {
+    await tester.pumpWidget(Builder(builder: (BuildContext context) {
+      final ThemeData themeData = Theme.of(context);
+      return Theme(
+        data: themeData.copyWith(
+          cardTheme: themeData.cardTheme.copyWith(
+            clipBehavior: Clip.antiAliasWithSaveLayer,
+          ),
+        ),
+        child: const Card(clipBehavior: null),
+      );
+    }));
+    expect(tester.widget<Material>(find.byType(Material)).clipBehavior, Clip.antiAliasWithSaveLayer);
+  });
 }
diff --git a/packages/flutter/test/material/material_test.dart b/packages/flutter/test/material/material_test.dart
index d3afca7..2cc7f82 100644
--- a/packages/flutter/test/material/material_test.dart
+++ b/packages/flutter/test/material/material_test.dart
@@ -300,6 +300,22 @@
       expect(find.byKey(materialKey), hasNoImmediateClip);
     });
 
+    testWidgets('Null clipBehavior asserts', (WidgetTester tester) async {
+      final GlobalKey materialKey = GlobalKey();
+      Future<void> doPump() async {
+        await tester.pumpWidget(
+            Material(
+              key: materialKey,
+              type: MaterialType.transparency,
+              child: const SizedBox(width: 100.0, height: 100.0),
+              clipBehavior: null,
+            )
+        );
+      }
+
+      expect(() async => doPump(), throwsAssertionError);
+    });
+
     testWidgets('clips to bounding rect by default given Clip.antiAlias', (WidgetTester tester) async {
       final GlobalKey materialKey = GlobalKey();
       await tester.pumpWidget(