I'm pinging the C++ parts. Thanks,
> On Thu, May 07, 2015 at 06:22:40PM +0200, Marek Polacek wrote: > > This (third) version of the patch entails the change in tsubst_enum Ed > > suggested + new testcase. > > > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > > > 2015-05-07 Marek Polacek <pola...@redhat.com> > > Edward Smith-Rowland <3dw...@verizon.net> > > > > PR c/47043 > > * c-common.c (handle_deprecated_attribute): Allow CONST_DECL. > > > > * c-parser.c (c_parser_enum_specifier): Parse and apply enumerator > > attributes. > > > > * cp-tree.h (build_enumerator): Update declaration. > > * decl.c (build_enumerator): Add attributes parameter. Call > > cplus_decl_attributes. > > * init.c (constant_value_1): Pass 0 to mark_used. > > * parser.c (cp_parser_enumerator_definition): Parse attributes and > > pass them down to build_enumerator. > > * pt.c (tsubst_enum): Pass decl attributes to build_enumerator. > > * semantics.c (finish_id_expression): Don't warn_deprecated_use here. > > > > * doc/extend.texi (Enumerator Attributes): New section. > > Document syntax of enumerator attributes. > > > > * c-c++-common/attributes-enum-1.c: New test. > > * c-c++-common/attributes-enum-2.c: New test. > > * g++.dg/cpp0x/attributes-enum-1.C: New test. > > * g++.dg/cpp1y/attributes-enum-1.C: New test. > > > > diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c > > index ada8e8a..36968e5 100644 > > --- gcc/c-family/c-common.c > > +++ gcc/c-family/c-common.c > > @@ -8810,6 +8810,7 @@ handle_deprecated_attribute (tree *node, tree name, > > || TREE_CODE (decl) == VAR_DECL > > || TREE_CODE (decl) == FUNCTION_DECL > > || TREE_CODE (decl) == FIELD_DECL > > + || TREE_CODE (decl) == CONST_DECL > > || objc_method_decl (TREE_CODE (decl))) > > TREE_DEPRECATED (decl) = 1; > > else > > diff --git gcc/c/c-parser.c gcc/c/c-parser.c > > index bf0e4c57..889e6d7 100644 > > --- gcc/c/c-parser.c > > +++ gcc/c/c-parser.c > > @@ -2516,6 +2516,13 @@ c_parser_declspecs (c_parser *parser, struct > > c_declspecs *specs, > > enumerator: > > enumeration-constant > > enumeration-constant = constant-expression > > + > > + GNU Extensions: > > + > > + enumerator: > > + enumeration-constant attributes[opt] > > + enumeration-constant attributes[opt] = constant-expression > > + > > */ > > > > static struct c_typespec > > @@ -2575,6 +2582,8 @@ c_parser_enum_specifier (c_parser *parser) > > c_parser_set_source_position_from_token (token); > > decl_loc = value_loc = token->location; > > c_parser_consume_token (parser); > > + /* Parse any specified attributes. */ > > + tree enum_attrs = c_parser_attributes (parser); > > if (c_parser_next_token_is (parser, CPP_EQ)) > > { > > c_parser_consume_token (parser); > > @@ -2584,7 +2593,9 @@ c_parser_enum_specifier (c_parser *parser) > > else > > enum_value = NULL_TREE; > > enum_decl = build_enumerator (decl_loc, value_loc, > > - &the_enum, enum_id, enum_value); > > + &the_enum, enum_id, enum_value); > > + if (enum_attrs) > > + decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0); > > TREE_CHAIN (enum_decl) = values; > > values = enum_decl; > > seen_comma = false; > > diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h > > index e0fbf5e..6b26cb1 100644 > > --- gcc/cp/cp-tree.h > > +++ gcc/cp/cp-tree.h > > @@ -5400,7 +5400,7 @@ extern bool xref_basetypes (tree, > > tree); > > extern tree start_enum (tree, tree, tree, > > bool, bool *); > > extern void finish_enum_value_list (tree); > > extern void finish_enum (tree); > > -extern void build_enumerator (tree, tree, tree, > > location_t); > > +extern void build_enumerator (tree, tree, tree, > > tree, location_t); > > extern tree lookup_enumerator (tree, tree); > > extern bool start_preparsed_function (tree, tree, int); > > extern bool start_function (cp_decl_specifier_seq *, > > diff --git gcc/cp/decl.c gcc/cp/decl.c > > index 261a12d..ebbd585 100644 > > --- gcc/cp/decl.c > > +++ gcc/cp/decl.c > > @@ -13067,11 +13067,12 @@ finish_enum (tree enumtype) > > > > /* Build and install a CONST_DECL for an enumeration constant of the > > enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided. > > - LOC is the location of NAME. > > + Apply ATTRIBUTES if available. LOC is the location of NAME. > > Assignment of sequential values by default is handled here. */ > > > > void > > -build_enumerator (tree name, tree value, tree enumtype, location_t loc) > > +build_enumerator (tree name, tree value, tree enumtype, tree attributes, > > + location_t loc) > > { > > tree decl; > > tree context; > > @@ -13234,6 +13235,9 @@ incremented enumerator value is too large for > > %<long%>"); > > TREE_READONLY (decl) = 1; > > DECL_INITIAL (decl) = value; > > > > + if (attributes) > > + cplus_decl_attributes (&decl, attributes, 0); > > + > > if (context && context == current_class_type && !SCOPED_ENUM_P > > (enumtype)) > > /* In something like `struct S { enum E { i = 7 }; };' we put `i' > > on the TYPE_FIELDS list for `S'. (That's so that you can say > > diff --git gcc/cp/init.c gcc/cp/init.c > > index c41e30c..9298f2d 100644 > > --- gcc/cp/init.c > > +++ gcc/cp/init.c > > @@ -2035,7 +2035,7 @@ constant_value_1 (tree decl, bool strict_p, bool > > return_aggregate_cst_ok_p) > > specialization, we must instantiate it here. The > > initializer for the static data member is not processed > > until needed; we need it now. */ > > - mark_used (decl); > > + mark_used (decl, 0); > > mark_rvalue_use (decl); > > init = DECL_INITIAL (decl); > > if (init == error_mark_node) > > diff --git gcc/cp/parser.c gcc/cp/parser.c > > index 30a3fab..420759e 100644 > > --- gcc/cp/parser.c > > +++ gcc/cp/parser.c > > @@ -16056,7 +16056,13 @@ cp_parser_enumerator_list (cp_parser* parser, tree > > type) > > enumerator = constant-expression > > > > enumerator: > > - identifier */ > > + identifier > > + > > + GNU Extensions: > > + > > + enumerator-definition: > > + enumerator attributes [opt] > > + enumerator attributes [opt] = constant-expression */ > > > > static void > > cp_parser_enumerator_definition (cp_parser* parser, tree type) > > @@ -16074,6 +16080,9 @@ cp_parser_enumerator_definition (cp_parser* parser, > > tree type) > > if (identifier == error_mark_node) > > return; > > > > + /* Parse any specified attributes. */ > > + tree attrs = cp_parser_attributes_opt (parser); > > + > > /* If the next token is an '=', then there is an explicit value. */ > > if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) > > { > > @@ -16091,7 +16100,7 @@ cp_parser_enumerator_definition (cp_parser* parser, > > tree type) > > value = error_mark_node; > > > > /* Create the enumerator. */ > > - build_enumerator (identifier, value, type, loc); > > + build_enumerator (identifier, value, type, attrs, loc); > > } > > > > /* Parse a namespace-name. > > diff --git gcc/cp/pt.c gcc/cp/pt.c > > index 8e0e789..d5e2b56 100644 > > --- gcc/cp/pt.c > > +++ gcc/cp/pt.c > > @@ -20686,8 +20686,8 @@ tsubst_enum (tree tag, tree newtag, tree args) > > set_current_access_from_decl (decl); > > > > /* Actually build the enumerator itself. */ > > - build_enumerator > > - (DECL_NAME (decl), value, newtag, DECL_SOURCE_LOCATION (decl)); > > + build_enumerator (DECL_NAME (decl), value, newtag, > > + DECL_ATTRIBUTES (decl), DECL_SOURCE_LOCATION (decl)); > > } > > > > if (SCOPED_ENUM_P (newtag)) > > diff --git gcc/cp/semantics.c gcc/cp/semantics.c > > index 701a8eb..b46c6fc 100644 > > --- gcc/cp/semantics.c > > +++ gcc/cp/semantics.c > > @@ -3651,11 +3651,6 @@ finish_id_expression (tree id_expression, > > } > > } > > > > - /* Handle references (c++/56130). */ > > - tree t = REFERENCE_REF_P (decl) ? TREE_OPERAND (decl, 0) : decl; > > - if (TREE_DEPRECATED (t)) > > - warn_deprecated_use (t, NULL_TREE); > > - > > return decl; > > } > > > > diff --git gcc/doc/extend.texi gcc/doc/extend.texi > > index c290059..4337a32 100644 > > --- gcc/doc/extend.texi > > +++ gcc/doc/extend.texi > > @@ -59,6 +59,7 @@ extensions, accepted by GCC in C90 mode and in C++. > > * Variable Attributes:: Specifying attributes of variables. > > * Type Attributes:: Specifying attributes of types. > > * Label Attributes:: Specifying attributes on labels. > > +* Enumerator Attributes:: Specifying attributes on enumerators. > > * Attribute Syntax:: Formal syntax for attributes. > > * Function Prototypes:: Prototype declarations and old-style definitions. > > * C++ Comments:: C++ comments are recognized. > > @@ -2175,6 +2176,7 @@ attribute syntax and placement. > > GCC also supports attributes on > > variable declarations (@pxref{Variable Attributes}), > > labels (@pxref{Label Attributes}), > > +enumerators (@pxref{Enumerator Attributes}), > > and types (@pxref{Type Attributes}). > > > > There is some overlap between the purposes of attributes and pragmas > > @@ -5041,8 +5043,9 @@ by an attribute specification inside double > > parentheses. Some > > attributes are currently defined generically for variables. > > Other attributes are defined for variables on particular target > > systems. Other attributes are available for functions > > -(@pxref{Function Attributes}), labels (@pxref{Label Attributes}) and for > > -types (@pxref{Type Attributes}). > > +(@pxref{Function Attributes}), labels (@pxref{Label Attributes}), > > +enumerators (@pxref{Enumerator Attributes}), and for types > > +(@pxref{Type Attributes}). > > Other front ends might define more attributes > > (@pxref{C++ Extensions,,Extensions to the C++ Language}). > > > > @@ -5837,7 +5840,8 @@ attributes of types. Some type attributes apply only > > to @code{struct} > > and @code{union} types, while others can apply to any type defined > > via a @code{typedef} declaration. Other attributes are defined for > > functions (@pxref{Function Attributes}), labels (@pxref{Label > > -Attributes}) and for variables (@pxref{Variable Attributes}). > > +Attributes}), enumerators (@pxref{Enumerator Attributes}), and for > > +variables (@pxref{Variable Attributes}). > > > > The @code{__attribute__} keyword is followed by an attribute specification > > inside double parentheses. > > @@ -6300,7 +6304,8 @@ compilers to match the native Microsoft compiler. > > GCC allows attributes to be set on C labels. @xref{Attribute Syntax}, for > > details of the exact syntax for using attributes. Other attributes are > > available for functions (@pxref{Function Attributes}), variables > > -(@pxref{Variable Attributes}) and for types (@pxref{Type Attributes}). > > +(@pxref{Variable Attributes}), enumerators (@xref{Enumerator Attributes}), > > +and for types (@pxref{Type Attributes}). > > > > This example uses the @code{cold} label attribute to indicate the > > @code{ErrorHandling} branch is unlikely to be taken and that the > > @@ -6346,6 +6351,45 @@ with computed goto or @code{asm goto}. > > > > @end table > > > > +@node Enumerator Attributes > > +@section Enumerator Attributes > > +@cindex Enumerator Attributes > > + > > +GCC allows attributes to be set on enumerators. @xref{Attribute Syntax}, > > for > > +details of the exact syntax for using attributes. Other attributes are > > +available for functions (@pxref{Function Attributes}), variables > > +(@pxref{Variable Attributes}), labels (@xref{Label Attributes}), > > +and for types (@pxref{Type Attributes}). > > + > > +This example uses the @code{deprecated} enumerator attribute to indicate > > the > > +@code{oldval} enumerator is deprecated: > > + > > +@smallexample > > +enum E @{ > > + oldval __attribute__((deprecated)), > > + newval > > +@}; > > + > > +int > > +fn (void) > > +@{ > > + return oldval; > > +@} > > +@end smallexample > > + > > +@table @code > > +@item deprecated > > +@cindex @code{deprecated} enumerator attribute > > +The @code{deprecated} attribute results in a warning if the enumerator > > +is used anywhere in the source file. This is useful when identifying > > +enumerators that are expected to be removed in a future version of a > > +program. The warning also includes the location of the declaration > > +of the deprecated enumerator, to enable users to easily find further > > +information about why the enumerator is deprecated, or what they should > > +do instead. Note that the warnings only occurs for uses. > > + > > +@end table > > + > > @node Attribute Syntax > > @section Attribute Syntax > > @cindex attribute syntax > > @@ -6371,6 +6415,8 @@ for details of the semantics of attributes applying > > to structure, union > > and enumerated types. > > @xref{Label Attributes}, for details of the semantics of attributes > > applying to labels. > > +@xref{Enumerator Attributes}, for details of the semantics of attributes > > +applying to enumerators. > > > > An @dfn{attribute specifier} is of the form > > @code{__attribute__ ((@var{attribute-list}))}. An @dfn{attribute list} > > @@ -6428,6 +6474,14 @@ ambiguous, as it is permissible for a declaration, > > which could begin > > with an attribute list, to be labelled in C++. Declarations cannot be > > labelled in C90 or C99, so the ambiguity does not arise there. > > > > +@subsubheading Enumerator Attributes > > + > > +In GNU C, an attribute specifier list may appear as part of an enumerator. > > +The attribute goes after the enumeration constant, before @code{=}, if > > +present. The optional attribute in the enumerator appertains to the > > +enumeration constant. It is not possible to place the attribute after > > +the constant expression, if present. > > + > > @subsubheading Type Attributes > > > > An attribute specifier list may appear as part of a @code{struct}, > > diff --git gcc/testsuite/c-c++-common/attributes-enum-1.c > > gcc/testsuite/c-c++-common/attributes-enum-1.c > > index e69de29..cb5af5b 100644 > > --- gcc/testsuite/c-c++-common/attributes-enum-1.c > > +++ gcc/testsuite/c-c++-common/attributes-enum-1.c > > @@ -0,0 +1,22 @@ > > +/* Test enumerators with attributes. */ > > +/* PR c/47043 */ > > +/* { dg-do compile } */ > > + > > +enum E { > > + A __attribute__((deprecated)), > > + B __attribute__((deprecated ("foo"))), > > + C __attribute__((deprecated)) = 10, > > + D __attribute__((deprecated ("foo"))) = 15, > > + E > > +}; > > + > > +int > > +f (int i) > > +{ > > + i += A; /* { dg-warning ".A. is deprecated" } */ > > + i += B; /* { dg-warning ".B. is deprecated" } */ > > + i += C; /* { dg-warning ".C. is deprecated" } */ > > + i += D; /* { dg-warning ".D. is deprecated" } */ > > + i += E; > > + return i; > > +} > > diff --git gcc/testsuite/c-c++-common/attributes-enum-2.c > > gcc/testsuite/c-c++-common/attributes-enum-2.c > > index e69de29..f143f15 100644 > > --- gcc/testsuite/c-c++-common/attributes-enum-2.c > > +++ gcc/testsuite/c-c++-common/attributes-enum-2.c > > @@ -0,0 +1,14 @@ > > +/* Test enumerators with attributes. Test invalid uses. */ > > +/* PR c/47043 */ > > +/* { dg-do compile } */ > > + > > +enum E { > > + A __attribute__((foo)), /* { dg-warning "ignored" } */ > > + B __attribute__((cold)), /* { dg-warning "ignored" } */ > > + C __attribute__((const)), /* { dg-warning "ignored" } */ > > + D __attribute__((unused)), /* { dg-warning "ignored" } */ > > + E __attribute__((flatten)), /* { dg-warning "ignored" } */ > > + F __attribute__((tm)), /* { dg-warning "ignored" } */ > > + G __attribute__((common)), /* { dg-warning "ignored" } */ > > + H __attribute__((volatile)), /* { dg-warning "ignored" } */ > > +}; > > diff --git gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C > > gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C > > index e69de29..fd1b6f0 100644 > > --- gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C > > +++ gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C > > @@ -0,0 +1,20 @@ > > +// PR c/47043 > > +// { dg-do compile { target c++11 } } > > + > > +enum E { > > + A [[gnu::deprecated]] > > +}; > > + > > +enum class F { > > + B [[gnu::deprecated]], > > + C __attribute__ ((deprecated)) > > +}; > > + > > +int > > +f (int i) > > +{ > > + F f1 = F::B; // { dg-warning ".B. is deprecated" } > > + F f2 = F::C; // { dg-warning ".C. is deprecated" } > > + i += A; // { dg-warning ".A. is deprecated" } > > + return i; > > +} > > diff --git gcc/testsuite/g++.dg/cpp1y/attributes-enum-1.C > > gcc/testsuite/g++.dg/cpp1y/attributes-enum-1.C > > index e69de29..3bd1ba1 100644 > > --- gcc/testsuite/g++.dg/cpp1y/attributes-enum-1.C > > +++ gcc/testsuite/g++.dg/cpp1y/attributes-enum-1.C > > @@ -0,0 +1,35 @@ > > +// PR c/47043 > > +// { dg-do compile { target c++14 } } > > + > > +class C > > +{ > > +public: > > + enum Foo > > + { > > + T, > > + U [[deprecated("unused")]], > > + V > > + }; > > +}; > > + > > +template<typename Tp> > > + class D > > + { > > + public: > > + enum Bar > > + { > > + X, > > + Y [[deprecated("unused")]], > > + Z > > + }; > > + }; > > + > > +int > > +f (int i) > > +{ > > + auto j = C::U; // { dg-warning ".U. is deprecated" } > > + > > + auto k = D<int>::Y; // { dg-warning ".Y. is deprecated" } > > + > > + return i; > > +} Marek