[c++/57709] Wshadow is too strict / has false positives
diff mbox

Message ID CAESRpQCimLsGrKCW6qh6Z1RD08u_Z-oUrgBYUNHHYa6rehFjgg@mail.gmail.com
State New
Headers show

Commit Message

Manuel López-Ibáñez Aug. 22, 2014, 6:24 p.m. UTC
On 22 August 2014 00:22, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> Hi,
>
>
> On 08/22/2014 12:01 AM, Manuel López-Ibáñez wrote:
>>
>> On 21 August 2014 23:35, Jason Merrill <jason@redhat.com> wrote:
>>>
>>> On 08/21/2014 04:22 PM, Manuel López-Ibáńez wrote:
>>>>
>>>> +                       && TREE_CODE (x) != FUNCTION_DECL
>>>> +                       && !FUNCTION_POINTER_TYPE_P (TREE_TYPE (x))))
>>>
>>>
>>> How about pointer to member function?
>>
>> Maybe like this? BTW, I did not actually want to include the
>> gcc_assert(), it was just a sanity check, thus I deleted it from this
>> patch.
>
> Note by the way, that this patch would introduce the *first* use of
> FUNCTION_POINTER_TYPE_P in the C++ front-end. Are we sure we want to use
> that vs TYPE_PTRFN_P?!? At the moment I'm a bit tired by I seem to remember
> subtleties in this area...

I took all the comments above into consideration and produced this new
version. Since the comments in cp-tree.h did actually confuse me more
than help, I decided to make them more consistent. This could be
committed together, separated or not at all as you wish.

Bootstrapped and regression tested.

gcc/cp/ChangeLog:

2014-08-22  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR c++/57709
    * name-lookup.c (pushdecl_maybe_friend_1): Do not warn if a
    declaration shadows a function declaration, unless the former
    declares a function, pointer to function or pointer to member
    function, because this is a common and valid case in real-world
    code.
    * cp-tree.h (TYPE_PTRFN_P,TYPE_REFFN_P,TYPE_PTRMEMFUNC_P):
    Improve description.

gcc/testsuite/ChangeLog:

2014-08-22  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR c++/57709
    * g++.dg/Wshadow.C: New test.

Comments

Jason Merrill Aug. 22, 2014, 6:36 p.m. UTC | #1
On 08/22/2014 02:24 PM, Manuel López-Ibáñez wrote:
> +			  && DECL_P(member))

Missing space before paren.

OK with that fixed.

Jason

Patch
diff mbox

Index: gcc/testsuite/g++.dg/Wshadow.C
===================================================================
--- gcc/testsuite/g++.dg/Wshadow.C	(revision 0)
+++ gcc/testsuite/g++.dg/Wshadow.C	(revision 0)
@@ -0,0 +1,15 @@ 
+// { dg-do compile }
+// { dg-options "-Wshadow" }
+// PR c++/57709 
+class C {
+  int both_var; // { dg-message "declaration" }
+  void var_and_method(void) {} // { dg-message "declaration" }
+  void m() { 
+    int 
+      both_var,  // { dg-warning "shadows" }
+      var_and_method; 
+  }
+  void m2() { 
+    void (C::*var_and_method)(void); // { dg-warning "shadows" }
+  }
+};
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 214229)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -3556,22 +3556,21 @@  more_aggr_init_expr_args_p (const aggr_i
 #define TYPE_PTROBV_P(NODE)					\
   (TYPE_PTR_P (NODE)						\
    && !(TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE		\
 	|| TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE))
 
-/* Returns true if NODE is a pointer to function.  */
+/* Returns true if NODE is a pointer to function type.  */
 #define TYPE_PTRFN_P(NODE)				\
   (TYPE_PTR_P (NODE)			                \
    && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
 
-/* Returns true if NODE is a reference to function.  */
+/* Returns true if NODE is a reference to function type.  */
 #define TYPE_REFFN_P(NODE)				\
   (TREE_CODE (NODE) == REFERENCE_TYPE			\
    && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
 
-/* Nonzero for _TYPE node means that this type is a pointer to member
-   function type.  */
+/* Returns true if NODE is a pointer to member function type.  */
 #define TYPE_PTRMEMFUNC_P(NODE)		\
   (TREE_CODE (NODE) == RECORD_TYPE	\
    && TYPE_PTRMEMFUNC_FLAG (NODE))
 
 #define TYPE_PTRMEMFUNC_FLAG(NODE) \
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 214229)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -1237,13 +1237,28 @@  pushdecl_maybe_friend_1 (tree x, bool is
 	      else
 		member = NULL_TREE;
 
 	      if (member && !TREE_STATIC (member))
 		{
-		  /* Location of previous decl is not useful in this case.  */
-		  warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
-			   x);
+		  if (BASELINK_P (member))
+		    member = BASELINK_FUNCTIONS (member);
+		  member = OVL_CURRENT (member);
+	
+		  /* Do not warn if a variable shadows a function, unless
+		     the variable is a function or a pointer-to-function.  */
+		  if (TREE_CODE (member) != FUNCTION_DECL
+		      || TREE_CODE (x) == FUNCTION_DECL
+		      || TYPE_PTRFN_P (TREE_TYPE (x))
+		      || TYPE_PTRMEMFUNC_P (TREE_TYPE (x)))
+		    {
+		      if (warning_at (input_location, OPT_Wshadow,
+				      "declaration of %qD shadows a member of %qT",
+				      x, current_nonlambda_class_type ())
+			  && DECL_P(member))
+			inform (DECL_SOURCE_LOCATION (member),
+				"shadowed declaration is here");
+		    }
 		}
 	      else if (oldglobal != NULL_TREE
 		       && (VAR_P (oldglobal)
                            /* If the old decl is a type decl, only warn if the
                               old decl is an explicit typedef or if both the