c++: Add -Wno-changes-meaning
In recent years this error has been coming up more because other compilers don't diagnose it as consistently. So let's add a flag for it, and be more lenient about cases that aren't likely to cause bugs. gcc/ChangeLog: * doc/invoke.texi: Document -Wno-changes-meaning. gcc/c-family/ChangeLog: * c.opt: Add -Wno-changes-meaning. gcc/cp/ChangeLog: * class.cc (note_name_declared_in_class): Change from permerror to -Wchanges-meaning pedwarn, forcing -pedantic-errors for most cases. gcc/testsuite/ChangeLog: * g++.dg/warn/changes-meaning2.C: New test. * g++.dg/warn/changes-meaning3.C: New test.
This commit is contained in:
parent
d03ae4be2c
commit
e2f939d30f
5 changed files with 64 additions and 4 deletions
|
@ -494,6 +494,10 @@ Wcatch-value=
|
|||
C++ ObjC++ Var(warn_catch_value) Warning Joined RejectNegative UInteger LangEnabledBy(C++ ObjC++,Wall, 1, 0) IntegerRange(0, 3)
|
||||
Warn about catch handlers of non-reference type.
|
||||
|
||||
Wchanges-meaning
|
||||
C++ ObjC++ Var(warn_changes_meaning) Warning Init(1)
|
||||
Complain about a name being declared as a class member after a previous use of the same name.
|
||||
|
||||
Wchar-subscripts
|
||||
C ObjC C++ ObjC++ Var(warn_char_subscripts) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
|
||||
Warn about subscripts whose type is \"char\".
|
||||
|
|
|
@ -9016,7 +9016,7 @@ note_name_declared_in_class (tree name, tree decl)
|
|||
return;
|
||||
/* The C language allows members to be declared with a type of the same
|
||||
name, and the C++ standard says this diagnostic is not required. So
|
||||
allow it in extern "C" blocks unless predantic is specified.
|
||||
allow it in extern "C" blocks unless pedantic is specified.
|
||||
Allow it in all cases if -ms-extensions is specified. */
|
||||
if ((!pedantic && current_lang_name == lang_name_c)
|
||||
|| flag_ms_extensions)
|
||||
|
@ -9032,9 +9032,19 @@ note_name_declared_in_class (tree name, tree decl)
|
|||
A name N used in a class S shall refer to the same declaration
|
||||
in its context and when re-evaluated in the completed scope of
|
||||
S. */
|
||||
if (permerror (location_of (decl),
|
||||
"declaration of %q#D changes meaning of %qD",
|
||||
decl, OVL_NAME (decl)))
|
||||
auto ov = make_temp_override (global_dc->pedantic_errors);
|
||||
if (TREE_CODE (decl) == TYPE_DECL
|
||||
&& TREE_CODE (olddecl) == TYPE_DECL
|
||||
&& same_type_p (TREE_TYPE (decl), TREE_TYPE (olddecl)))
|
||||
/* Different declaration, but same meaning; just warn. */;
|
||||
else if (flag_permissive)
|
||||
/* Let -fpermissive make it a warning like past versions. */;
|
||||
else
|
||||
/* Make it an error. */
|
||||
global_dc->pedantic_errors = 1;
|
||||
if (pedwarn (location_of (decl), OPT_Wchanges_meaning,
|
||||
"declaration of %q#D changes meaning of %qD",
|
||||
decl, OVL_NAME (decl)))
|
||||
{
|
||||
inform (loc, "used here to mean %q#D", olddecl);
|
||||
inform (location_of (olddecl), "declared here" );
|
||||
|
|
|
@ -6287,6 +6287,23 @@ union U @{
|
|||
|
||||
@end itemize
|
||||
|
||||
@item -Wno-changes-meaning @r{(C++ and Objective-C++ only)}
|
||||
C++ requires that unqualified uses of a name within a class have the
|
||||
same meaning in the complete scope of the class, so declaring the name
|
||||
after using it is ill-formed:
|
||||
@smallexample
|
||||
struct A;
|
||||
struct B1 @{ A a; typedef A A; @}; // warning, 'A' changes meaning
|
||||
struct B2 @{ A a; struct A @{ @}; @}; // error, 'A' changes meaning
|
||||
@end smallexample
|
||||
By default, the B1 case is only a warning because the two declarations
|
||||
have the same type, while the B2 case is an error. Both diagnostics
|
||||
can be disabled with @option{-Wno-changes-meaning}. Alternately, the
|
||||
error case can be reduced to a warning with
|
||||
@option{-Wno-error=changes-meaning} or @option{-fpermissive}.
|
||||
|
||||
Both diagnostics are also suppressed by @option{-fms-extensions}.
|
||||
|
||||
@item -Wchar-subscripts
|
||||
@opindex Wchar-subscripts
|
||||
@opindex Wno-char-subscripts
|
||||
|
|
16
gcc/testsuite/g++.dg/warn/changes-meaning2.C
Normal file
16
gcc/testsuite/g++.dg/warn/changes-meaning2.C
Normal file
|
@ -0,0 +1,16 @@
|
|||
// It's an error to redeclare a name after using it in the class, but be
|
||||
// lenient if it has the same meaning.
|
||||
|
||||
// { dg-options "" }
|
||||
|
||||
struct Lock { };
|
||||
struct Traits
|
||||
{
|
||||
Lock lock;
|
||||
typedef ::Lock Lock; // { dg-warning -Wchanges-meaning }
|
||||
};
|
||||
struct Traits2
|
||||
{
|
||||
Lock lock;
|
||||
typedef int Lock; // { dg-error -Wchanges-meaning }
|
||||
};
|
13
gcc/testsuite/g++.dg/warn/changes-meaning3.C
Normal file
13
gcc/testsuite/g++.dg/warn/changes-meaning3.C
Normal file
|
@ -0,0 +1,13 @@
|
|||
// { dg-additional-options "-Wno-changes-meaning" }
|
||||
|
||||
struct Lock { };
|
||||
struct Traits
|
||||
{
|
||||
Lock lock;
|
||||
typedef ::Lock Lock;
|
||||
};
|
||||
struct Traits2
|
||||
{
|
||||
Lock lock;
|
||||
typedef int Lock;
|
||||
};
|
Loading…
Add table
Reference in a new issue