Deprecate some C++ extensions
https://gcc.gnu.org/ml/gcc-patches/2018-03/msg00995.html * doc/extend.texi (Deprecated Features): Update deprecared flags, mention anon-struct/union members and trailing attributes. cp/ * 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. testsuite/ * 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 From-SVN: r258712
This commit is contained in:
parent
7cd9cf2f0b
commit
f82ece6b59
12 changed files with 100 additions and 56 deletions
|
@ -1,3 +1,8 @@
|
|||
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
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
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.
|
||||
|
|
|
@ -2869,9 +2869,7 @@ warn_hidden (tree t)
|
|||
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
|
||||
|
@ -2885,50 +2883,34 @@ finish_struct_anon_r (tree field, bool complain)
|
|||
|| 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 {
|
||||
|
|
|
@ -19685,12 +19685,21 @@ cp_parser_init_declarator (cp_parser* parser,
|
|||
/* 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)
|
||||
|
|
|
@ -23824,23 +23824,25 @@ some cases that the feature will be dropped in the future. In other
|
|||
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
|
||||
|
@ -23879,6 +23881,14 @@ initializers for static members of const integral types and const
|
|||
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
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
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.
|
||||
|
||||
|
|
|
@ -5,6 +5,6 @@ struct A
|
|||
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" }
|
||||
};
|
||||
|
|
22
gcc/testsuite/g++.dg/ext/deprecate-1.C
Normal file
22
gcc/testsuite/g++.dg/ext/deprecate-1.C
Normal file
|
@ -0,0 +1,22 @@
|
|||
// 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" }
|
||||
};
|
||||
};
|
4
gcc/testsuite/g++.dg/ext/deprecate-2.C
Normal file
4
gcc/testsuite/g++.dg/ext/deprecate-2.C
Normal file
|
@ -0,0 +1,4 @@
|
|||
// 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 }
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
struct X {
|
||||
union {
|
||||
class a; // { dg-warning "can only have" }
|
||||
class a; // { dg-warning "public non-static data member" }
|
||||
};
|
||||
a *b;
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ X::a *a;
|
|||
|
||||
struct Y {
|
||||
union {
|
||||
class a; // { dg-warning "can only have" }
|
||||
class a; // { dg-warning "public non-static data member" }
|
||||
int a;
|
||||
};
|
||||
class a *b;
|
||||
|
@ -23,7 +23,7 @@ struct Z {
|
|||
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;
|
||||
|
|
|
@ -6,7 +6,7 @@ struct X {
|
|||
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" }
|
||||
|
|
|
@ -11,6 +11,6 @@ struct A
|
|||
{
|
||||
union
|
||||
{
|
||||
void bad(); // { dg-error "can only have non-static data" }
|
||||
void bad(); // { dg-error "public non-static data member" }
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue