+2015-05-22 Marek Polacek <polacek@redhat.com>
+
+ PR c/47043
+ * doc/extend.texi (Enumerator Attributes): New section.
+ Document syntax of enumerator attributes.
+
2015-05-22 Richard Biener <rguenther@suse.de>
* tree-vect-loop.c (get_reduction_op): New function.
+2015-05-22 Marek Polacek <polacek@redhat.com>
+
+ PR c/47043
+ * c-common.c (handle_deprecated_attribute): Allow CONST_DECL.
+
2015-05-20 Trevor Saunders <tbsaunde+gcc@tbsaunde.org>
* c-cppbuiltin.c (c_cpp_builtins): Use if instead of #if with
|| TREE_CODE (decl) == PARM_DECL
|| VAR_OR_FUNCTION_DECL_P (decl)
|| TREE_CODE (decl) == FIELD_DECL
+ || TREE_CODE (decl) == CONST_DECL
|| objc_method_decl (TREE_CODE (decl)))
TREE_DEPRECATED (decl) = 1;
else
+2015-05-22 Marek Polacek <polacek@redhat.com>
+
+ PR c/47043
+ * c-parser.c (c_parser_enum_specifier): Parse and apply enumerator
+ attributes.
+
2015-05-21 Marek Polacek <polacek@redhat.com>
* c-typeck.c (inform_declaration): Use DECL_IS_BUILTIN instead of
enumerator:
enumeration-constant
enumeration-constant = constant-expression
+
+ GNU Extensions:
+
+ enumerator:
+ enumeration-constant attributes[opt]
+ enumeration-constant attributes[opt] = constant-expression
+
*/
static struct c_typespec
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);
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;
+2015-05-22 Marek Polacek <polacek@redhat.com>
+ Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c/47043
+ * cp-tree.h (build_enumerator): Update declaration.
+ * decl.c (build_enumerator): Add attributes parameter. Call
+ cplus_decl_attributes.
+ * init.c (constant_value_1): Pass tf_none 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.
+
2015-05-21 Nathan Sidwell <nathan@acm.org>
PR c++/60943
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 *,
/* 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;
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
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, tf_none);
mark_rvalue_use (decl);
init = DECL_INITIAL (decl);
if (init == error_mark_node)
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)
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))
{
value = error_mark_node;
/* Create the enumerator. */
- build_enumerator (identifier, value, type, loc);
+ build_enumerator (identifier, value, type, attrs, loc);
}
/* Parse a namespace-name.
/* Give this enumeration constant the correct access. */
set_current_access_from_decl (decl);
- /* Actually build the enumerator itself. */
- build_enumerator
- (DECL_NAME (decl), value, newtag, DECL_SOURCE_LOCATION (decl));
+ /* Actually build the enumerator itself. Here we're assuming that
+ enumerators can't have dependent attributes. */
+ build_enumerator (DECL_NAME (decl), value, newtag,
+ DECL_ATTRIBUTES (decl), DECL_SOURCE_LOCATION (decl));
}
if (SCOPED_ENUM_P (newtag))
}
}
- /* 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;
}
* 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.
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
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}).
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.
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
@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
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}
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},
+2015-05-22 Marek Polacek <polacek@redhat.com>
+
+ PR c/47043
+ * 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.
+
2015-05-21 Sandra Loosemore <sandra@codesourcery.com>
* gcc.target/arm/simd/simd.exp: Skip all tests if no arm_neon_ok
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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" } */
+};
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}