re PR c++/92024 (crash in check_local_shadow)
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Wed, 30 Oct 2019 20:29:21 +0000 (20:29 +0000)
committerBernd Edlinger <edlinger@gcc.gnu.org>
Wed, 30 Oct 2019 20:29:21 +0000 (20:29 +0000)
2019-10-30  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        * doc/invoke.texi (-Wshadow, -Wshadow=global
        -Wshadow=local, -Wshadow=compatible-local): Update documentation.

cp:
2019-10-30  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR c++/92024
        * name-lookup.c (check_local_shadow): Shadowing TYPE_DECLs
        is always a -Wshadow=compatible-local warning, unless
        -Wshadow is used.

testsuite:
2019-10-30  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR c++/92024
        * g++.dg/parse/crash70.C: New test.
        * c-c++-common/Wshadow-1.c: New test.

From-SVN: r277643

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wshadow-1.c [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/crash70.C [new file with mode: 0644]

index d1110fced48f99de1d024c6200fa25f6ac4ac858..d1a83f50d1281322ea050149fa77039cf9440bf0 100644 (file)
@@ -1,3 +1,8 @@
+2019-10-30  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       * doc/invoke.texi (-Wshadow, -Wshadow=global
+       -Wshadow=local, -Wshadow=compatible-local): Update documentation.
+
 2019-10-30  Tobias Burnus  <tobias@codesourcery.com>
 
        * gimplify.c (gimplify_scan_omp_clauses): Remove FE-generated
index 6808527d0f5c85f9cbd9a7f9e4fbc1a37a530f07..402d321d0e7488785d41c481b39611e031b9b4b6 100644 (file)
@@ -1,3 +1,10 @@
+2019-10-30  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       PR c++/92024
+       * name-lookup.c (check_local_shadow): Shadowing TYPE_DECLs
+       is always a -Wshadow=compatible-local warning, unless
+       -Wshadow is used.
+
 2019-10-30  Jason Merrill  <jason@redhat.com>
 
        * cxx-pretty-print.c (get_fold_operator): Use OVL_OP_INFO.
index 9352ce5da0b00f1a190b5cf7b8117247d2d0944b..9ef1ed9c8e36cfecbfed0c76305b092ece3b9bed 100644 (file)
@@ -2750,29 +2750,31 @@ check_local_shadow (tree decl)
         parameter, more than often they would use the variable
         thinking (mistakenly) it's still the parameter. It would be
         rare that users would use the variable in the place that
-        expects the parameter but thinking it's a new decl.  */
+        expects the parameter but thinking it's a new decl.
+        If either object is a TYPE_DECL, '-Wshadow=compatible-local'
+        warns regardless of whether one of the types involved
+        is a subclass of the other, since that is never okay.  */
 
       enum opt_code warning_code;
       if (warn_shadow)
        warning_code = OPT_Wshadow;
-      else if (warn_shadow_local)
-       warning_code = OPT_Wshadow_local;
-      else if (warn_shadow_compatible_local
-              && (same_type_p (TREE_TYPE (old), TREE_TYPE (decl))
-                  || (!dependent_type_p (TREE_TYPE (decl))
-                      && !dependent_type_p (TREE_TYPE (old))
-                      /* If the new decl uses auto, we don't yet know
-                         its type (the old type cannot be using auto
-                         at this point, without also being
-                         dependent).  This is an indication we're
-                         (now) doing the shadow checking too
-                         early.  */
-                      && !type_uses_auto (TREE_TYPE (decl))
-                      && can_convert (TREE_TYPE (old), TREE_TYPE (decl),
-                                      tf_none))))
+      else if (same_type_p (TREE_TYPE (old), TREE_TYPE (decl))
+              || TREE_CODE (decl) == TYPE_DECL
+              || TREE_CODE (old) == TYPE_DECL
+              || (!dependent_type_p (TREE_TYPE (decl))
+                  && !dependent_type_p (TREE_TYPE (old))
+                  /* If the new decl uses auto, we don't yet know
+                     its type (the old type cannot be using auto
+                     at this point, without also being
+                     dependent).  This is an indication we're
+                     (now) doing the shadow checking too
+                     early.  */
+                  && !type_uses_auto (TREE_TYPE (decl))
+                  && can_convert (TREE_TYPE (old), TREE_TYPE (decl),
+                                  tf_none)))
        warning_code = OPT_Wshadow_compatible_local;
       else
-       return;
+       warning_code = OPT_Wshadow_local;
 
       const char *msg;
       if (TREE_CODE (old) == PARM_DECL)
index 1407d019d1404ebbdb9630d6f541eab2e7a1bd01..d1eb317f43cd31156c80ef7dd910024c50f33deb 100644 (file)
@@ -342,7 +342,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-pragmas  -Wno-prio-ctor-dtor  -Wredundant-decls @gol
 -Wrestrict  -Wno-return-local-addr @gol
 -Wreturn-type  -Wsequence-point  -Wshadow  -Wno-shadow-ivar @gol
--Wshadow=global,  -Wshadow=local,  -Wshadow=compatible-local @gol
+-Wshadow=global  -Wshadow=local  -Wshadow=compatible-local @gol
 -Wshift-overflow  -Wshift-overflow=@var{n} @gol
 -Wshift-count-negative  -Wshift-count-overflow  -Wshift-negative-value @gol
 -Wsign-compare  -Wsign-conversion  -Wfloat-conversion @gol
@@ -6309,7 +6309,7 @@ can be used to suppress such a warning.
 @opindex Wno-discarded-array-qualifiers
 @opindex Wdiscarded-array-qualifiers
 Do not warn if type qualifiers on arrays which are pointer targets
-are being discarded. Typically, the compiler warns if a
+are being discarded.  Typically, the compiler warns if a
 @code{const int (*)[]} variable is passed to a function that
 takes a @code{int (*)[]} parameter.  This option can be used to
 suppress such a warning.
@@ -6508,9 +6508,13 @@ allowed in GCC@.  It is not supported by ISO C90.  @xref{Mixed Declarations}.
 @opindex Wno-shadow
 Warn whenever a local variable or type declaration shadows another
 variable, parameter, type, class member (in C++), or instance variable
-(in Objective-C) or whenever a built-in function is shadowed. Note
+(in Objective-C) or whenever a built-in function is shadowed.  Note
 that in C++, the compiler warns if a local variable shadows an
 explicit typedef, but not if it shadows a struct/class/enum.
+If this warning is enabled, it includes also all instances of
+local shadowing.  This means that @option{-Wno-shadow=local}
+and @option{-Wno-shadow=compatible-local} are ignored when
+@option{-Wshadow} is used.
 Same as @option{-Wshadow=global}.
 
 @item -Wno-shadow-ivar @r{(Objective-C only)}
@@ -6521,20 +6525,19 @@ Objective-C method.
 
 @item -Wshadow=global
 @opindex Wshadow=global
-The default for @option{-Wshadow}. Warns for any (global) shadowing.
-This warning is enabled by @option{-Wshadow=global}.
+Warn for any shadowing.
+Same as @option{-Wshadow}.
 
 @item -Wshadow=local
 @opindex Wshadow=local
 Warn when a local variable shadows another local variable or parameter.
-This warning is enabled by @option{-Wshadow=local}.
 
 @item -Wshadow=compatible-local
 @opindex Wshadow=compatible-local
 Warn when a local variable shadows another local variable or parameter
-whose type is compatible with that of the shadowing variable. In C++,
+whose type is compatible with that of the shadowing variable.  In C++,
 type compatibility here means the type of the shadowing variable can be
-converted to that of the shadowed variable. The creation of this flag
+converted to that of the shadowed variable.  The creation of this flag
 (in addition to @option{-Wshadow=local}) is based on the idea that when
 a local variable shadows another one of incompatible type, it is most
 likely intentional, not a bug or typo, as shown in the following example:
@@ -6553,16 +6556,15 @@ for (SomeIterator i = SomeObj.begin(); i != SomeObj.end(); ++i)
 @end smallexample
 
 Since the two variable @code{i} in the example above have incompatible types,
-enabling only @option{-Wshadow=compatible-local} will not emit a warning.
+enabling only @option{-Wshadow=compatible-local} does not emit a warning.
 Because their types are incompatible, if a programmer accidentally uses one
-in place of the other, type checking will catch that and emit an error or
-warning. So not warning (about shadowing) in this case will not lead to
-undetected bugs. Use of this flag instead of @option{-Wshadow=local} can
+in place of the other, type checking is expected to catch that and emit an
+error or warning.  Use of this flag instead of @option{-Wshadow=local} can
 possibly reduce the number of warnings triggered by intentional shadowing.
-Note that this does also mean that shadowing @code{const char *i} by
-@code{char *i} will not emit a warning.
+Note that this also means that shadowing @code{const char *i} by
+@code{char *i} does not emit a warning.
 
-This warning is enabled by @option{-Wshadow=compatible-local}.
+This warning is also enabled by @option{-Wshadow=local}.
 
 @item -Wlarger-than=@var{byte-size}
 @opindex Wlarger-than=
index c2d63003f9bf425154a76ac016a9993b0e63c3c3..67de104fb1d43ee86b48846268eb3cb7c58526e3 100644 (file)
@@ -1,3 +1,9 @@
+2019-10-30  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       PR c++/92024
+       * g++.dg/parse/crash70.C: New test.
+       * c-c++-common/Wshadow-1.c: New test.
+
 2019-10-30  Tobias Burnus  <tobias@codesourcery.com>
 
        PR fortran/92208
diff --git a/gcc/testsuite/c-c++-common/Wshadow-1.c b/gcc/testsuite/c-c++-common/Wshadow-1.c
new file mode 100644 (file)
index 0000000..4d1edf0
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do-compile } */
+/* { dg-additional-options "-Wshadow=local -Wno-shadow=compatible-local" } */
+int c;
+void foo(int *c, int *d)   /* { dg-bogus   "Wshadow" } */
+{
+  int *e = d;
+  {
+    int d = 0;             /* { dg-warning "Wshadow=local" } */
+  }
+  {
+    int *e = 0;            /* { dg-bogus   "Wshadow=compatible-local" } */
+  }
+}
+#pragma GCC diagnostic warning "-Wshadow"
+void bar(int *c, int *d)   /* { dg-warning "Wshadow" } */
+{
+  int *e = d;
+  {
+    int d = 0;             /* { dg-warning "Wshadow" } */
+  }
+  {
+    int *e = 0;            /* { dg-warning "Wshadow" } */
+  }
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash70.C b/gcc/testsuite/g++.dg/parse/crash70.C
new file mode 100644 (file)
index 0000000..16c0785
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/92024
+// { dg-additional-options "-Wshadow=compatible-local" }
+
+template<typename>
+struct S {
+  S () {
+    struct c;
+      {
+       struct c {}; // { dg-warning "Wshadow=compatible-local" }
+      }
+  }
+};
+
+S<int> s;