(Not a proper review really.) On Tue, Aug 08, 2017 at 10:13:07AM -0600, Martin Sebor wrote: > @@ -490,7 +583,9 @@ decl_attributes (tree *node, tree attributes, int flags) > | (int) ATTR_FLAG_ARRAY_NEXT)) > { > /* Pass on this attribute to be tried again. */ > - returned_attrs = tree_cons (name, args, returned_attrs); > + tree attr = tree_cons (name, args, NULL_TREE); > + returned_attrs = chainon (returned_attrs, attr); > + // returned_attrs = tree_cons (name, args, returned_attrs); > continue; > } > else > @@ -535,7 +630,9 @@ decl_attributes (tree *node, tree attributes, int flags) > else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT) > { > /* Pass on this attribute to be tried again. */ > - returned_attrs = tree_cons (name, args, returned_attrs); > + tree attr = tree_cons (name, args, NULL_TREE); > + returned_attrs = chainon (returned_attrs, attr); > + // returned_attrs = tree_cons (name, args, returned_attrs);
What's with these // lines? I suppose they weren't supposed to be here. > + /* If the attribute was sussceefully handled on its own and is "successfully" > diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c > index e970ab2..8bbfcb5 100644 > --- a/gcc/c-family/c-warn.c > +++ b/gcc/c-family/c-warn.c > @@ -2143,36 +2143,19 @@ diagnose_mismatched_attributes (tree olddecl, tree > newdecl) > newdecl); > > /* Diagnose inline __attribute__ ((noinline)) which is silly. */ > + const char* noinline = "noinline"; "const char *noinline" > --- a/gcc/cp/name-lookup.c > +++ b/gcc/cp/name-lookup.c > @@ -2291,6 +2291,71 @@ set_local_extern_decl_linkage (tree decl, bool > shadowed) > } > } > > +/* Given a new DECL that hasn't been pushed yet, try to find the last > + DECL for the same symbol and return it, oterwise return null. */ > + > +tree > +find_decl (tree decl) > +{ > + if (!DECL_P (decl)) > + return NULL_TREE; > + > + /* if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl) */ > + /* set_decl_context_in_fn (current_function_decl, decl); */ Looks like some stray lines. > + > + /* The binding level we will be pushing into. During local class > + pushing, we want to push to the containing scope. */ > + cp_binding_level *level = current_binding_level; > + while (level->kind == sk_class) > + level = level->level_chain; > + > + tree name = DECL_NAME (decl); > + if (!name) > + return NULL_TREE; > + > + cxx_binding *binding = NULL; /* Local scope binding. */ > + tree ns = NULL_TREE; /* Searched namespace. */ > + tree *slot = NULL; /* Binding slot in namespace. */ > + tree old = NULL_TREE; > + > + if (level->kind == sk_namespace) > + { > + /* We look in the decl's namespace for an existing > + declaration, even though we push into the current > + namespace. */ > + ns = (DECL_NAMESPACE_SCOPE_P (decl) > + ? CP_DECL_CONTEXT (decl) : current_namespace); > + /* Create the binding, if this is current namespace, because > + that's where we'll be pushing anyway. */ > + slot = find_namespace_slot (ns, name, ns == current_namespace); > + if (slot) > + old = MAYBE_STAT_DECL (*slot); > + } > + else > + { > + binding = find_local_binding (level, name); > + if (binding) > + old = binding->value; > + } > + > + /* if (current_function_decl && VAR_OR_FUNCTION_DECL_P (decl) */ > + /* && DECL_EXTERNAL (decl)) */ > + /* set_local_extern_decl_linkage (decl, old != NULL_TREE); */ Here too. > + if (old == error_mark_node) > + old = NULL_TREE; > + > + for (ovl_iterator iter (old); iter; ++iter) > + { > + if (iter.using_p ()) > + ; /* Ignore using decls here. */ > + else if (decls_match (decl, *iter, /*record_decls=*/false)) > + return *iter; > + } > + > + return NULL_TREE; > +} > + > /* Record DECL as belonging to the current lexical scope. Check for > errors (such as an incompatible declaration for the same name > already seen in the same scope). IS_FRIEND is true if DECL is > diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h > index 2e2075c..ce0826e 100644 > --- a/gcc/cp/name-lookup.h > +++ b/gcc/cp/name-lookup.h > @@ -339,4 +339,6 @@ extern void pop_nested_namespace (tree); > extern void push_to_top_level (void); > extern void pop_from_top_level (void); > > +extern tree find_decl (tree); > + > #endif /* GCC_CP_NAME_LOOKUP_H */ > diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c > index 8f18665..6cbf4b2 100644 > --- a/gcc/cp/tree.c > +++ b/gcc/cp/tree.c > @@ -4314,10 +4314,10 @@ const struct attribute_spec cxx_attribute_table[] = > /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, > affects_type_identity } */ > { "init_priority", 1, 1, true, false, false, > - handle_init_priority_attribute, false }, > + handle_init_priority_attribute, false, NULL }, > { "abi_tag", 1, -1, false, false, false, > - handle_abi_tag_attribute, true }, > - { NULL, 0, 0, false, false, false, NULL, false } > + handle_abi_tag_attribute, true, NULL }, > + { NULL, 0, 0, false, false, false, NULL, false, NULL } > }; > > /* Table of C++ standard attributes. */ > @@ -4326,10 +4326,10 @@ const struct attribute_spec std_attribute_table[] = > /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, > affects_type_identity } */ > { "maybe_unused", 0, 0, false, false, false, > - handle_unused_attribute, false }, > + handle_unused_attribute, false, NULL }, > { "nodiscard", 0, 0, false, false, false, > - handle_nodiscard_attribute, false }, > - { NULL, 0, 0, false, false, false, NULL, false } > + handle_nodiscard_attribute, false, NULL }, > + { NULL, 0, 0, false, false, false, NULL, false, NULL } > }; > > /* Handle an "init_priority" attribute; arguments as in > diff --git a/gcc/tree-core.h b/gcc/tree-core.h > index 278d0c9..943b349 100644 > --- a/gcc/tree-core.h > +++ b/gcc/tree-core.h > @@ -1933,6 +1933,20 @@ struct attribute_spec { > int flags, bool *no_add_attrs); > /* Specifies if attribute affects type's identity. */ > bool affects_type_identity; > + > + /* Specifies the name of an attribute that's mutually exclusive with > + this one, and whether the relationship applies to the function, > + variable, or type form of the attribute. */ > + struct exclusions { > + const char* name; "const char *name" > + bool function; > + bool variable; > + bool type; > + }; > + > + /* An array of attribute exclusions describing names of other attributes > + that this attribute is mutually exclusive with. */ > + const exclusions* exclude; "const exclusions *exclude;" > }; > > /* These functions allow a front-end to perform a manual layout of a > diff --git a/libstdc++-v3/include/ext/mt_allocator.h > b/libstdc++-v3/include/ext/mt_allocator.h > index effb13b..f349ff8 100644 > --- a/libstdc++-v3/include/ext/mt_allocator.h > +++ b/libstdc++-v3/include/ext/mt_allocator.h > @@ -355,7 +355,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > } > > // XXX GLIBCXX_ABI Deprecated > - _GLIBCXX_CONST void > + void > _M_destroy_thread_key(void*) throw (); > > size_t Why this change? Seems unrelated. > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c > b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c > index 146b76c..58a4742 100644 > --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c > +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c > @@ -113,7 +113,7 @@ int test9 (int *intarr) > > int test99 (int *intarr) > { > - extern int foo9 (int) __attribute__ ((pure)); > + extern int foo9 (int) __attribute__ ((const)); > int h, v; > g9 = 9; > h = foo9 (g9); > And why this? I'd avoid modifying existing tests like that unless it's directly related to the new diagnostic. Marek