[pushed] c++: Add -Wno-changes-meaning
Checks
Commit Message
Tested x86_64-pc-linux-gnu, applying to trunk.
This isn't exactly a regression fix, but it is in response to new build
failures and safe.
-- 8< --
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.
---
gcc/doc/invoke.texi | 17 +++++++++++++++++
gcc/c-family/c.opt | 4 ++++
gcc/cp/class.cc | 18 ++++++++++++++----
gcc/testsuite/g++.dg/warn/changes-meaning2.C | 16 ++++++++++++++++
gcc/testsuite/g++.dg/warn/changes-meaning3.C | 13 +++++++++++++
5 files changed, 64 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/warn/changes-meaning2.C
create mode 100644 gcc/testsuite/g++.dg/warn/changes-meaning3.C
base-commit: b533084d756a2696a3eb6521810e0a0b2182a8e8
@@ -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
@@ -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" );
new file mode 100644
@@ -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 }
+};
new file mode 100644
@@ -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;
+};