diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 24bcd70b26cb0c4afb453b8202c29dec046edb13..abdc32eb7d41bc1c2dff67fdfe337a47cdd9065e 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -159,6 +159,7 @@ static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
 static tree handle_copy_attribute (tree *, tree, tree, int, bool *);
 static tree handle_nsobject_attribute (tree *, tree, tree, int, bool *);
 static tree handle_objc_root_class_attribute (tree *, tree, tree, int, bool *);
+static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool *);
 
 /* Helper to define attribute exclusions.  */
 #define ATTR_EXCL(name, function, type, variable)	\
@@ -516,6 +517,8 @@ const struct attribute_spec c_common_attribute_table[] =
 			      handle_nsobject_attribute, NULL },
   { "objc_root_class",	      0, 0, true, false, false, false,
 			      handle_objc_root_class_attribute, NULL },
+  { "objc_nullability",	      1, 1, true, false, false, false,
+			      handle_objc_nullability_attribute, NULL },
   { NULL,                     0, 0, false, false, false, false, NULL, NULL }
 };
 
@@ -5182,6 +5185,52 @@ handle_objc_root_class_attribute (tree */*node*/, tree name, tree /*args*/,
   return NULL_TREE;
 }
 
+/* Handle an "objc_nullability" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_objc_nullability_attribute (tree *node, tree name, tree args,
+				   int /*flags*/,
+				   bool *no_add_attrs)
+{
+  *no_add_attrs = true;
+
+  tree type = TREE_TYPE (*node);
+  if (TREE_CODE (*node) == FUNCTION_DECL)
+    type = TREE_TYPE (type);
+
+  if (type && !POINTER_TYPE_P (type))
+    {
+      error ("%qE cannot be applied to non-pointer type %qT", name, type);
+      return NULL_TREE;
+    }
+
+  /* We accept objc_nullability() with a single argument.
+     string: "unspecified", "nullable", "nonnull" or "resettable"
+     integer: 0 and 3 where the values have the same meaning as
+     the strings.  */
+  tree val = TREE_VALUE (args);
+  if (TREE_CODE (val) == INTEGER_CST)
+    {
+      val = default_conversion (val);
+      if (!tree_fits_uhwi_p (val) || tree_to_uhwi (val) > 3)
+	error ("%qE attribute argument %qE is not an integer constant"
+	       " between 0 and 3", name, val);
+      else
+	*no_add_attrs = false; /* OK */
+    }
+  else if (TREE_CODE (val) == STRING_CST
+	   && (strcmp (TREE_STRING_POINTER (val), "nullable") == 0
+	      || strcmp (TREE_STRING_POINTER (val), "nonnull") == 0
+	      || strcmp (TREE_STRING_POINTER (val), "unspecified") == 0
+	      || strcmp (TREE_STRING_POINTER (val), "resettable") == 0))
+    *no_add_attrs = false; /* OK */
+  else if (val != error_mark_node)
+    error ("%qE attribute argument %qE is not recognised", name, val);
+
+  return NULL_TREE;
+}
+
 /* Attempt to partially validate a single attribute ATTR as if
    it were to be applied to an entity OPER.  */
 
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 29508bca97b5b9482b45164104c66b98f4920fbf..ab7f64272740b02ae7b1111921bbdb0181b614c5 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -580,6 +580,12 @@ const struct c_common_resword c_common_reswords[] =
   { "readwrite",	RID_READWRITE,		D_OBJC },
   { "retain",		RID_RETAIN,		D_OBJC },
   { "setter",		RID_SETTER,		D_OBJC },
+  /* These are Objective C implementation of nullability, accepted only in
+     specific contexts.  */
+  { "null_unspecified", RID_NULL_UNSPECIFIED,	D_OBJC },
+  { "nullable",		RID_NULLABLE,		D_OBJC },
+  { "nonnull",		RID_NONNULL,		D_OBJC },
+  { "null_resettable",	RID_NULL_RESETTABLE,	D_OBJC },
 };
 
 const unsigned int num_c_common_reswords =
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index f47097442ebab0b65cf7c05216305cf3f7ef81aa..3c508979b144e5767a8132a1c1e02c3c58136407 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -87,6 +87,11 @@ enum rid
   RID_ASSIGN, RID_RETAIN, RID_COPY,
   RID_PROPATOMIC, RID_NONATOMIC,
 
+  /* ObjC nullability support keywords that also can appear in the
+     property attribute context.  These values should remain contiguous
+     with the other property attributes.  */
+  RID_NULL_UNSPECIFIED, RID_NULLABLE, RID_NONNULL, RID_NULL_RESETTABLE,
+
   /* C (reserved and imaginary types not implemented, so any use is a
      syntax error) */
   RID_IMAGINARY,
@@ -264,7 +269,7 @@ enum rid
   RID_FIRST_PQ = RID_IN,
   RID_LAST_PQ = RID_ONEWAY,
   RID_FIRST_PATTR = RID_GETTER,
-  RID_LAST_PATTR = RID_NONATOMIC
+  RID_LAST_PATTR = RID_NULL_RESETTABLE
 };
 
 #define OBJC_IS_AT_KEYWORD(rid) \
diff --git a/gcc/c-family/c-objc.h b/gcc/c-family/c-objc.h
index 9414aecc668a7d9d537c92c2a6fe5ef23c63431d..4b502609eaa953286903115c7348254ebc61a798 100644
--- a/gcc/c-family/c-objc.h
+++ b/gcc/c-family/c-objc.h
@@ -44,6 +44,7 @@ enum objc_property_attribute_group
   OBJC_PROPATTR_GROUP_READWRITE,
   OBJC_PROPATTR_GROUP_ASSIGN,
   OBJC_PROPATTR_GROUP_ATOMIC,
+  OBJC_PROPATTR_GROUP_NULLABLE,
   OBJC_PROPATTR_GROUP_CLASS,
   OBJC_PROPATTR_GROUP_MAX
 };
@@ -60,6 +61,10 @@ enum objc_property_attribute_kind
   OBJC_PROPERTY_ATTR_COPY =		( 7 << 8)|OBJC_PROPATTR_GROUP_ASSIGN,
   OBJC_PROPERTY_ATTR_ATOMIC =		( 8 << 8)|OBJC_PROPATTR_GROUP_ATOMIC,
   OBJC_PROPERTY_ATTR_NONATOMIC =	( 9 << 8)|OBJC_PROPATTR_GROUP_ATOMIC,
+  OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED = (12 << 8)|OBJC_PROPATTR_GROUP_NULLABLE,
+  OBJC_PROPERTY_ATTR_NULLABLE =		(13 << 8)|OBJC_PROPATTR_GROUP_NULLABLE,
+  OBJC_PROPERTY_ATTR_NONNULL =		(14 << 8)|OBJC_PROPATTR_GROUP_NULLABLE,
+  OBJC_PROPERTY_ATTR_NULL_RESETTABLE =	(15 << 8)|OBJC_PROPATTR_GROUP_NULLABLE,
   OBJC_PROPERTY_ATTR_CLASS =		(16 << 8)|OBJC_PROPATTR_GROUP_CLASS,
   OBJC_PROPERTY_ATTR_MAX =		(255 << 8|OBJC_PROPATTR_GROUP_MAX)
 };
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index c353eb432b961512500e1d0b7c9928b3cef342da..4e5197fc038fa0762fd5028f29864e8af6a5de46 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7429,6 +7429,33 @@ data in this way can reduce program startup times.  This attribute is
 specific to ELF targets and relies on the linker to place such data in
 the right location
 
+@item objc_nullability (@var{nullability kind}) @r{(Objective-C and Objective
+-C++ only)}
+@cindex @code{objc_nullability} variable attribute
+This attribute applies to pointer variables only.  It allows marking the
+pointer with one of four possible values describing the conditions under
+which the pointer might have a @code{nil} value. In most cases, the
+attribute is intended to be an internal representation for property and
+method nullability (specified by language keywords); it is not recommended
+to use it directly.
+
+When @var{nullability kind} is @code{"unspecified"} or @code{0}, nothing is
+known about the conditions in which the pointer might be @code{nil}. Making
+this state specific serves to avoid false positives in diagnostics.
+
+When @var{nullability kind} is @code{"nonnull"} or @code{1}, the pointer has
+no meaning if it is @code{nil} and thus the compiler is free to emit
+diagnostics if it can be determined that the value will be @code{nil}.
+
+When @var{nullability kind} is @code{"nullable"} or @code{2}, the pointer might
+be @code{nil} and carry meaning as such.
+
+When @var{nullability kind} is @code{"resettable"} or @code{3} (used only in
+the context of property attribute lists) this describes the case in which a
+property setter may take the value @code{nil} (which perhaps causes the
+property to be reset in some manner to a default) but for which the property
+getter will never validly return @code{nil}.
+
 @end table
 
 @node ARC Variable Attributes
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index e4103860aae98b24745c7239d00b0124eebc7240..2700bbee639562ecc4d65378ddda81d13f72c788 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -825,6 +825,11 @@ objc_prop_attr_kind_for_rid (enum rid prop_rid)
       case RID_PROPATOMIC:	return OBJC_PROPERTY_ATTR_ATOMIC;
       case RID_NONATOMIC:	return OBJC_PROPERTY_ATTR_NONATOMIC;
 
+      case RID_NULL_UNSPECIFIED:return OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED;
+      case RID_NULLABLE:	return OBJC_PROPERTY_ATTR_NULLABLE;
+      case RID_NONNULL:		return OBJC_PROPERTY_ATTR_NONNULL;
+      case RID_NULL_RESETTABLE:	return OBJC_PROPERTY_ATTR_NULL_RESETTABLE;
+
       case RID_CLASS:		return OBJC_PROPERTY_ATTR_CLASS;
     }
 }
@@ -995,6 +1000,27 @@ objc_add_property_declaration (location_t location, tree decl,
     property_nonatomic = attrs[OBJC_PROPATTR_GROUP_CLASS]->prop_kind
 			 == OBJC_PROPERTY_ATTR_CLASS;
 
+  /* Nullability specifications for the property.  */
+  enum objc_property_nullability property_nullability
+    =  OBJC_PROPERTY_NULL_UNSET;
+  if (attrs[OBJC_PROPATTR_GROUP_NULLABLE])
+    {
+      if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
+	  == OBJC_PROPERTY_ATTR_NULL_UNSPECIFIED)
+	property_nullability = OBJC_PROPERTY_NULL_UNSPECIFIED;
+      else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
+	  == OBJC_PROPERTY_ATTR_NULLABLE)
+	property_nullability = OBJC_PROPERTY_NULLABLE;
+      else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
+	  == OBJC_PROPERTY_ATTR_NONNULL)
+	property_nullability = OBJC_PROPERTY_NONNULL;
+      else if (attrs[OBJC_PROPATTR_GROUP_NULLABLE]->prop_kind
+	  == OBJC_PROPERTY_ATTR_NULL_RESETTABLE)
+	property_nullability = OBJC_PROPERTY_NULL_RESETTABLE;
+      else
+	gcc_unreachable ();
+    }
+
   /* TODO: Check that the property type is an Objective-C object or a
      "POD".  */
 
@@ -1272,7 +1298,8 @@ objc_add_property_declaration (location_t location, tree decl,
   tree property_decl = make_node (PROPERTY_DECL);
 
   /* Copy the basic information from the original decl.  */
-  TREE_TYPE (property_decl) = TREE_TYPE (decl);
+  tree p_type = TREE_TYPE (decl);
+  TREE_TYPE (property_decl) = p_type;
   DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
   TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
 
@@ -1287,6 +1314,28 @@ objc_add_property_declaration (location_t location, tree decl,
   PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
   PROPERTY_DYNAMIC (property_decl) = 0;
 
+  /* FIXME: We seem to drop any existing DECL_ATTRIBUTES on the floor.  */
+  if (property_nullability != OBJC_PROPERTY_NULL_UNSET)
+    {
+      if (p_type && !POINTER_TYPE_P (p_type))
+	error_at (decl_loc, "nullability specifier %qE cannot be applied to"
+		  " non-pointer type %qT",
+		  attrs[OBJC_PROPATTR_GROUP_NULLABLE]->name, p_type);
+      else if (p_type && POINTER_TYPE_P (p_type) && TREE_TYPE (p_type)
+	       && POINTER_TYPE_P (TREE_TYPE (p_type)))
+	error_at (decl_loc, "nullability specifier %qE cannot be applied to"
+		  " multi-level pointer type %qT",
+		  attrs[OBJC_PROPATTR_GROUP_NULLABLE]->name, p_type);
+      else
+	{
+	  tree attr_name = get_identifier ("objc_nullability");
+	  tree attr_value = build_int_cst (unsigned_type_node,
+				       (unsigned)property_nullability);
+	  tree nulla = build_tree_list (attr_name, attr_value);
+	  DECL_ATTRIBUTES (property_decl) = nulla;
+	}
+    }
+
   /* Remember the fact that the property was found in the @optional
      section in a @protocol, or not.  */
   if (objc_method_optional_flag)
diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
index 5b0433ff0ee7572792bce11dab6518a478514703..2fe409db4fc95a900dc3f6ad1486c4c642be99ff 100644
--- a/gcc/objc/objc-act.h
+++ b/gcc/objc/objc-act.h
@@ -141,6 +141,16 @@ enum objc_property_assign_semantics {
 #define PROPERTY_CLASS(DECL) \
    DECL_LANG_FLAG_6 (PROPERTY_DECL_CHECK (DECL))
 
+/* PROPERTY_NULLABILITY attributes added to the decl attributes.
+   effectively, __attribute__((objc_nullability(kind))),   */
+enum objc_property_nullability {
+  OBJC_PROPERTY_NULL_UNSPECIFIED = 0,
+  OBJC_PROPERTY_NULLABLE,
+  OBJC_PROPERTY_NONNULL,
+  OBJC_PROPERTY_NULL_RESETTABLE,
+  OBJC_PROPERTY_NULL_UNSET
+};
+
 /* PROPERTY_REF.  A PROPERTY_REF represents an 'object.property'
    expression.  It is normally used for property access, but when
    the Objective-C 2.0 "dot-syntax" (object.component) is used
diff --git a/gcc/testsuite/obj-c++.dg/attributes/nullability-00.mm b/gcc/testsuite/obj-c++.dg/attributes/nullability-00.mm
new file mode 100644
index 0000000000000000000000000000000000000000..957fca4e3ba1dfefcab5d0fa3f7ea1656567a781
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/attributes/nullability-00.mm
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class -fsyntax-only" } */
+
+__attribute__((objc_nullability(0))) id a;
+__attribute__((objc_nullability(4))) id e_1; /* { dg-error {'objc_nullability' attribute argument '4' is not an integer constant between 0 and 3} } */
+__attribute__((objc_nullability(-22))) id e_2; /* { dg-error {'objc_nullability' attribute argument '-22' is not an integer constant between 0 and 3} } */
+__attribute__((objc_nullability("unspecified"))) id b;
+__attribute__((objc_nullability("nullable"))) id c;
+__attribute__((objc_nullability("nonnull"))) id d;
+__attribute__((objc_nullability("resettable"))) id e;
+__attribute__((objc_nullability("nonsense"))) id e_3; /* { dg-error {'objc_nullability' attribute argument '"nonsense"' is not recognised} } */
+__attribute__((objc_nullability(noGoingToWork))) id e_4; /* { dg-error {'noGoingToWork' was not declared in this scope} } */
+
+@interface MyRoot
+{
+  __attribute__((objc_nullability(0))) id iv_a;
+  __attribute__((objc_nullability(3))) struct { int bad_a; } s;/* { dg-error {'objc_nullability' cannot be applied to non-pointer type '<unnamed struct>'} } */
+  __attribute__((objc_nullability("resettable"))) int iv_b;/* { dg-error {'objc_nullability' cannot be applied to non-pointer type 'int'} } */
+}
+@end
diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-4.mm b/gcc/testsuite/obj-c++.dg/property/at-property-4.mm
index f73d70639b6a4a738d268c1e92cbcc2f14ba66ae..f58935401b97f637e43658b59c937c6909e8e032 100644
--- a/gcc/testsuite/obj-c++.dg/property/at-property-4.mm
+++ b/gcc/testsuite/obj-c++.dg/property/at-property-4.mm
@@ -26,12 +26,17 @@
 
 @property (class) int property_cl_1;
 
+@property (null_unspecified) int *property_null_1;
+@property (nullable) int *property_null_2;
+@property (nonnull) int *property_null_3;
+@property (null_resettable) int *property_null_4;
+
 @property (release)   int property_err_1;      /* { dg-error "unknown property attribute" } */
 
 @property (getter=myGetter)  int property_g0;
 @property (setter=mySetter:) int property_s0;
 
-/* Now test various problems.  */
+/* Now test various basic problems.  */
 
 @property (readonly, readwrite) int a;    /* { dg-error ".readwrite. attribute conflicts with .readonly. attribute" } */
 @property (readonly, setter=mySetterB:) int b; /* { dg-error ".readonly. attribute conflicts with .setter. attribute" } */
@@ -42,6 +47,19 @@
 
 @property (atomic, nonatomic) int property_j; /* { dg-error {'nonatomic' attribute conflicts with 'atomic' attribute} } */
 
+@property (null_unspecified) int property_bad_t_1; /* { dg-error {nullability specifier 'null_unspecified' cannot be applied to non-pointer type 'int'} } */
+@property (nullable) int property_bad_t_2;/* { dg-error {nullability specifier 'nullable' cannot be applied to non-pointer type 'int'} } */
+@property (nonnull) int property_bad_t_3;/* { dg-error {nullability specifier 'nonnull' cannot be applied to non-pointer type 'int'} } */
+@property (null_resettable) int property_bad_t_4;/* { dg-error {nullability specifier 'null_resettable' cannot be applied to non-pointer type 'int'} } */
+@property (nullable) int **property_bad_t_5;/* { dg-error {nullability specifier 'nullable' cannot be applied to multi-level pointer type 'int\*\*'} } */
+
+@property (null_unspecified, nullable) int *property_ne_1; /* { dg-error {'nullable' attribute conflicts with 'null_unspecified' attribute} } */
+@property (null_unspecified, nonnull) int *property_ne_2; /* { dg-error {'nonnull' attribute conflicts with 'null_unspecified' attribute} } */
+@property (null_unspecified, null_resettable) int *property_ne_3; /* { dg-error {'null_resettable' attribute conflicts with 'null_unspecified' attribute} } */
+@property (nullable,nonnull) int *property_ne_4; /* { dg-error {'nonnull' attribute conflicts with 'nullable' attribute} } */
+@property (nullable,null_resettable) int *property_ne_5; /* { dg-error {'null_resettable' attribute conflicts with 'nullable' attribute} } */
+@property (nonnull, null_resettable) int *property_ne_6; /* { dg-error {'null_resettable' attribute conflicts with 'nonnull' attribute} } */
+
 @property (setter=mySetter:,setter=mySetter2:)  int f; /* { dg-warning {multiple property 'setter' methods specified, the latest one will be used} } */
 @property (getter=myGetter, getter=myGetter2 )  int g; /* { dg-warning {multiple property 'getter' methods specified, the latest one will be used} } */
 
diff --git a/gcc/testsuite/obj-c++.dg/property/nullability-00.mm b/gcc/testsuite/obj-c++.dg/property/nullability-00.mm
new file mode 100644
index 0000000000000000000000000000000000000000..9b0c8084cf3b676f60a695475c49f03d03774482
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/property/nullability-00.mm
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fsyntax-only" } */
+
+@interface MyRoot
+{
+  Class isa __attribute__((deprecated));
+  id p;
+  int x;
+  int *i;
+}
+
+@property(null_unspecified, assign) MyRoot *p1;
+@property(nonnull, assign) MyRoot *p2;
+@property(nullable, assign) MyRoot *p3;
+@property(null_resettable, assign) MyRoot *p4;
+@property(null_exciting, assign) MyRoot *e_5; /* { dg-error {unknown property attribute 'null_exciting'} } */
+
+@property(nonnull, retain, nullable) MyRoot *e_6; /* { dg-error {'nullable' attribute conflicts with 'nonnull' attribute} } */
+@property(nonnull, nonnull) int *i; /* { dg-warning {duplicate 'nonnull' attribute} } */
+
+@end
diff --git a/gcc/testsuite/objc.dg/attributes/nullability-00.m b/gcc/testsuite/objc.dg/attributes/nullability-00.m
new file mode 100644
index 0000000000000000000000000000000000000000..81c0145f17b2dccb91cb604adc53556d288ebb03
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/nullability-00.m
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-objc-root-class -fsyntax-only" } */
+
+__attribute__((objc_nullability(0))) id a;
+__attribute__((objc_nullability(4))) id e_1; /* { dg-error {'objc_nullability' attribute argument '4' is not an integer constant between 0 and 3} } */
+__attribute__((objc_nullability(-22))) id e_2; /* { dg-error {'objc_nullability' attribute argument '-22' is not an integer constant between 0 and 3} } */
+__attribute__((objc_nullability("unspecified"))) id b;
+__attribute__((objc_nullability("nullable"))) id c;
+__attribute__((objc_nullability("nonnull"))) id d;
+__attribute__((objc_nullability("resettable"))) id e;
+__attribute__((objc_nullability("nonsense"))) id e_3; /* { dg-error {'objc_nullability' attribute argument '"nonsense"' is not recognised} } */
+__attribute__((objc_nullability(noGoingToWork))) id e_4; /* { dg-error {'noGoingToWork' undeclared here} } */
+
+@interface MyRoot
+{
+  __attribute__((objc_nullability(0))) id iv_a;
+  __attribute__((objc_nullability(3))) struct { int bad_a; } s;/* { dg-error {'objc_nullability' cannot be applied to non-pointer type 'struct <anonymous>'} } */
+  __attribute__((objc_nullability("resettable"))) int iv_b;/* { dg-error {'objc_nullability' cannot be applied to non-pointer type 'int'} } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/property/at-property-4.m b/gcc/testsuite/objc.dg/property/at-property-4.m
index 0e905db0eb46bb9546cc5eaa643ef2cb2f74a068..04da34eaa0be750d8c7df5431e501dae705929d8 100644
--- a/gcc/testsuite/objc.dg/property/at-property-4.m
+++ b/gcc/testsuite/objc.dg/property/at-property-4.m
@@ -26,6 +26,11 @@
 
 @property (class) int property_cl_1;
 
+@property (null_unspecified) int *property_null_1;
+@property (nullable) int *property_null_2;
+@property (nonnull) int *property_null_3;
+@property (null_resettable) int *property_null_4;
+
 @property (release)   int property_err_1;      /* { dg-error "unknown property attribute" } */
 
 @property (getter=myGetter)  int property_h;
@@ -42,6 +47,19 @@
 
 @property (atomic, nonatomic) int property_j; /* { dg-error {'nonatomic' attribute conflicts with 'atomic' attribute} } */
 
+@property (null_unspecified) int property_bad_t_1; /* { dg-error {nullability specifier 'null_unspecified' cannot be applied to non-pointer type 'int'} } */
+@property (nullable) int property_bad_t_2;/* { dg-error {nullability specifier 'nullable' cannot be applied to non-pointer type 'int'} } */
+@property (nonnull) int property_bad_t_3;/* { dg-error {nullability specifier 'nonnull' cannot be applied to non-pointer type 'int'} } */
+@property (null_resettable) int property_bad_t_4;/* { dg-error {nullability specifier 'null_resettable' cannot be applied to non-pointer type 'int'} } */
+@property (nullable) int **property_bad_t_5;/* { dg-error {nullability specifier 'nullable' cannot be applied to multi-level pointer type 'int \*\*'} } */
+
+@property (null_unspecified, nullable) int *property_ne_1; /* { dg-error {'nullable' attribute conflicts with 'null_unspecified' attribute} } */
+@property (null_unspecified, nonnull) int *property_ne_2; /* { dg-error {'nonnull' attribute conflicts with 'null_unspecified' attribute} } */
+@property (null_unspecified, null_resettable) int *property_ne_3; /* { dg-error {'null_resettable' attribute conflicts with 'null_unspecified' attribute} } */
+@property (nullable,nonnull) int *property_ne_4; /* { dg-error {'nonnull' attribute conflicts with 'nullable' attribute} } */
+@property (nullable,null_resettable) int *property_ne_5; /* { dg-error {'null_resettable' attribute conflicts with 'nullable' attribute} } */
+@property (nonnull, null_resettable) int *property_ne_6; /* { dg-error {'null_resettable' attribute conflicts with 'nonnull' attribute} } */
+
 @property (setter=mySetter:,setter=mySetter2:)  int f; /* { dg-warning {multiple property 'setter' methods specified, the latest one will be used} } */
 @property (getter=myGetter, getter=myGetter2 )  int g; /* { dg-warning {multiple property 'getter' methods specified, the latest one will be used} } */
 
diff --git a/gcc/testsuite/objc.dg/property/nullability-00.m b/gcc/testsuite/objc.dg/property/nullability-00.m
new file mode 100644
index 0000000000000000000000000000000000000000..9b0c8084cf3b676f60a695475c49f03d03774482
--- /dev/null
+++ b/gcc/testsuite/objc.dg/property/nullability-00.m
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fsyntax-only" } */
+
+@interface MyRoot
+{
+  Class isa __attribute__((deprecated));
+  id p;
+  int x;
+  int *i;
+}
+
+@property(null_unspecified, assign) MyRoot *p1;
+@property(nonnull, assign) MyRoot *p2;
+@property(nullable, assign) MyRoot *p3;
+@property(null_resettable, assign) MyRoot *p4;
+@property(null_exciting, assign) MyRoot *e_5; /* { dg-error {unknown property attribute 'null_exciting'} } */
+
+@property(nonnull, retain, nullable) MyRoot *e_6; /* { dg-error {'nullable' attribute conflicts with 'nonnull' attribute} } */
+@property(nonnull, nonnull) int *i; /* { dg-warning {duplicate 'nonnull' attribute} } */
+
+@end