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); >> > > +} >> > > >> > >> >