On Fri, Aug 2, 2019 at 10:14 AM Akshat Garg <xks...@gmail.com> wrote:

>
>
> On Thu, Aug 1, 2019 at 8:57 PM Paul McKenney <paulmck...@gmail.com> wrote:
>
>> Excellent point, this discussion needs to be made official.
>> Please see attached for an initial draft of a working paper.
>>
>> Thoughts?
>>
>>                                          Thanx, Paul
>>
> Please, find the attachment here (
> https://drive.google.com/open?id=0B9Q3hzI3TofcZ3o2aXVMd2V1Ujl4VUZnT3MtXzZpV1I2OHFv
> ).
>
>>
>> On Tue, Jul 30, 2019 at 12:46 PM Martin Sebor <mse...@gmail.com> wrote:
>> >
>> > On 7/30/19 1:13 AM, Akshat Garg wrote:
>> > > Hi,
>> > > This patch includes C front-end code for a type qualifier
>> _Dependent_ptr.
>> >
>> > Just some very high-level comments/questions.  I only followed
>> > the _Dependent_ptr discussion from a distance and I'm likely
>> > missing some context so the first thing I looked for in this
>> > patch is documentation of the new qualifier.  Unless it's
>> > a proposed C2x feature that I missed I would expect to find it
>> > in section 6 - Extensions to the C Language Family of the manual.
>> > I saw the references to WG21's p0190r4 in the tests but the paper
>> > doesn't mention _Dependent_ptr, and I found no references to a C
>> > paper that does.  If it has been proposed for C2X as well can
>> > you point to it?  (In that case, or if a proposal is planned,
>> > the feature should probably either only be available with
>> > -std=c2x and -std=gnu2x or a pedantic warning should be issued
>> > for its use in earlier modes similarly to how uses of _Atomic
>> > are diagnosed in pre-C11 modes.)
>> >
>> > Martin
>>
> I have tried this patch which raises pedantic warning with pre-gnu2x
modes. Let us know what you think.

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 9e80bfee7d4..4d61a38c5b9 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -2870,6 +2870,12 @@ c_parser_declspecs (c_parser *parser, struct
c_declspecs *specs,
            declspecs_add_qual (loc, specs, value);
          break;
        case RID_DEPENDENT_PTR:
+         if (flag_isoc11)
+           pedwarn_c11 (loc, OPT_Wpedantic,
+                        "ISO C11 does not support the %<_Dependent_ptr%>
qualifier");
+         else
+           pedwarn_c99 (loc, OPT_Wpedantic,
+                        "ISO C90 does not support the %<_Dependent_ptr%>
qualifier");
          attrs_ok = true;
          declspecs_add_qual (loc, specs, c_parser_peek_token
(parser)->value);
          c_parser_consume_token (parser);


> >
>> > > The patch has been tested using the following
>> > > make bootstrap -j 4
>> > > make -k check -j 4
>> > >
>> > > on x86_64-linux-gnu.
>> > >
>> > > Thanks,
>> > > Akshat
>> > >
>> > > gcc/ChangeLog:
>> > >
>> > > 2019-07-30  Akshat Garg <xks...@gmail.com>
>> > >
>> > >          * c-family/c-common.c (struct c_common_resword
>> c_common_reswords):
>> > > Add "_Dependent_ptr".
>> > >          (c_apply_type_quals_to_decl): Set the flag for
>> _Dependent_ptr if
>> > > qualified.
>> > >          (keyword_is_type_qualifier): Add RID_DEPENDENT_PTR.
>> > >          * c-family/c-common.h (enum rid): Add RID_DEPENDENT_PTR.
>> > >          * c-family/c-format.c (check_format_types): Add dependent
>> pointer
>> > > as a qualifier check.
>> > >          * c-family/c-pretty-print.c (pp_c_cv_qualifiers): Handle
>> dependent
>> > > pointer qualifier.
>> > >          * c/c-aux-info.c (gen_type): Handle dependent pointer
>> qualifier.
>> > >          (gen_decl): Handle dependent pointer qualifier.
>> > >          * c/c-decl.c (merge_decls): Set old declaration as having
>> dependent
>> > > pointer qualification if new declaration has one.
>> > >          (shadow_tag_warned): Add dependent_ptr_p to declspecs check.
>> > >          (quals_from_declspecs): Add dependent_ptr_p to declspecs
>> check.
>> > >          (grokdeclarator): Add checks for dependent pointer qualifier
>> and
>> > > warn of duplicate or errors. Allow dependent pointer for pointer
>> types only.
>> > >          * c/c-parser.c (c_keyword_starts_typename,
>> c_token_is_qualifier,
>> > > c_token_starts_declspecs): Add RID_DEPENDENT_PTR.
>> > >          (c_parser_static_assert_declaration_no_semi): Add
>> _Dependent_ptr
>> > > qualifier in comments.
>> > >          (c_parser_declspecs, c_parser_attribute_any_word): Add
>> > > RID_DEPENDENT_PTR.
>> > >          * c/c-tree.h (C_TYPE_FIELDS_DEPENDENT_PTR): New macro to mark
>> > > dependent pointer.
>> > >          (enum c_declspec_word): Add cdw_dependent_ptr.
>> > >          (struct c_declspecs): Add dependent_ptr_p field.
>> > >          * print-tree.c (print_node): Print dependent_ptr qualifier.
>> > >          * tree-core.hi (enum cv_qualifier): Add
>> TYPE_QUAL_DEPENDENT_PTR.
>> > >          (enum tree_index): Add TI_DEPENDENT_PTR_TYPE.
>> > >          (struct tree_base): Add dependent_ptr_flag field.
>> > >          * tree-pretty-print.c (dump_generic_node): Print dependent
>> pointer
>> > > type qualifier.
>> > >          * tree.c (fld_type_variant, set_type_quals): Set
>> TYPE_DEPENDENT_PTR.
>> > >          * tree.h (TREE_THIS_DEPENDENT_PTR): New macro. To access
>> > > dependent_ptr_flag field in tree_base.
>> > >          (TYPE_DEPENDENT_PTR): New accessor macro.
>> > >          (TYPE_QUALS, TYPE_QUALS_NO_ADDR_SPACE): Add
>> TYPE_QUAL_DEPENDENT_PTR.
>> > >          (dependent_ptrTI_type_node): Add new type node.
>> > >
>> > > gcc/testsuite/ChangeLog:
>> > >
>> > > 2019-07-30  Akshat Garg <xks...@gmail.com>
>> > >
>> > >          * gcc.dg/c11-dependent_ptr-test-1.c: New test for
>> _Dependent_ptr
>> > > qualifier.
>> > >          * gcc.dg/{p0190r4_fig8, p0190r4_fig9, p0190r4_fig10,
>> p0190r4_fig11,
>> > > p0190r4_fig12, p0190r4_fig13}.c: New tests from document P0190R4 for
>> > > _Dependent_ptr qualifier.
>> > >
>> > > diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
>> > > index cb92710..4f09037 100644
>> > > --- a/gcc/c-family/c-common.c
>> > > +++ b/gcc/c-family/c-common.c
>> > > @@ -345,6 +345,7 @@ const struct c_common_resword c_common_reswords[]
>> =
>> > >     { "_Alignas", RID_ALIGNAS,   D_CONLY },
>> > >     { "_Alignof", RID_ALIGNOF,   D_CONLY },
>> > >     { "_Atomic", RID_ATOMIC,    D_CONLY },
>> > > + { "_Dependent_ptr",   RID_DEPENDENT_PTR,  0 },
>> > >     { "_Bool", RID_BOOL,      D_CONLY },
>> > >     { "_Complex", RID_COMPLEX, 0 },
>> > >     { "_Imaginary", RID_IMAGINARY, D_CONLY },
>> > > @@ -3546,6 +3547,11 @@ c_apply_type_quals_to_decl (int type_quals,
>> tree
>> > > decl)
>> > >         TREE_SIDE_EFFECTS (decl) = 1;
>> > >         TREE_THIS_VOLATILE (decl) = 1;
>> > >       }
>> > > +  if (type_quals & TYPE_QUAL_DEPENDENT_PTR)
>> > > +    {
>> > > +      TREE_SIDE_EFFECTS (decl) = 1;
>> > > +      TREE_THIS_DEPENDENT_PTR (decl) = 1;
>> > > +    }
>> > >     if (type_quals & TYPE_QUAL_RESTRICT)
>> > >       {
>> > >         while (type && TREE_CODE (type) == ARRAY_TYPE)
>> > > @@ -7851,6 +7857,7 @@ keyword_is_type_qualifier (enum rid keyword)
>> > >       case RID_VOLATILE:
>> > >       case RID_RESTRICT:
>> > >       case RID_ATOMIC:
>> > > +    case RID_DEPENDENT_PTR:
>> > >         return true;
>> > >       default:
>> > >         return false;
>> > > diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
>> > > index 117d729..ab55882 100644
>> > > --- a/gcc/c-family/c-common.h
>> > > +++ b/gcc/c-family/c-common.h
>> > > @@ -68,7 +68,7 @@ enum rid
>> > >     RID_UNSIGNED, RID_LONG,    RID_CONST, RID_EXTERN,
>> > >     RID_REGISTER, RID_TYPEDEF, RID_SHORT, RID_INLINE,
>> > >     RID_VOLATILE, RID_SIGNED,  RID_AUTO,  RID_RESTRICT,
>> > > -  RID_NORETURN, RID_ATOMIC,
>> > > +  RID_NORETURN, RID_ATOMIC, RID_DEPENDENT_PTR,
>> > >
>> > >     /* C extensions */
>> > >     RID_COMPLEX, RID_THREAD, RID_SAT,
>> > > diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
>> > > index d134116..00769bb 100644
>> > > --- a/gcc/c-family/c-format.c
>> > > +++ b/gcc/c-family/c-format.c
>> > > @@ -4172,6 +4172,7 @@ check_format_types (const substring_loc
>> &fmt_loc,
>> > >     && (TYPE_READONLY (cur_type)
>> > >         || TYPE_VOLATILE (cur_type)
>> > >         || TYPE_ATOMIC (cur_type)
>> > > +      || TYPE_DEPENDENT_PTR (cur_type)
>> > >         || TYPE_RESTRICT (cur_type)))
>> > >    warning (OPT_Wformat_, "extra type qualifiers in format "
>> > >    "argument (argument %d)",
>> > > diff --git a/gcc/c-family/c-pretty-print.c
>> b/gcc/c-family/c-pretty-print.c
>> > > index 3e25624..e034a8f 100644
>> > > --- a/gcc/c-family/c-pretty-print.c
>> > > +++ b/gcc/c-family/c-pretty-print.c
>> > > @@ -181,6 +181,8 @@ pp_c_cv_qualifiers (c_pretty_printer *pp, int
>> > > qualifiers, bool func_type)
>> > >
>> > >     if (qualifiers & TYPE_QUAL_ATOMIC)
>> > >       pp_c_ws_string (pp, "_Atomic");
>> > > +  if (qualifiers & TYPE_QUAL_DEPENDENT_PTR)
>> > > +    pp_c_ws_string (pp, "_Dependent_ptr");
>> > >     if (qualifiers & TYPE_QUAL_CONST)
>> > >       pp_c_ws_string (pp, func_type ? "__attribute__((const))" :
>> "const");
>> > >     if (qualifiers & TYPE_QUAL_VOLATILE)
>> > > diff --git a/gcc/c/c-aux-info.c b/gcc/c/c-aux-info.c
>> > > index 96bb2e2..514093c 100644
>> > > --- a/gcc/c/c-aux-info.c
>> > > +++ b/gcc/c/c-aux-info.c
>> > > @@ -284,6 +284,8 @@ gen_type (const char *ret_val, tree t,
>> formals_style
>> > > style)
>> > >    case POINTER_TYPE:
>> > >     if (TYPE_ATOMIC (t))
>> > >       ret_val = concat ("_Atomic ", ret_val, NULL);
>> > > +  if (TYPE_DEPENDENT_PTR (t))
>> > > +    ret_val = concat ("_Dependent_ptr ", ret_val, NULL);
>> > >     if (TYPE_READONLY (t))
>> > >       ret_val = concat ("const ", ret_val, NULL);
>> > >     if (TYPE_VOLATILE (t))
>> > > @@ -427,6 +429,8 @@ gen_type (const char *ret_val, tree t,
>> formals_style
>> > > style)
>> > >       }
>> > >     if (TYPE_ATOMIC (t))
>> > >       ret_val = concat ("_Atomic ", ret_val, NULL);
>> > > +  if (TYPE_DEPENDENT_PTR (t))
>> > > +    ret_val = concat ("_Dependent_ptr ", ret_val, NULL);
>> > >     if (TYPE_READONLY (t))
>> > >       ret_val = concat ("const ", ret_val, NULL);
>> > >     if (TYPE_VOLATILE (t))
>> > > @@ -474,6 +478,8 @@ gen_decl (tree decl, int is_func_definition,
>> > > formals_style style)
>> > >       ret_val = concat ("volatile ", ret_val, NULL);
>> > >     if (TREE_READONLY (decl))
>> > >       ret_val = concat ("const ", ret_val, NULL);
>> > > +  if (TREE_THIS_DEPENDENT_PTR (decl))
>> > > +    ret_val = concat ("dependent_ptr ", ret_val, NULL);
>> > >
>> > >     data_type = "";
>> > >
>> > > diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
>> > > index f85f481..2047575 100644
>> > > --- a/gcc/c/c-decl.c
>> > > +++ b/gcc/c/c-decl.c
>> > > @@ -2587,6 +2587,9 @@ merge_decls (tree newdecl, tree olddecl, tree
>> > > newtype, tree oldtype)
>> > >     if (TREE_THIS_VOLATILE (newdecl))
>> > >       TREE_THIS_VOLATILE (olddecl) = 1;
>> > >
>> > > +  if (TREE_THIS_DEPENDENT_PTR (newdecl))
>> > > +    TREE_THIS_DEPENDENT_PTR (olddecl) = 1;
>> > > +
>> > >     /* Merge deprecatedness.  */
>> > >     if (TREE_DEPRECATED (newdecl))
>> > >       TREE_DEPRECATED (olddecl) = 1;
>> > > @@ -2638,6 +2641,7 @@ merge_decls (tree newdecl, tree olddecl, tree
>> > > newtype, tree oldtype)
>> > >     DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
>> > >       |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
>> > >     TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
>> > > +  TREE_THIS_DEPENDENT_PTR (newdecl) |= TREE_THIS_DEPENDENT_PTR
>> (olddecl);
>> > >     DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
>> > >     if (DECL_IS_OPERATOR_NEW_P (olddecl))
>> > >       DECL_SET_IS_OPERATOR_NEW (newdecl, true);
>> > > @@ -4544,6 +4548,7 @@ shadow_tag_warned (const struct c_declspecs
>> > > *declspecs, int warned)
>> > >      && (declspecs->const_p
>> > >          || declspecs->volatile_p
>> > >          || declspecs->atomic_p
>> > > +       || declspecs->dependent_ptr_p
>> > >          || declspecs->restrict_p
>> > >          || declspecs->address_space))
>> > >       {
>> > > @@ -4672,6 +4677,7 @@ quals_from_declspecs (const struct c_declspecs
>> *specs)
>> > >          | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0)
>> > >          | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0)
>> > >          | (specs->atomic_p ? TYPE_QUAL_ATOMIC : 0)
>> > > +       | (specs->dependent_ptr_p ? TYPE_QUAL_DEPENDENT_PTR : 0)
>> > >          | (ENCODE_QUAL_ADDR_SPACE (specs->address_space)));
>> > >     gcc_assert (!specs->type
>> > >         && !specs->decl_attr
>> > > @@ -5837,6 +5843,7 @@ grokdeclarator (const struct c_declarator
>> *declarator,
>> > >     int restrictp;
>> > >     int volatilep;
>> > >     int atomicp;
>> > > +  int dependent_ptrp;
>> > >     int type_quals = TYPE_UNQUALIFIED;
>> > >     tree name = NULL_TREE;
>> > >     bool funcdef_flag = false;
>> > > @@ -6003,6 +6010,7 @@ grokdeclarator (const struct c_declarator
>> *declarator,
>> > >     restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type);
>> > >     volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type);
>> > >     atomicp = declspecs->atomic_p + TYPE_ATOMIC (element_type);
>> > > +  dependent_ptrp = declspecs->dependent_ptr_p + TYPE_DEPENDENT_PTR
>> > > (element_type);
>> > >     as1 = declspecs->address_space;
>> > >     as2 = TYPE_ADDR_SPACE (element_type);
>> > >     address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1;
>> > > @@ -6015,6 +6023,8 @@ grokdeclarator (const struct c_declarator
>> *declarator,
>> > >       pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<volatile%>");
>> > >     if (atomicp > 1)
>> > >       pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<_Atomic%>");
>> > > +  if (dependent_ptrp > 1)
>> > > +    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<_Dependent_ptr%>");
>> > >
>> > >     if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) &&
>> as1 !=
>> > > as2)
>> > >       error_at (loc, "conflicting named address spaces (%s vs %s)",
>> > > @@ -6031,6 +6041,7 @@ grokdeclarator (const struct c_declarator
>> *declarator,
>> > >    | (restrictp ? TYPE_QUAL_RESTRICT : 0)
>> > >    | (volatilep ? TYPE_QUAL_VOLATILE : 0)
>> > >    | (atomicp ? TYPE_QUAL_ATOMIC : 0)
>> > > + | (dependent_ptrp ? TYPE_QUAL_DEPENDENT_PTR : 0)
>> > >    | ENCODE_QUAL_ADDR_SPACE (address_space));
>> > >     if (type_quals != TYPE_QUALS (element_type))
>> > >       orig_qual_type = NULL_TREE;
>> > > @@ -6042,6 +6053,13 @@ grokdeclarator (const struct c_declarator
>> > > *declarator,
>> > >     if (declspecs->atomic_p && TREE_CODE (type) == ARRAY_TYPE)
>> > >       error_at (loc, "%<_Atomic%>-qualified array type");
>> > >
>> > > +  /* Applying the _Dependent_ptr qualifier to an array type (through
>> > > +     the use of typedefs or typeof) must be detected here.  If the
>> > > +     qualifier is introduced later, any appearance of applying it to
>> > > +     an array is actually applying it to an element of that array.
>> */
>> > > +  if (declspecs->dependent_ptr_p && TREE_CODE (type) == ARRAY_TYPE)
>> > > +    error_at (loc, "%<_Dependent_ptr%>-qualified array type");
>> > > +
>> > >     /* Warn about storage classes that are invalid for certain
>> > >        kinds of declarations (parameters, typenames, etc.).  */
>> > >
>> > > @@ -7214,6 +7232,10 @@ grokdeclarator (const struct c_declarator
>> > > *declarator,
>> > >    /* An uninitialized decl with `extern' is a reference.  */
>> > >    int extern_ref = !initialized && storage_class == csc_extern;
>> > >
>> > > + /* _Dependent_ptr qualifier only reserved for pointer type variable
>> */
>> > > + if ((type_quals & TYPE_QUAL_DEPENDENT_PTR) && (!POINTER_TYPE_P
>> (type)))
>> > > +  error_at (loc, "invalid use of %<_Dependent_ptr%>");
>> > > +
>> > >    type = c_build_qualified_type (type, type_quals, orig_qual_type,
>> > >          orig_qual_indirect);
>> > >
>> > > @@ -7294,7 +7316,7 @@ grokdeclarator (const struct c_declarator
>> *declarator,
>> > >    DECL_REGISTER (decl) = 1;
>> > >         }
>> > >
>> > > -    /* Record constancy and volatility.  */
>> > > +    /* Record constancy, data dependency and volatility.  */
>> > >       c_apply_type_quals_to_decl (type_quals, decl);
>> > >
>> > >       /* Apply _Alignas specifiers.  */
>> > > @@ -8258,6 +8280,11 @@ finish_struct (location_t loc, tree t, tree
>> > > fieldlist, tree attributes,
>> > >         if (TREE_THIS_VOLATILE (x))
>> > >    C_TYPE_FIELDS_VOLATILE (t) = 1;
>> > >
>> > > +      /* Any field that is a dependent pointer means variables of
>> this
>> > > + type must be treated in some ways as dependent pointer.  */
>> > > +      if (TREE_THIS_DEPENDENT_PTR (x))
>> > > + C_TYPE_FIELDS_DEPENDENT_PTR (t) = 1;
>> > > +
>> > >         /* Any field of nominal variable size implies structure is
>> too.  */
>> > >         if (C_DECL_VARIABLE_SIZE (x))
>> > >    C_TYPE_VARIABLE_SIZE (t) = 1;
>> > > @@ -10177,6 +10204,12 @@ declspecs_add_qual (location_t loc,
>> > >         prev_loc = specs->locations[cdw_atomic];
>> > >         specs->locations[cdw_atomic] = loc;
>> > >         break;
>> > > +    case RID_DEPENDENT_PTR:
>> > > +      dupe = specs->dependent_ptr_p;
>> > > +      specs->dependent_ptr_p = true;
>> > > +      prev_loc = specs->locations[cdw_dependent_ptr];
>> > > +      specs->locations[cdw_dependent_ptr] = loc;
>> > > +      break;
>> > >       default:
>> > >         gcc_unreachable ();
>> > >       }
>> > > diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
>> > > index 6721049..35e25bb 100644
>> > > --- a/gcc/c/c-parser.c
>> > > +++ b/gcc/c/c-parser.c
>> > > @@ -503,6 +503,7 @@ c_keyword_starts_typename (enum rid keyword)
>> > >       case RID_TYPEOF:
>> > >       case RID_CONST:
>> > >       case RID_ATOMIC:
>> > > +    case RID_DEPENDENT_PTR:
>> > >       case RID_VOLATILE:
>> > >       case RID_RESTRICT:
>> > >       case RID_ATTRIBUTE:
>> > > @@ -606,6 +607,7 @@ c_token_is_qualifier (c_token *token)
>> > >    case RID_RESTRICT:
>> > >    case RID_ATTRIBUTE:
>> > >    case RID_ATOMIC:
>> > > + case RID_DEPENDENT_PTR:
>> > >     return true;
>> > >    default:
>> > >     return false;
>> > > @@ -687,6 +689,7 @@ c_token_starts_declspecs (c_token *token)
>> > >    case RID_SAT:
>> > >    case RID_ALIGNAS:
>> > >    case RID_ATOMIC:
>> > > + case RID_DEPENDENT_PTR:
>> > >    case RID_AUTO_TYPE:
>> > >     return true;
>> > >    default:
>> > > @@ -2575,6 +2578,7 @@ c_parser_static_assert_declaration_no_semi
>> (c_parser
>> > > *parser)
>> > >        volatile
>> > >        address-space-qualifier
>> > >        _Atomic
>> > > +     _Dependent_ptr
>> > >
>> > >      (restrict is new in C99.)
>> > >      (_Atomic is new in C11.)
>> > > @@ -2865,6 +2869,11 @@ c_parser_declspecs (c_parser *parser, struct
>> > > c_declspecs *specs,
>> > >     else
>> > >       declspecs_add_qual (loc, specs, value);
>> > >     break;
>> > > + case RID_DEPENDENT_PTR:
>> > > +  attrs_ok = true;
>> > > +  declspecs_add_qual (loc, specs, c_parser_peek_token
>> (parser)->value);
>> > > +  c_parser_consume_token (parser);
>> > > +  break;
>> > >    case RID_CONST:
>> > >    case RID_VOLATILE:
>> > >    case RID_RESTRICT:
>> > > @@ -4275,6 +4284,7 @@ c_parser_attribute_any_word (c_parser *parser)
>> > >    case RID_TRANSACTION_ATOMIC:
>> > >    case RID_TRANSACTION_CANCEL:
>> > >    case RID_ATOMIC:
>> > > + case RID_DEPENDENT_PTR:
>> > >    case RID_AUTO_TYPE:
>> > >    case RID_INT_N_0:
>> > >    case RID_INT_N_1:
>> > > diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
>> > > index dae2979..0e416f2 100644
>> > > --- a/gcc/c/c-tree.h
>> > > +++ b/gcc/c/c-tree.h
>> > > @@ -34,6 +34,9 @@ along with GCC; see the file COPYING3.  If not see
>> > >   /* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is
>> volatile.
>> > >   */
>> > >   #define C_TYPE_FIELDS_VOLATILE(TYPE) TREE_LANG_FLAG_2 (TYPE)
>> > >
>> > > +/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is
>> dependent
>> > > pointer.  */
>> > > +#define C_TYPE_FIELDS_DEPENDENT_PTR(TYPE) TREE_LANG_FLAG_3 (TYPE)
>> > > +
>> > >   /* In a RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE
>> > >      nonzero if the definition of the type has already started.  */
>> > >   #define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE)
>> > > @@ -279,6 +282,7 @@ enum c_declspec_word {
>> > >     cdw_volatile,
>> > >     cdw_restrict,
>> > >     cdw_atomic,
>> > > +  cdw_dependent_ptr,
>> > >     cdw_saturating,
>> > >     cdw_alignas,
>> > >     cdw_address_space,
>> > > @@ -387,6 +391,8 @@ struct c_declspecs {
>> > >     BOOL_BITFIELD restrict_p : 1;
>> > >     /* Whether "_Atomic" was specified.  */
>> > >     BOOL_BITFIELD atomic_p : 1;
>> > > +  /* Whether "_Dependent_ptr" was specified.  */
>> > > +  BOOL_BITFIELD dependent_ptr_p : 1;
>> > >     /* Whether "_Sat" was specified.  */
>> > >     BOOL_BITFIELD saturating_p : 1;
>> > >     /* Whether any alignment specifier (even with zero alignment) was
>> > > diff --git a/gcc/print-tree.c b/gcc/print-tree.c
>> > > index debea2b..ec4e3db 100644
>> > > --- a/gcc/print-tree.c
>> > > +++ b/gcc/print-tree.c
>> > > @@ -348,6 +348,8 @@ print_node (FILE *file, const char *prefix, tree
>> node,
>> > > int indent,
>> > >       fputs (" addressable", file);
>> > >     if (TREE_THIS_VOLATILE (node))
>> > >       fputs (" volatile", file);
>> > > +  if (TREE_THIS_DEPENDENT_PTR (node))
>> > > +    fputs (" dependent_ptr", file);
>> > >     if (TREE_ASM_WRITTEN (node))
>> > >       fputs (" asm_written", file);
>> > >     if (TREE_USED (node))
>> > > diff --git a/gcc/tree-core.h b/gcc/tree-core.h
>> > > index 60d8c68..3f3e682 100644
>> > > --- a/gcc/tree-core.h
>> > > +++ b/gcc/tree-core.h
>> > > @@ -567,7 +567,8 @@ enum cv_qualifier {
>> > >     TYPE_QUAL_CONST    = 0x1,
>> > >     TYPE_QUAL_VOLATILE = 0x2,
>> > >     TYPE_QUAL_RESTRICT = 0x4,
>> > > -  TYPE_QUAL_ATOMIC   = 0x8
>> > > +  TYPE_QUAL_ATOMIC   = 0x8,
>> > > +  TYPE_QUAL_DEPENDENT_PTR = 0x10
>> > >   };
>> > >
>> > >   /* Standard named or nameless data types of the C compiler.  */
>> > > @@ -591,6 +592,8 @@ enum tree_index {
>> > >     TI_ATOMICDI_TYPE,
>> > >     TI_ATOMICTI_TYPE,
>> > >
>> > > +  TI_DEPENDENT_PTR_TYPE,
>> > > +
>> > >     TI_UINT16_TYPE,
>> > >     TI_UINT32_TYPE,
>> > >     TI_UINT64_TYPE,
>> > > @@ -969,6 +972,7 @@ struct GTY(()) tree_base {
>> > >     unsigned asm_written_flag: 1;
>> > >     unsigned nowarning_flag : 1;
>> > >     unsigned visited : 1;
>> > > +  unsigned dependent_ptr_flag : 1;
>> > >
>> > >     unsigned used_flag : 1;
>> > >     unsigned nothrow_flag : 1;
>> > > diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
>> > > index 9bea132..ae59cea 100644
>> > > --- a/gcc/tree-pretty-print.c
>> > > +++ b/gcc/tree-pretty-print.c
>> > > @@ -1622,6 +1622,8 @@ dump_generic_node (pretty_printer *pp, tree
>> node, int
>> > > spc, dump_flags_t flags,
>> > >     pp_string (pp, "atomic ");
>> > >    if (quals & TYPE_QUAL_CONST)
>> > >     pp_string (pp, "const ");
>> > > + if (quals & TYPE_QUAL_DEPENDENT_PTR)
>> > > +  pp_string (pp, "dependent_ptr ");
>> > >    else if (quals & TYPE_QUAL_VOLATILE)
>> > >     pp_string (pp, "volatile ");
>> > >    else if (quals & TYPE_QUAL_RESTRICT)
>> > > @@ -1768,6 +1770,8 @@ dump_generic_node (pretty_printer *pp, tree
>> node, int
>> > > spc, dump_flags_t flags,
>> > >       pp_string (pp, " volatile");
>> > >     if (quals & TYPE_QUAL_RESTRICT)
>> > >       pp_string (pp, " restrict");
>> > > +  if (quals & TYPE_QUAL_DEPENDENT_PTR)
>> > > +    pp_string (pp, " dependent_ptr");
>> > >
>> > >     if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
>> > >       {
>> > > @@ -1871,6 +1875,8 @@ dump_generic_node (pretty_printer *pp, tree
>> node, int
>> > > spc, dump_flags_t flags,
>> > >
>> > >    if (quals & TYPE_QUAL_ATOMIC)
>> > >     pp_string (pp, "atomic ");
>> > > + if (quals & TYPE_QUAL_DEPENDENT_PTR)
>> > > +  pp_string (pp, "dependent_ptr ");
>> > >    if (quals & TYPE_QUAL_CONST)
>> > >     pp_string (pp, "const ");
>> > >    if (quals & TYPE_QUAL_VOLATILE)
>> > > diff --git a/gcc/tree.c b/gcc/tree.c
>> > > index 8cf75f2..b4dff8d 100644
>> > > --- a/gcc/tree.c
>> > > +++ b/gcc/tree.c
>> > > @@ -5213,6 +5213,7 @@ fld_type_variant (tree first, tree t, class
>> > > free_lang_data_d *fld,
>> > >     TYPE_READONLY (v) = TYPE_READONLY (t);
>> > >     TYPE_VOLATILE (v) = TYPE_VOLATILE (t);
>> > >     TYPE_ATOMIC (v) = TYPE_ATOMIC (t);
>> > > +  TYPE_DEPENDENT_PTR (v) = TYPE_DEPENDENT_PTR (t);
>> > >     TYPE_RESTRICT (v) = TYPE_RESTRICT (t);
>> > >     TYPE_ADDR_SPACE (v) = TYPE_ADDR_SPACE (t);
>> > >     TYPE_NAME (v) = TYPE_NAME (t);
>> > > @@ -6348,6 +6349,7 @@ set_type_quals (tree type, int type_quals)
>> > >     TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
>> > >     TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
>> > >     TYPE_ATOMIC (type) = (type_quals & TYPE_QUAL_ATOMIC) != 0;
>> > > +  TYPE_DEPENDENT_PTR (type) = (type_quals & TYPE_QUAL_DEPENDENT_PTR)
>> != 0;
>> > >     TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals);
>> > >   }
>> > >
>> > > diff --git a/gcc/tree.h b/gcc/tree.h
>> > > index 4aa2c4a..0c2f192 100644
>> > > --- a/gcc/tree.h
>> > > +++ b/gcc/tree.h
>> > > @@ -789,6 +789,9 @@ extern void omp_clause_range_check_failed
>> (const_tree,
>> > > const char *, int,
>> > >      If this bit is set in an expression, so is TREE_SIDE_EFFECTS.  */
>> > >   #define TREE_THIS_VOLATILE(NODE) ((NODE)->base.volatile_flag)
>> > >
>> > > +/* Nonzero means this expression is involved in some data
>> dependency.  */
>> > > +#define TREE_THIS_DEPENDENT_PTR(NODE)
>> ((NODE)->base.dependent_ptr_flag)
>> > > +
>> > >   /* Nonzero means this node will not trap.  In an INDIRECT_REF, means
>> > >      accessing the memory pointed to won't generate a trap.  However,
>> > >      this only applies to an object when used appropriately: it
>> doesn't
>> > > @@ -2070,6 +2073,9 @@ extern machine_mode vector_type_mode
>> (const_tree);
>> > >   /* Nonzero in a type considered atomic as a whole.  */
>> > >   #define TYPE_ATOMIC(NODE) (TYPE_CHECK
>> (NODE)->base.u.bits.atomic_flag)
>> > >
>> > > +/* Nonzero in a type considered dependent_ptr as a whole.  */
>> > > +#define TYPE_DEPENDENT_PTR(NODE) (TYPE_CHECK
>> > > (NODE)->base.dependent_ptr_flag)
>> > > +
>> > >   /* Means this type is const-qualified.  */
>> > >   #define TYPE_READONLY(NODE) (TYPE_CHECK (NODE)->base.readonly_flag)
>> > >
>> > > @@ -2100,6 +2106,7 @@ extern machine_mode vector_type_mode
>> (const_tree);
>> > >     ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \
>> > >     | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
>> > >     | (TYPE_ATOMIC (NODE) * TYPE_QUAL_ATOMIC) \
>> > > +  | (TYPE_DEPENDENT_PTR (NODE) * TYPE_QUAL_DEPENDENT_PTR)   \
>> > >     | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT) \
>> > >     | (ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (NODE)))))
>> > >
>> > > @@ -2108,6 +2115,7 @@ extern machine_mode vector_type_mode
>> (const_tree);
>> > >     ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \
>> > >     | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
>> > >     | (TYPE_ATOMIC (NODE) * TYPE_QUAL_ATOMIC) \
>> > > +  | (TYPE_DEPENDENT_PTR (NODE) * TYPE_QUAL_DEPENDENT_PTR)   \
>> > >     | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT)))
>> > >
>> > >   /* The same as TYPE_QUALS without the address space and atomic
>> > > @@ -3940,6 +3948,8 @@ tree_strip_any_location_wrapper (tree exp)
>> > >   #define atomicDI_type_node global_trees[TI_ATOMICDI_TYPE]
>> > >   #define atomicTI_type_node global_trees[TI_ATOMICTI_TYPE]
>> > >
>> > > +#define dependent_ptrTI_type_node global_trees[TI_DEPENDENT_PTR_TYPE]
>> > > +
>> > >   #define uint16_type_node global_trees[TI_UINT16_TYPE]
>> > >   #define uint32_type_node global_trees[TI_UINT32_TYPE]
>> > >   #define uint64_type_node global_trees[TI_UINT64_TYPE]
>> > > diff --git a/gcc/testsuite/gcc.dg/c11-dependent_ptr-test-1.c
>> > > b/gcc/testsuite/gcc.dg/c11-dependent_ptr-test-1.c
>> > > new file mode 100644
>> > > index 0000000..8a70733
>> > > --- /dev/null
>> > > +++ b/gcc/testsuite/gcc.dg/c11-dependent_ptr-test-1.c
>> > > @@ -0,0 +1,62 @@
>> > > +/* Test for _Dependent_ptr. _Dependent_ptr qualified pointer
>> > > initialization tests. */
>> > > +/* { dg-do run } */
>> > > +/* { dg-options "-std=c11 -pedantic-errors" } */
>> > > +
>> > > +typedef __SIZE_TYPE__ size_t;
>> > > +extern void abort (void);
>> > > +extern void exit (int);
>> > > +extern void *malloc (size_t);
>> > > +
>> > > +#define TEST_SIMPLE_ASSIGN(TYPE)           \
>> > > +  do                   \
>> > > +    {                 \
>> > > +      static volatile _Atomic (TYPE) * _Dependent_ptr a;     \
>> > > +      static volatile _Atomic (TYPE) b;         \
>> > > +      a = &b;               \
>> > > +      if (a != &b)               \
>> > > +   abort();               \
>> > > +    }                                                             \
>> > > +  while (0)
>> > > +
>> > > +#define TEST_SIMPLE_ASSIGN_POINTER()           \
>> > > +  do                                                               \
>> > > +    {                                                             \
>> > > +      TEST_SIMPLE_ASSIGN (_Bool);         \
>> > > +      TEST_SIMPLE_ASSIGN (char);           \
>> > > +      TEST_SIMPLE_ASSIGN (signed char);         \
>> > > +      TEST_SIMPLE_ASSIGN (unsigned char);       \
>> > > +      TEST_SIMPLE_ASSIGN (signed short);         \
>> > > +      TEST_SIMPLE_ASSIGN (unsigned short);         \
>> > > +      TEST_SIMPLE_ASSIGN (signed int);           \
>> > > +      TEST_SIMPLE_ASSIGN (unsigned int);         \
>> > > +      TEST_SIMPLE_ASSIGN (signed long);         \
>> > > +      TEST_SIMPLE_ASSIGN (unsigned long);       \
>> > > +      TEST_SIMPLE_ASSIGN (signed long long);         \
>> > > +      TEST_SIMPLE_ASSIGN (unsigned long long);         \
>> > > +      TEST_SIMPLE_ASSIGN (float);         \
>> > > +      TEST_SIMPLE_ASSIGN (double);           \
>> > > +      TEST_SIMPLE_ASSIGN (long double);         \
>> > > +      TEST_SIMPLE_ASSIGN (_Complex float);         \
>> > > +      TEST_SIMPLE_ASSIGN (_Complex double);       \
>> > > +      TEST_SIMPLE_ASSIGN (_Complex long double);       \
>> > > +      struct new_struct { struct new_struct * _Dependent_ptr next;
>> };   \
>> > > +      struct new_struct * _Dependent_ptr s;         \
>> > > +      s = malloc (sizeof (struct new_struct));         \
>> > > +      struct new_struct t;             \
>> > > +      s->next = &t;             \
>> > > +      if (s->next != &t)             \
>> > > +        abort();               \
>> > > +    }                 \
>> > > +  while (0)
>> > > +
>> > > +static void
>> > > +test_simple_assign (void)
>> > > +{
>> > > +  TEST_SIMPLE_ASSIGN_POINTER ();
>> > > +}
>> > > +
>> > > +int main (void)
>> > > +{
>> > > +  test_simple_assign ();
>> > > +  exit (0);
>> > > +}
>> > > diff --git a/gcc/testsuite/gcc.dg/p0190r4_fig10.c
>> > > b/gcc/testsuite/gcc.dg/p0190r4_fig10.c
>> > > new file mode 100644
>> > > index 0000000..057c2ba
>> > > --- /dev/null
>> > > +++ b/gcc/testsuite/gcc.dg/p0190r4_fig10.c
>> > > @@ -0,0 +1,46 @@
>> > > +/* Test for _Dependent_ptr. _Dependent_ptr test for checking
>> dependency
>> > > through non-local storage. Refer figure 10 in document p0190r4 (
>> > > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf).
>> */
>> > > +/* { dg-do compile } */
>> > > +/* { dg-options "-std=c11 -pedantic" } */
>> > > +
>> > > +#include <stdatomic.h>
>> > > +
>> > > +typedef __SIZE_TYPE__ size_t;
>> > > +extern void abort (void);
>> > > +extern void exit (int);
>> > > +extern void *malloc (size_t);
>> > > +extern int assert ();
>> > > +
>> > > +struct rcutest
>> > > +{
>> > > +  int a;
>> > > +  int b;
>> > > +  int c;
>> > > +};
>> > > +
>> > > +_Atomic struct rcutest *gp;
>> > > +struct rcutest *gslp;
>> > > +
>> > > +#define rcu_assign_pointer(p,v) \
>> > > +  atomic_store_explicit(&(p), (v), memory_order_release);
>> > > +
>> > > +#define rcu_dereference(p) \
>> > > +  atomic_load_explicit(&(p), memory_order_consume);
>> > > +
>> > > +void thread0 ()
>> > > +{
>> > > +  struct rcutest *p;
>> > > +
>> > > +  p = (struct rcutest *)malloc (sizeof (*p));
>> > > +  assert (p);
>> > > +  p->a = 42;
>> > > +  rcu_assign_pointer (gp,p); /* { dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +}
>> > > +
>> > > +void thread1 ()
>> > > +{
>> > > +  struct rcutest *_Dependent_ptr p = rcu_dereference (gp); /* {
>> dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +  gslp = p;
>> > > +  p = gslp;
>> > > +  if (p)
>> > > +    assert (p->a = 42);
>> > > +}
>> > > diff --git a/gcc/testsuite/gcc.dg/p0190r4_fig11.c
>> > > b/gcc/testsuite/gcc.dg/p0190r4_fig11.c
>> > > new file mode 100644
>> > > index 0000000..39c4b61
>> > > --- /dev/null
>> > > +++ b/gcc/testsuite/gcc.dg/p0190r4_fig11.c
>> > > @@ -0,0 +1,51 @@
>> > > +/* Test for _Dependent_ptr. _Dependent_ptr test in which reload kills
>> > > dependency. Refer figure 11 in document p0190r4 (
>> > > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf).
>> */
>> > > +/* { dg-do compile } */
>> > > +/* { dg-options "-std=c11 -pedantic" } */
>> > > +
>> > > +#include <stdatomic.h>
>> > > +
>> > > +typedef __SIZE_TYPE__ size_t;
>> > > +extern void abort (void);
>> > > +extern void exit (int);
>> > > +extern void *malloc (size_t);
>> > > +extern int assert ();
>> > > +struct rcutest
>> > > +{
>> > > +  int a;
>> > > +  int b;
>> > > +  int c;
>> > > +};
>> > > +
>> > > +_Atomic struct rcutest *gp;
>> > > +_Atomic struct rcutest *gsgp;
>> > > +
>> > > +#define rcu_assign_pointer(p,v) \
>> > > +  atomic_store_explicit(&(p), (v), memory_order_release);
>> > > +
>> > > +#define rcu_dereference(p) \
>> > > +  atomic_load_explicit(&(p), memory_order_consume);
>> > > +
>> > > +void thread0 ()
>> > > +{
>> > > +  struct rcutest *p;
>> > > +
>> > > +  p = (struct rcutest *)malloc (sizeof (*p));
>> > > +  assert (p);
>> > > +  p->a = 42;
>> > > +  rcu_assign_pointer (gp,p); /* { dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +}
>> > > +
>> > > +void thread1 ()
>> > > +{
>> > > +  struct rcutest * _Dependent_ptr p = rcu_dereference (gp); /* {
>> > > dg-warning "\\\[-Wincompatible-pointer-types]" } */
>> > > +  atomic_store_explicit(&gsgp, p, memory_order_relaxed); /* {
>> dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +}
>> > > +
>> > > +void thread2 ()
>> > > +{
>> > > +  struct rcutest *p;
>> > > +
>> > > +  p = atomic_load_explicit(&gsgp, memory_order_relaxed); /* {
>> dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +  if (p)
>> > > +    assert(p->a == 42);
>> > > +}
>> > > diff --git a/gcc/testsuite/gcc.dg/p0190r4_fig12.c
>> > > b/gcc/testsuite/gcc.dg/p0190r4_fig12.c
>> > > new file mode 100644
>> > > index 0000000..4f7fcd3
>> > > --- /dev/null
>> > > +++ b/gcc/testsuite/gcc.dg/p0190r4_fig12.c
>> > > @@ -0,0 +1,53 @@
>> > > +/* Test for _Dependent_ptr. _Dependent_ptr test when casting a
>> dependency
>> > > pointer to another pointer type which in turn reserves the dependency.
>> > > Refer figure 12 in document p0190r4 (
>> > > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf).
>> */
>> > > +/* { dg-do compile } */
>> > > +/* { dg-options "-std=c11 -pedantic" } */
>> > > +
>> > > +#include <stdatomic.h>
>> > > +
>> > > +typedef __SIZE_TYPE__ size_t;
>> > > +extern void abort (void);
>> > > +extern void exit (int);
>> > > +extern void *malloc (size_t);
>> > > +extern int assert ();
>> > > +
>> > > +struct rcutest
>> > > +{
>> > > +  int a;
>> > > +  int b;
>> > > +  int c;
>> > > +};
>> > > +
>> > > +struct rcutest1
>> > > +{
>> > > +  int a;
>> > > +  struct rcutest rt;
>> > > +};
>> > > +
>> > > +_Atomic struct rcutest *gp;
>> > > +
>> > > +#define rcu_assign_pointer(p,v) \
>> > > +  atomic_store_explicit(&(p), (v), memory_order_release);
>> > > +
>> > > +#define rcu_dereference(p) \
>> > > +  atomic_load_explicit(&(p), memory_order_consume);
>> > > +
>> > > +void thread0 ()
>> > > +{
>> > > +  struct rcutest *p;
>> > > +
>> > > +  p = (struct rcutest *)malloc (sizeof (*p));
>> > > +  assert (p);
>> > > +  p->a = 42;
>> > > +  rcu_assign_pointer (gp,p); /* { dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +}
>> > > +
>> > > +void thread1 ()
>> > > +{
>> > > +  struct rcutest * _Dependent_ptr p;
>> > > +  struct rcutest1 *_Dependent_ptr q;
>> > > +
>> > > +  p = rcu_dereference (gp); /* { dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +  q = p;                /* { dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +  if (q)
>> > > +    assert(q->a == 42);
>> > > +}
>> > > diff --git a/gcc/testsuite/gcc.dg/p0190r4_fig13.c
>> > > b/gcc/testsuite/gcc.dg/p0190r4_fig13.c
>> > > new file mode 100644
>> > > index 0000000..b4010fc
>> > > --- /dev/null
>> > > +++ b/gcc/testsuite/gcc.dg/p0190r4_fig13.c
>> > > @@ -0,0 +1,48 @@
>> > > +/* Test for _Dependent_ptr. _Dependent_ptr test: casting to
>> non-pointer
>> > > kills dependency. Refer figure 13 in document p0190r4 (
>> > > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf).
>> */
>> > > +/* { dg-do compile } */
>> > > +/* { dg-options "-std=c11 -pedantic" } */
>> > > +
>> > > +#include <stdatomic.h>
>> > > +
>> > > +typedef __SIZE_TYPE__ size_t;
>> > > +extern void abort (void);
>> > > +extern void exit (int);
>> > > +extern void *malloc (size_t);
>> > > +extern int assert ();
>> > > +
>> > > +struct rcutest
>> > > +{
>> > > +  int a;
>> > > +  int b;
>> > > +  int c;
>> > > +};
>> > > +
>> > > +_Atomic struct rcutest *gp;
>> > > +
>> > > +#define rcu_assign_pointer(p,v) \
>> > > +  atomic_store_explicit(&(p), (v), memory_order_release);
>> > > +
>> > > +#define rcu_dereference(p) \
>> > > +  atomic_load_explicit(&(p), memory_order_consume);
>> > > +
>> > > +void thread0 ()
>> > > +{
>> > > +  struct rcutest *p;
>> > > +
>> > > +  p = (struct rcutest *)malloc (sizeof (*p));
>> > > +  assert (p);
>> > > +  p->a = 42;
>> > > +  rcu_assign_pointer (gp,p); /* { dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +}
>> > > +
>> > > +void thread1 ()
>> > > +{
>> > > +  struct rcutest * _Dependent_ptr p;
>> > > +  long int q;
>> > > +
>> > > +  p = rcu_dereference (gp); /* { dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +  q = (long int)(p);
>> > > +  p = (_Dependent_ptr struct rcutest *)q;
>> > > +  if (p)
>> > > +    assert(p->a == 42);
>> > > +}
>> > > diff --git a/gcc/testsuite/gcc.dg/p0190r4_fig8.c
>> > > b/gcc/testsuite/gcc.dg/p0190r4_fig8.c
>> > > new file mode 100644
>> > > index 0000000..e706a9b
>> > > --- /dev/null
>> > > +++ b/gcc/testsuite/gcc.dg/p0190r4_fig8.c
>> > > @@ -0,0 +1,44 @@
>> > > +/* Test for _Dependent_ptr. _Dependent_ptr test for checking simple
>> > > left-hand side dependency. Refer figure 8 in document p0190r4 (
>> > > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf).
>> */
>> > > +/* { dg-do compile } */
>> > > +/* { dg-options "-std=c11 -pedantic" } */
>> > > +
>> > > +#include <stdatomic.h>
>> > > +
>> > > +typedef __SIZE_TYPE__ size_t;
>> > > +extern void abort (void);
>> > > +extern void exit (int);
>> > > +extern void *malloc (size_t);
>> > > +extern int assert ();
>> > > +
>> > > +struct rcutest
>> > > +{
>> > > +  int a;
>> > > +  int b;
>> > > +  int c;
>> > > +};
>> > > +
>> > > +_Atomic struct rcutest *gp;
>> > > +
>> > > +#define rcu_assign_pointer(p,v) \
>> > > +  atomic_store_explicit(&(p), (v), memory_order_release);
>> > > +
>> > > +#define rcu_dereference(p) \
>> > > +  atomic_load_explicit(&(p), memory_order_consume);
>> > > +
>> > > +void thread0 ()
>> > > +{
>> > > +  struct rcutest *p;
>> > > +
>> > > +  p = (struct rcutest *)malloc (sizeof (*p));
>> > > +  assert (p);
>> > > +  p->a = 42;
>> > > +  assert (p->a != 43);
>> > > +  rcu_assign_pointer (gp,p); /* { dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +}
>> > > +
>> > > +void thread1 ()
>> > > +{
>> > > +  struct rcutest * _Dependent_ptr p = rcu_dereference (gp); /* {
>> > > dg-warning "\\\[-Wincompatible-pointer-types]" } */
>> > > +  if (p)
>> > > +    p->a = 43;
>> > > +}
>> > > diff --git a/gcc/testsuite/gcc.dg/p0190r4_fig9.c
>> > > b/gcc/testsuite/gcc.dg/p0190r4_fig9.c
>> > > new file mode 100644
>> > > index 0000000..32f67b3
>> > > --- /dev/null
>> > > +++ b/gcc/testsuite/gcc.dg/p0190r4_fig9.c
>> > > @@ -0,0 +1,43 @@
>> > > +/* Test for _Dependent_ptr. _Dependent_ptr test for checking simple
>> > > right-hand side dependency. Refer figure 9 in document p0190r4 (
>> > > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf).
>> */
>> > > +/* { dg-do compile } */
>> > > +/* { dg-options "-std=c11 -pedantic" } */
>> > > +
>> > > +#include <stdatomic.h>
>> > > +
>> > > +typedef __SIZE_TYPE__ size_t;
>> > > +extern void abort (void);
>> > > +extern void exit (int);
>> > > +extern void *malloc (size_t);
>> > > +extern int assert ();
>> > > +
>> > > +struct rcutest
>> > > +{
>> > > +  int a;
>> > > +  int b;
>> > > +  int c;
>> > > +};
>> > > +
>> > > +_Atomic struct rcutest *gp;
>> > > +
>> > > +#define rcu_assign_pointer(p,v) \
>> > > +  atomic_store_explicit(&(p), (v), memory_order_release);
>> > > +
>> > > +#define rcu_dereference(p) \
>> > > +  atomic_load_explicit(&(p), memory_order_consume);
>> > > +
>> > > +void thread0 ()
>> > > +{
>> > > +  struct rcutest *p;
>> > > +
>> > > +  p = (struct rcutest *)malloc (sizeof (*p));
>> > > +  assert (p);
>> > > +  p->a = 42;
>> > > +  rcu_assign_pointer (gp,p); /* { dg-warning
>> > > "\\\[-Wincompatible-pointer-types]" } */
>> > > +}
>> > > +
>> > > +void thread1 ()
>> > > +{
>> > > +  struct rcutest * _Dependent_ptr p = rcu_dereference (gp); /* {
>> > > dg-warning "\\\[-Wincompatible-pointer-types]" } */
>> > > +  if (p)
>> > > +    assert (p->a = 42);
>> > > +}
>> > >
>> >
>>
>

Reply via email to