diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 9523f73d9a308ff9cdbccd0e2814e6ab0d03810a..e4021835ed58034334dc5884db989d481a6fe3c9 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -29239,8 +29239,7 @@ cp_parser_std_attribute (cp_parser *parser, tree attr_ns) /* Warn if the attribute ATTRIBUTE appears more than once in the attribute-list ATTRIBUTES. This used to be enforced for certain - attributes, but the restriction was removed in P2156. Note that - carries_dependency ([dcl.attr.depend]) isn't implemented yet in GCC. + attributes, but the restriction was removed in P2156. LOC is the location of ATTRIBUTE. Returns true if ATTRIBUTE was not found in ATTRIBUTES. */ @@ -29249,7 +29248,7 @@ cp_parser_check_std_attribute (location_t loc, tree attributes, tree attribute) { static auto alist = { "noreturn", "deprecated", "nodiscard", "maybe_unused", "likely", "unlikely", "fallthrough", - "no_unique_address" }; + "no_unique_address", "carries_dependency" }; if (attributes) for (const auto &a : alist) if (is_attribute_p (a, get_attribute_name (attribute)) diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index c30bbeb0839ec0f45392cb43bac87a206d973b14..954c6de2fcd396483b4d0f7160e04a3e0de79d10 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -4923,6 +4923,32 @@ structural_type_p (tree t, bool explain) return true; } +/* Partially handle the C++11 [[carries_dependency]] attribute. + Just emit a different diagnostics when it is used on something the + spec doesn't allow vs. where it allows and we just choose to ignore + it. */ + +static tree +handle_carries_dependency_attribute (tree *node, tree name, + tree ARG_UNUSED (args), + int ARG_UNUSED (flags), + bool *no_add_attrs) +{ + if (TREE_CODE (*node) != FUNCTION_DECL + && TREE_CODE (*node) != PARM_DECL) + { + warning (OPT_Wattributes, "%qE attribute can only be applied to " + "functions or parameters", name); + *no_add_attrs = true; + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + return NULL_TREE; +} + /* Handle the C++17 [[nodiscard]] attribute, which is similar to the GNU warn_unused_result attribute. */ @@ -5036,6 +5062,8 @@ const struct attribute_spec std_attribute_table[] = handle_likeliness_attribute, attr_cold_hot_exclusions }, { "noreturn", 0, 0, true, false, false, false, handle_noreturn_attribute, attr_noreturn_exclusions }, + { "carries_dependency", 0, 0, true, false, false, false, + handle_carries_dependency_attribute, NULL }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; diff --git a/gcc/testsuite/g++.dg/cpp0x/attr-carries_dependency1.C b/gcc/testsuite/g++.dg/cpp0x/attr-carries_dependency1.C new file mode 100644 index 0000000000000000000000000000000000000000..bf0f9cb3645fc4711e730c2d66069e0f3f5ca2c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/attr-carries_dependency1.C @@ -0,0 +1,17 @@ +// { dg-do compile { target c++11 } } + +[[carries_dependency]] int *f1 (); // { dg-warning "attribute ignored" } +int f2 (int *x [[carries_dependency]]); // { dg-warning "attribute ignored" } +[[carries_dependency]] int f3 (); // { dg-warning "attribute ignored" } +int f4 (int x [[carries_dependency]]); // { dg-warning "attribute ignored" } +[[carries_dependency(1)]] int f5 (); // { dg-error "'carries_dependency' attribute does not take any arguments" } +[[carries_dependency]] int v; // { dg-warning "'carries_dependency' attribute can only be applied to functions or parameters" } +[[carries_dependency]]; // { dg-warning "attribute ignored" } +void +f6 () +{ + [[carries_dependency]]; // { dg-warning "attributes at the beginning of statement are ignored" } +} +#if __has_cpp_attribute(carries_dependency) +#error carries_dependency attribute is not actually implemented +#endif