Bug 53528 - Support C++11 generalized attributes
Summary: Support C++11 generalized attributes
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: 4.8.0
Assignee: Dodji Seketeli
URL:
Keywords:
Depends on:
Blocks: 51776
  Show dependency treegraph
 
Reported: 2012-05-30 12:49 UTC by Dodji Seketeli
Modified: 2023-01-19 05:11 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-05-30 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dodji Seketeli 2012-05-30 12:49:37 UTC
G++ should support the generalized attributes feature presented in the N2761 paper at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf.
Comment 1 jsm-csl@polyomino.org.uk 2012-05-30 13:47:38 UTC
Note that the syntactic binding of C++11 attributes is different from that 
of GNU attributes in various cases, so the front end will need to track 
separately what attributes of each syntax have been used in various 
places.
Comment 2 Michal Malecki 2012-06-25 08:11:16 UTC
If this feature is going to be used also for extended GNU attributes, it can be done via a special extension:

[[gnu init_priority(200)]]
[[gnu format(printf, 2, 3)]]

would be same as:

__attribute__ ((init_priority (200)))
__attribute__ ((format(printf, 2, 3)))

Some standard attributes can be also implemented as alias to existing gnu attributes, for example [[gnu noreturn]] would be the same as [[noreturn]].

Currently the only standard attributes are "noreturn" and "carries_dependency". They don't get any arguments, so I don't think the difference to current attribute syntax matters.
Comment 3 Jonathan Wakely 2012-06-25 08:32:29 UTC
There's no need for an extension, the grammar allows [[gnu::init_priority(200)]]
Comment 4 Dodji Seketeli 2012-07-26 15:27:17 UTC
A candidate implementation patch for this has been posted to http://gcc.gnu.org/ml/gcc-patches/2012-07/msg01348.html

@Joseph:
Thank you for the note.  I believe the patch handles this, unless I have forgotten things.

@Michal Malecki / Jonathan Wakely
The scoped attributes syntax [[gnu::priority(200)]] is now supported.  The patch has put all the GNU attributes in the "gnu" namespace by default.  So now whenever one writes __attribute__((priority(200))), the priority attribute is looked up from or put into the "gnu" namespace.

We'll see what comes out of the discussion that arises from the patch submission.
Comment 5 Michal Malecki 2012-07-26 20:18:36 UTC
Looks nice. Is that a big deal if you also make a standard [[noreturn]] attribute simply an alias to [[gnu::noreturn]]? As far as I know the standard, they should behave exactly the same way.

Another thing is that I think this should work, according to the standard:

void quit [[gnu::noreturn]] () { throw 0; }

And it doesn't with this patch. Of course, [[gnu::noreturn]] void quit()... works and is more intuitive, but both are required by the standard. I guess the difference is when you'd do this:

int quit [[noreturn]](), pass(); // pass does return!

while here both are noreturn:

[[noreturn]] int quit(), pass();
Comment 6 Dodji Seketeli 2012-10-08 09:29:13 UTC
Author: dodji
Date: Mon Oct  8 09:29:05 2012
New Revision: 192199

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=192199
Log:
PR c++/53528 C++11 attribute support

This patch implements the c++-11 generalized attributes, described in
the N2761 paper[1].

The idea is to modify the front-end to accept the new attribute syntax
(including alignas expressions) and to build an internal
representation similar to the one we already have for GNU attributes.

This lets us re-use our existing GNU attribute mechanisms to support
the generalized c++11 attributes.

The patch does change the existing internal representation to support
scoped attribute (aka attributes with namespaces), which is a concept
that doesn't exist in GNU attributes.  I have thus put all existing
GNU extension attributes into the "gnu" namespace.  For instance, in
C++-11, the "unused" attribute would be represented as
"[[gnu::unused]]".  Because there is no syntax for scoped attributes
in C, writting "__attribute__((unused))" unconditionnally refers to
the "unused" attribute in the "gnu" namespace.

Note that this patch follows a conservative understanding of the
specification by disallowing attributes appertaining to types, unless
they apply to a type definition.

Tested on x86_64-unknown-linux-gnu and powerpc64-unknown-linux-gnu.

[1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf

gcc/
	* plugin.h (register_scoped_attributes): Declare new function.
	* tree.h (enu attribute_flags::ATTR_FLAG_CXX_11): New flag.
	(lookup_scoped_attribute_spec, cxx_11_attribute_p)
	(get_attribute_name, get_attribute_namespace): Declare new functions.
	(struct attribute_spec): Remove const qualifier from the members.
	* tree.c (comp_type_attributes, private_lookup_attribute)
	(lookup_ident_attribute, remove_attribute, merge_attribute)
	(attribute_hash_list, attribute_list_contained): Use
	get_attribute_name.
	* attribs.c (decl_attributes): Don't crash on error_mark_node.
	Forbid c++11 attributes appertaining to type-specifiers.
	(attribute_hash): Remove global variable.
	(attributes_table): New global variable.
	(find_attribute_namespace, register_scoped_attribute): New static
	functions.
	(register_scoped_attributes, lookup_scoped_attribute_spec)
	(cxx11_attribute_p, get_attribute_name, get_attribute_namespace):
	New public functions.
	(init_attributes): Register all the GNU attributes into the "gnu"
	namespace.
	(register_attribute): Use register_scoped_attribute to register
	the attribute into the "gnu" namespace.
	(lookup_attribute_spec): Use lookup_scoped_attribute_spec to
	lookup the attribute in the "gnu" namespace.
	(decl_attributes): Use new get_attribute_namespace and
	lookup_scoped_attribute_spec to consider attribute namespaces when
	looking up attributes.  When operating in c++-11 mode, pass flag
	ATTR_FLAG_CXX11 to the spec handler.

gcc/c-family/

	* c-common.h (bitfield_p, cxx_fundamental_alignment_p): Declare
	new functions.
	* c-common.c (check_cxx_fundamental_alignment_constraints): New
	static function.
	(handle_aligned_attribute): In choose strictest alignment
	among many.  Use new check_cxx_fundamental_alignment_constraints.
	(handle_transparent_union_attribute): In c++11 attribute syntax,
	don't look through typedefs.

gcc/cp/

	* cp-tree.h (enum cpp0x_warn_str::CPP0X_ATTRIBUTES): New member.
	(enum cp_decl_spec::ds_std_attribute): New enumerator.
	(struct cp_decl_specifier_seq::std_attributes): New field.
	(cxx_alignas_expr, warn_misplaced_attr_for_class_type): Declare
	new functions.
	(check_tag_decl): Take an extra parameter for explicit
	instantiations.
	* decl.c (warn_misplaced_attr_for_class_type): Extract from ...
	(check_tag_decl): ... here.  Add check for c++11 attributes being
	applied to an explicit instantiation.  Take an extra parameter for
	explicit instantiations.
	(grokdeclarator): Make sure a c++11 attribute after an array
	declarator appertains to the array, an attribute after a function
	declarator appertains to the function type, an attribute after a
	declarator-id appertains to the entity being declared, and an
	attribute after a pointer declarator appertains to the pointer.
	* decl2.c (is_late_template_attribute): Use get_attribute_name.
	* error.c (maybe_warn_cpp0x): Support
	CPP0X_GENERALIZED_ATTRIBUTES.
	* parser.c (cp_next_tokens_can_be_attribute_p)
	(cp_next_tokens_can_be_gnu_attribute_p)
	(cp_next_tokens_can_be_std_attribute_p)
	(cp_nth_tokens_can_be_attribute_p)
	(cp_nth_tokens_can_be_gnu_attribute_p)
	(cp_nth_tokens_can_be_std_attribute_p)
	(cp_parser_gnu_attribute_list, cp_parser_std_attribute)
	(cp_parser_std_attribute_spec, cp_parser_std_attribute_spec_seq)
	(cp_parser_attributes_opt, cp_parser_std_attribute_list): New
	static functions.
	(cp_parser_gnu_attributes_opt): Replace cp_parser_attributes_opt.
	(cp_parser_gnu_attribute_list): Replace cp_parser_attribute_list.
	(cp_parser_postfix_expression): Disallow "[[" tokens here.
	(cp_parser_label_for_labeled_statement): Use take an extra
	parameter for attributes.
	(cp_parser_block_declaration): Use
	cp_nth_tokens_can_be_std_attribute_p here.
	(cp_parser_decl_specifier_seq): Likewise.  Store C++11 attributes
	that appears in in decl specifiers in cp_decl_specifier_seq::std_attributes.
	declaration.  Emit proper warning about misplaced c++11 attributes
	for class type.
	(cp_parser_explicit_instantiation): Adjust call to check_tag_decl.
	(cp_parser_init_declarator):  Parsing attributes here is no more a
	GNU extension in c++-11.
	(cp_parser_type_specifier_seq): Use
	cp_next_tokens_can_be_attribute_p.
	(cp_parser_direct_declarator): Likewise.  Hang c++11 attributes
	following the declarator to its syntactic construct.  It'll later
	be applied to the proper appertaining entity by grokdeclarator.
	(cp_parser_ptr_operator): Likewise.
	(make_declarator): Initialize cp_declarator::std_attribute.
	(make_pointer_declarator, make_reference_declarator)
	(make_ptrmem_declarator, cp_parser_make_indirect_declarator): Take
	attributes that appertain to the pointer/reference in argument.
	(cp_parser_ptr_operator): Take an out parameter for c++11
	attributes.  Update comments.
	(cp_parser_new_declarator_opt)
	(cp_parser_conversion_declarator_opt): Adjust.
	(cp_parser_declarator): Likewise.  Handle C++11 attributes.
	Rename attributes to gnu_attribute for better legibility.
	(cp_parser_simple_declaration): Update comment.
	(cp_parser_class_specifier_1): Parse GNU attributes specifically
	(cp_parser_enum_specifier): Accept only gnu attributes after the
	specifier.
	(cp_parser_member_declaration): Don't clear attributes -- intended
	for the entity being declared -- too early because check_tag_decl
	needs them.
	(cp_parser_statement): Update comment.  Parse optional c++11
	attributes at the beginning of the relevant kind of statements and
	ignore them, for now, unless when calling
	cp_parser_label_for_labeled_statement.
	(cp_parser_label_for_labeled_statement): Take c++11 attributes
	in parameter.
	* semantics.c (potential_constant_expression_1): Likewise.
	* typeck.c (fundamental_alignment_p, cxx_alignas_expr): New public
	functions.

gcc/testsuite/

	* g++.dg/cpp0x/gen-attrs-1.C: New test.
	* g++.dg/cpp0x/gen-attrs-2.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-2-1.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-3.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-4.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-5.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-6.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-7.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-8.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-9.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-10.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-11.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-12.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-13.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-14.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-15.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-16.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-17.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-18.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-19.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-20.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-21.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-22.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-23.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-24.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-25.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-26.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-27.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-28.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-29.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-30.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-31.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-32.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-33.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-34.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-35.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-36.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-36-1.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-37.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-38.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-39.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-39-1.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-40.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-41.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-42.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-43.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-44.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-45.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-46.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-47.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-47-1.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-48.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-49.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-50.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-51.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-52.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-53.C: Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-10.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-11.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-12.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-13.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-14.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-15.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-16.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-17.2.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-17.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-18.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-19.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-2-1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-2.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-20.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-21.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-22.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-23.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-24.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-25.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-26.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-27.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-28.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-29.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-3.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-30.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-31.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-32.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-34.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-35.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-37.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-38.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-39-1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-39.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-4.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-40.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-41.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-42.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-43.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-44.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-45.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-46.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-47-1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-47.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-48.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-49.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-5.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-50.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-51.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-52.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-53.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-6.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-7.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-8.C
    trunk/gcc/testsuite/g++.dg/cpp0x/gen-attrs-9.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/attribs.c
    trunk/gcc/c-family/ChangeLog
    trunk/gcc/c-family/c-common.c
    trunk/gcc/c-family/c-common.h
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/decl2.c
    trunk/gcc/cp/error.c
    trunk/gcc/cp/parser.c
    trunk/gcc/cp/typeck.c
    trunk/gcc/plugin.h
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree.c
    trunk/gcc/tree.h
Comment 7 dodji@seketeli.org 2012-10-08 12:06:48 UTC
Sorry Michal for getting to your comment this late.

"ethouris at gmail dot com" <gcc-bugzilla@gcc.gnu.org> a écrit:

> Looks nice. Is that a big deal if you also make a standard [[noreturn]]
> attribute simply an alias to [[gnu::noreturn]]?

The patch as it is focused on bringing in the core support for c++11
attributes.  Supporting some attributes in particular is left as a
follow-up to come up later.  An exception to this is that the patch also
supports alignas expressions, but that is just because it was needed to
complete the support of the attributes syntax.

> As far as I know the standard, they should behave exactly the same
> way.

I haven't looked at the details yet, but I think you are correct.

>
> Another thing is that I think this should work, according to the standard:
>
> void quit [[gnu::noreturn]] () { throw 0; }
>
> And it doesn't with this patch.

I think it works with the version of the patch that I just committed.
Or maybe I don't understand what you mean by "doesn't work".

Thanks for caring.
Comment 8 Dodji Seketeli 2012-10-08 12:10:26 UTC
Applied to trunk (4.8).