+2018-03-21 Nathan Sidwell <nathan@acm.org>
+
+ * doc/extend.texi (Deprecated Features): Update deprecared flags,
+ mention anon-struct/union members and trailing attributes.
+
2018-03-21 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/84969
2018-03-21 Nathan Sidwell <nathan@acm.org>
+ * class.c (finish_struct_anon_r): Refactor, deprecate anything
+ other than public non-static data members.
+ * parser.c (cp_parser_init_declarator): Deprecate attributes after
+ parenthesized initializer.
+
PR c++/84836
* name-lookup.c (update_binding): Correct logic for local binding
update.
static void
finish_struct_anon_r (tree field, bool complain)
{
- bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE;
- tree elt = TYPE_FIELDS (TREE_TYPE (field));
- for (; elt; elt = DECL_CHAIN (elt))
+ for (tree elt = TYPE_FIELDS (TREE_TYPE (field)); elt; elt = DECL_CHAIN (elt))
{
/* We're generally only interested in entities the user
declared, but we also find nested classes by noticing
|| TYPE_UNNAMED_P (TREE_TYPE (elt))))
continue;
- if (TREE_CODE (elt) != FIELD_DECL)
+ if (complain
+ && (TREE_CODE (elt) != FIELD_DECL
+ || (TREE_PRIVATE (elt) || TREE_PROTECTED (elt))))
{
/* We already complained about static data members in
finish_static_data_member_decl. */
- if (complain && !VAR_P (elt))
+ if (!VAR_P (elt)
+ && permerror (DECL_SOURCE_LOCATION (elt),
+ TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
+ ? "%q#D invalid; an anonymous union may "
+ "only have public non-static data members"
+ : "%q#D invalid; an anonymous struct may "
+ "only have public non-static data members", elt))
{
- if (is_union)
- permerror (DECL_SOURCE_LOCATION (elt),
- "%q#D invalid; an anonymous union can "
- "only have non-static data members", elt);
- else
- permerror (DECL_SOURCE_LOCATION (elt),
- "%q#D invalid; an anonymous struct can "
- "only have non-static data members", elt);
- }
- continue;
- }
-
- if (complain)
- {
- if (TREE_PRIVATE (elt))
- {
- if (is_union)
- permerror (DECL_SOURCE_LOCATION (elt),
- "private member %q#D in anonymous union", elt);
- else
- permerror (DECL_SOURCE_LOCATION (elt),
- "private member %q#D in anonymous struct", elt);
- }
- else if (TREE_PROTECTED (elt))
- {
- if (is_union)
- permerror (DECL_SOURCE_LOCATION (elt),
- "protected member %q#D in anonymous union", elt);
- else
- permerror (DECL_SOURCE_LOCATION (elt),
- "protected member %q#D in anonymous struct", elt);
+ static bool hint;
+ if (flag_permissive && !hint)
+ {
+ hint = true;
+ inform (DECL_SOURCE_LOCATION (elt),
+ "this flexibility is deprecated and will be removed");
+ }
}
}
TREE_PRIVATE (elt) = TREE_PRIVATE (field);
TREE_PROTECTED (elt) = TREE_PROTECTED (field);
- /* Recurse into the anonymous aggregates to handle correctly
+ /* Recurse into the anonymous aggregates to correctly handle
access control (c++/24926):
class A {
/* The old parser allows attributes to appear after a parenthesized
initializer. Mark Mitchell proposed removing this functionality
on the GCC mailing lists on 2002-08-13. This parser accepts the
- attributes -- but ignores them. */
+ attributes -- but ignores them. Made a permerror in GCC 8. */
if (cp_parser_allow_gnu_extensions_p (parser)
- && initialization_kind == CPP_OPEN_PAREN)
- if (cp_parser_attributes_opt (parser))
- warning (OPT_Wattributes,
- "attributes after parenthesized initializer ignored");
+ && initialization_kind == CPP_OPEN_PAREN
+ && cp_parser_attributes_opt (parser)
+ && permerror (input_location,
+ "attributes after parenthesized initializer ignored"))
+ {
+ static bool hint;
+ if (flag_permissive && !hint)
+ {
+ hint = true;
+ inform (input_location,
+ "this flexibility is deprecated and will be removed");
+ }
+ }
/* And now complain about a non-function implicit template. */
if (bogus_implicit_tmpl && decl != error_mark_node)
cases, the feature might be gone already.
While the list below is not exhaustive, it documents some of the options
-that are now deprecated:
+that are now deprecated or have been removed:
@table @code
@item -fexternal-templates
@itemx -falt-external-templates
-These are two of the many ways for G++ to implement template
-instantiation. @xref{Template Instantiation}. The C++ standard clearly
-defines how template definitions have to be organized across
-implementation units. G++ has an implicit instantiation mechanism that
-should work just fine for standard-conforming code.
+These are two options provided alternative methods of template
+instantiation. @xref{Template Instantiation}. The options have been removed.
@item -fstrict-prototype
@itemx -fno-strict-prototype
Previously it was possible to use an empty prototype parameter list to
indicate an unspecified number of parameters (like C), rather than no
-parameters, as C++ demands. This feature has been removed, except where
-it is required for backwards compatibility. @xref{Backwards Compatibility}.
+parameters, as C++ demands. This feature has been removed.
+
+@item -fno-for-scope
+@item -ffriend-injection
+These two options provide compatibility with pre-standard C++.
+@xref{Backwards Compatibility}.
+
@end table
G++ allows a virtual function returning @samp{void *} to be overridden
enumeration types so this extension has been deprecated and will be removed
from a future version.
+G++ allows attributes to follow a parenthesized direct initializer,
+e.g.@: @samp{ int f (0) __attribute__ ((something)); } This extension
+has been ignored since G++ 3.3 and is deprecated.
+
+G++ allows anonymous structs and unions to have members that are not
+public non-static data members (i.e.@: fields). These extensions are
+deprecated.
+
@node Backwards Compatibility
@section Backwards Compatibility
@cindex Backwards Compatibility
2018-03-21 Nathan Sidwell <nathan@acm.org>
+ * g++.dg/ext/anon-struct6.C: Adjust.
+ * g++.dg/ext/deprecate-1.C: New.
+ * g++.dg/ext/deprecate-2.C: New.
+ * g++.dg/lookup/pr84602.C: Adjust.
+ * g++.dg/lookup/pr84962.C: Adjust.
+ * g++.old-deja/g++.other/anon4.C
+
PR c++/84836
* g++.dg/lookup/pr84836.C: New.
struct
{
struct { static int i; }; // { dg-error "prohibits anonymous structs|non-static data members|unnamed class" }
- void foo() { i; } // { dg-error "can only have non-static data" }
+ void foo() { i; } // { dg-error "public non-static data" }
}; // { dg-error "prohibits anonymous structs" }
};
--- /dev/null
+// be pickier about anon-union and structs
+// { dg-options "-fpermissive" }
+
+struct X
+{
+ struct
+ {
+ int f1 (); // { dg-warning "public non-static data" }
+ // { dg-message "will be removed" "" { target *-*-* } .-1 }
+ typedef int t1; // { dg-warning "public non-static data" }
+ private:
+ int m1; // { dg-warning "public non-static data" }
+ };
+
+ union
+ {
+ int f2 (); // { dg-warning "public non-static data" }
+ typedef int t2; // { dg-warning "public non-static data" }
+ protected:
+ int m2; // { dg-warning "public non-static data" }
+ };
+};
--- /dev/null
+// Stop accepting attributes after a parenthesized initializer
+// { dg-options "-fpermissive" }
+int i (0) __attribute__ ((ignored)); // { dg-warning "attributes" }
+// { dg-message "will be removed" "" { target *-*-* } .-1 }
struct X {
union {
- class a; // { dg-warning "can only have" }
+ class a; // { dg-warning "public non-static data member" }
};
a *b;
};
struct Y {
union {
- class a; // { dg-warning "can only have" }
+ class a; // { dg-warning "public non-static data member" }
int a;
};
class a *b;
union {
// Force MEMBER_VEC creation
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
- class a; // { dg-warning "can only have" }
+ class a; // { dg-warning "public non-static data member" }
int a;
};
class a *b;
struct
{
template <typename> int a ();
- // { dg-error "can only have" "" { target *-*-* } .-1 }
+ // { dg-error "public non-static data member" "" { target *-*-* } .-1 }
};
int : a; // { dg-error "non-integral" }
{
union
{
- void bad(); // { dg-error "can only have non-static data" }
+ void bad(); // { dg-error "public non-static data member" }
};
};