And please see the following URL for an update: http://www.rdrop.com/~paulmck/submission/DNNNN%20_Dependent_ptr%20to%20simplify%20carries%20a%20dependency.pdf
This adds a description of conversions, warnings, and patches. Thanx, Paul On Sun, Aug 04, 2019 at 04:11:12PM -0700, Paul E. McKenney wrote: > Good points! > > On the type-qualifier interactions, here is an initial list. Thoughts? > > Thanx, Paul > > _Alignas: Dependency-breaking optimizations would be avoided, and the > variable would be aligned as specified. > > _Atomic: Dependency-breaking optimizations would be avoided, and the > variable would be accessed using C11 atomics. > > const: This is not particularly useful for variables with static storage > duration because compile-time initialization does not require dependency > ordering, but then again, use of _Dependent_ptr on such variables is > suspect to begin with. Otherwise, the const _Dependent_ptr variable > would normally be initialized from another _Dependent_ptr variable or > from a memory_order_consume load. The variable would disallow further > stores and avoid breaking dependencies. > > extern: Dependency-breaking optimizations would be avoided, and the > variable would be usable within other translation units. This is > also an unusual addition to a _Dependent_ptr unless also accompanied by > _Thread_local because there are no known non-suspect multi-threaded-access > use cases for _Dependent_ptr. > > register: Dependency-breaking optimizations would be avoided, and the > compiler would be given a hint to keep the variable in a register. > > restrict: Dependency-breaking optimizations would be avoided, and the > compiler may assume that the pointed-to object is only accessed through > this pointer and through pointers derived from it. > > static: Dependency-breaking optimizations would be avoided, and the > variable would be static. This is also an unusual addition to a > _Dependent_ptr unless also accompanied by _Thread_local because there are > no known non-suspect multi-threaded-access use cases for _Dependent_ptr. > > _Thread_local: The dependency-carrying variable is thread-local, and > avoids dependency-breaking optimizations. > > volatile: All accesses would be executed as per the abstract machine, > and dependency-breaking optimizations would be avoided. > > On Fri, Aug 02, 2019 at 08:30:49PM -0600, Martin Sebor wrote: > > On 8/1/19 9:26 AM, Paul McKenney wrote: > > >Excellent point, this discussion needs to be made official. > > >Please see attached for an initial draft of a working paper. > > > > > >Thoughts? > > > > The draft is a start but it (obviously) needs a lot of work to cover > > the constraints and semantics so I'll just comment on the patch in > > a bit more detail. > > > > Since the feature is being (or will be) proposed to WG14 and could > > change I would expect it to be only available under -std=c2x and > > disabled otherwise, so that code that makes use of it does so with > > the understanding that it's only experimental. (I just noticed > > Akshat email with a tweak to the patch. I'm not sure that issuing > > a pedantic warning and having the name in the implementation namepace > > is enough but others (the C FE maintainers) will know better.) > > > > Other than that, I would also expect to see more extensive test > > coverage, at a minimum to exercise error detection (invalid uses, > > conversions, etc.). For example, I see the code that rejects it > > but no tests for declaring, say, a _Dependent_ptr-qualified integer. > > What I don't think I see is code that rejects _Dependent_ptr-qualified > > function pointers (AFAIK, POINTER_TYPE_P evaluates to nonzero for both). > > Is that intended? (And if so, what does it mean?) I also see that > > the new tests look for warnings but it's not clear to me that that's > > their intent or that the dg-warning directives are being used to > > "suppress" warnings for issues in the tests. For instance, this > > is common: > > > > rcu_assign_pointer (gp,p); /* { dg-warning > > "\\\[-Wincompatible-pointer-types]" } */ > > > > but neither gp nor p is a _Dependent_ptr. (I may be missing > > the purpose of the compile-only tests. E.g., the only thing > > p0190r4_fig10.c seems to be exercising besides that the _Dependent_ptr > > qualifier is accepted is a couple of warnings, one of which is the one > > above.) I would suggest to look at tests for other qualifiers for > > examples and model the new ones after those. > > > > I'm also wondering how the new qualifier interacts with others like > > const. Should all combinations of qualifiers be accepted and do > > they affect the semantics in any interesting way? This is probably > > something to cover in the proposal. > > > > Martin > > > > > > > > Thanx, Paul > > > > > >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 > > >> > > >>>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); > > >>>+} > > >>> > > >> > >