LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 16088 - Wshadow results in (correct, but unhelpful) warning with constructor parameter having the name of data member
Summary: Wshadow results in (correct, but unhelpful) warning with constructor paramete...
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: C++ (show other bugs)
Version: trunk
Hardware: All All
: P normal
Assignee: Reid Kleckner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-05-21 07:54 PDT by jonathan.sauer
Modified: 2017-01-20 07:26 PST (History)
10 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jonathan.sauer 2013-05-21 07:54:40 PDT
The following program results in a warning about the constructor parameter <i> shadowing Foo's data member <i> when compiled with clang r181693:

struct Foo {
    int i;
    
    Foo(int i) : i(i) {}
};


This results in:

% clang++ -v -Wshadow -c clang.cpp
clang version 3.4 (trunk 181693)
[...]
clang.cpp:4:13: warning: declaration shadows a field of 'Foo' [-Wshadow]
    Foo(int i) : i(i) {}
            ^
clang.cpp:2:9: note: previous declaration is here
    int i;
        ^
1 warning generated.


While the warning is correct, it is IMHO a common idiom to name the constructor's parameters identical to the class's data member they initialize. In that case the warning is unhelpful.

Of course there are workarounds:

1. Rename the parameters, e.g. add a trailing underscore.

2. Use C++11's uniform initialization syntax where possible.

That is why I'm not sure if clang's current behavior should be changed (one possible change would be to only warn if the parameter is used in the constructor's body instead of only in the member initialization list).
Comment 1 Reid Kleckner 2014-10-21 16:54:57 PDT
This has come up multiple times in LLDB coding style discussion and on chromium-dev.

It'd also be nice if we could keep warning when there's ambiguity in the way that the ctor parameter is used, though, as in:

struct Foo {
  int i;
  Foo(int i) : i(i) { i++; } // modifies the parameter, not member
};
Comment 2 Reid Kleckner 2014-10-21 16:57:04 PDT
*** Bug 21110 has been marked as a duplicate of this bug. ***
Comment 3 Trass3r 2016-02-23 10:11:46 PST
Yes this generates hundreds of useless warnings!
It should only warn if the name is used inside the constructor body.
Comment 4 Hans Wennborg 2016-02-23 10:53:27 PST
+rtrieu in case he's interested in this one
Comment 5 Trass3r 2016-02-24 05:33:55 PST
Function of interest is Sema::CheckShadow.

Something along the lines of:

Index: SemaDecl.cpp
===================================================================
--- SemaDecl.cpp	(revision 260978)
+++ SemaDecl.cpp	(working copy)
@@ -6344,10 +6344,18 @@
     return;
 
   // Fields are not shadowed by variables in C++ static methods.
-  if (isa<FieldDecl>(ShadowedDecl))
+  if (isa<FieldDecl>(ShadowedDecl)) {
     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewDC))
       if (MD->isStatic())
         return;
+    if (auto CD = dyn_cast<CXXConstructorDecl>(NewDC)) {
+      if (dyn_cast<ParmVarDecl>(D)) {
+        return;
+      }
+    }
+  }
 
   if (VarDecl *shadowedVar = dyn_cast<VarDecl>(ShadowedDecl))
     if (shadowedVar->isExternC()) {
Comment 6 Reid Kleckner 2016-03-18 12:34:34 PDT
Here's something that kind of works but needs more extensive testing:
http://reviews.llvm.org/D18271
Comment 7 Reid Kleckner 2016-04-28 19:38:48 PDT
r267957. If you want the old behavior, use -Wshadow-all.
Comment 8 Trass3r 2017-01-20 07:26:37 PST
Much better now, thanks!

Though it still warns about a similar pattern as some people don't use field name prefixes:

void setFoo(Foo* f) { this->f = f; }
int doBoo(int a, int f) { return a + f; }