[PATCH] D31069: Don't warn about an unreachable fallthrough annotation in a template function

2017-03-16 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi updated this revision to Diff 92104.
ahmedasadi added a comment.

Added a test case.


https://reviews.llvm.org/D31069

Files:
  lib/Sema/AnalysisBasedWarnings.cpp
  test/SemaCXX/P30636.cpp


Index: test/SemaCXX/P30636.cpp
===
--- test/SemaCXX/P30636.cpp
+++ test/SemaCXX/P30636.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s
+// expected-no-diagnostics
+
+template
+int fallthrough_template(int i)
+{
+  switch (i) {
+case 1:
+  if (param)
+return 3;
+  [[clang::fallthrough]]; // no warning here, for an unreachable 
annotation (in the fallthrough_template case) in a template function
+case 2:
+  return 4;
+default:
+  return 5;
+  }
+}
+  
+template int fallthrough_template(int);
+
Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -972,7 +972,7 @@
   }
 }
 
-bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) {
+bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt, bool 
isTemplateInstantiation) {
   assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
 
   int UnannotatedCnt = 0;
@@ -1002,8 +1002,12 @@
ElemIt != ElemEnd; ++ElemIt) {
 if (Optional CS = ElemIt->getAs()) {
   if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) 
{
-S.Diag(AS->getLocStart(),
-   diag::warn_fallthrough_attr_unreachable);
+// Don't issue a warning for an unreachable fallthrough
+// attribute in template instantiations as it may not be
+// unreachable in all instantiations of the template
+if (!isTemplateInstantiation)
+S.Diag(AS->getLocStart(),
+   diag::warn_fallthrough_attr_unreachable);
 markFallthroughVisited(AS);
 ++AnnotatedCnt;
 break;
@@ -1164,7 +1168,10 @@
 
 int AnnotatedCnt;
 
-if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt))
+bool isTemplateInstantiation = false;
+if (const FunctionDecl *Function = dyn_cast(AC.getDecl()))
+isTemplateInstantiation = Function->isTemplateInstantiation();
+if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt, 
isTemplateInstantiation))
   continue;
 
 S.Diag(Label->getLocStart(),


Index: test/SemaCXX/P30636.cpp
===
--- test/SemaCXX/P30636.cpp
+++ test/SemaCXX/P30636.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s
+// expected-no-diagnostics
+
+template
+int fallthrough_template(int i)
+{
+  switch (i) {
+case 1:
+  if (param)
+return 3;
+  [[clang::fallthrough]]; // no warning here, for an unreachable annotation (in the fallthrough_template case) in a template function
+case 2:
+  return 4;
+default:
+  return 5;
+  }
+}
+  
+template int fallthrough_template(int);
+
Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -972,7 +972,7 @@
   }
 }
 
-bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) {
+bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt, bool isTemplateInstantiation) {
   assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
 
   int UnannotatedCnt = 0;
@@ -1002,8 +1002,12 @@
ElemIt != ElemEnd; ++ElemIt) {
 if (Optional CS = ElemIt->getAs()) {
   if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {
-S.Diag(AS->getLocStart(),
-   diag::warn_fallthrough_attr_unreachable);
+// Don't issue a warning for an unreachable fallthrough
+// attribute in template instantiations as it may not be
+// unreachable in all instantiations of the template
+if (!isTemplateInstantiation)
+S.Diag(AS->getLocStart(),
+   diag::warn_fallthrough_attr_unreachable);
 markFallthroughVisited(AS);
 ++AnnotatedCnt;
 break;
@@ -1164,7 +1168,10 @@
 
 int AnnotatedCnt;
 
-if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt))
+bool isTemplateInstantiation = false;
+if (const FunctionDecl *Function = dyn_cast(AC.getDecl()))
+isTemplateInstantiation = Function->isTemplateInstantiation();
+if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt, isTemplateInstantiation))
   continue;
 

[PATCH] D31069: Don't warn about an unreachable fallthrough annotation in a template function

2017-03-17 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi added a comment.

Thanks for reviewing. Yes, I need someone to commit for me.


https://reviews.llvm.org/D31069



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31235: Enhance -Wshadow to warn when shadowing typedefs or type aliases

2017-03-22 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi created this revision.

Enhance -Wshadow to emit a warning when typedefs or type aliases are shadowed, 
or when it shadows a variable.

Bug:

https://bugs.llvm.org//show_bug.cgi?id=28676


Repository:
  rL LLVM

https://reviews.llvm.org/D31235

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/warn-shadow.cpp

Index: test/SemaCXX/warn-shadow.cpp
===
--- test/SemaCXX/warn-shadow.cpp
+++ test/SemaCXX/warn-shadow.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow-all %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -Wshadow-all %s
 
 namespace {
   int i; // expected-note {{previous declaration is here}}
@@ -7,14 +7,21 @@
 namespace one {
 namespace two {
   int j; // expected-note {{previous declaration is here}}
+  typedef int jj; // expected-note 3 {{previous declaration is here}}
+  using jjj=int; // expected-note 3 {{previous declaration is here}}
 }
 }
 
 namespace xx {
   int m;
+  typedef int mm;
+  using mmm=int;
+
 }
 namespace yy {
   int m;
+  typedef char mm;
+  using mmm=char;
 }
 
 using namespace one::two;
@@ -25,14 +32,19 @@
   int i; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
   int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
   int m;
+  int mm;
+  int mmm;
 }
 
 class A {
-  static int data; // expected-note {{previous declaration}}
-  // expected-note@+1 {{previous declaration}}
+  static int data; // expected-note 3 {{previous declaration}}
+  // expected-note@+1 3 {{previous declaration}}
   int field;
   int f1, f2, f3, f4; // expected-note 8 {{previous declaration is here}}
 
+  typedef int a1; // expected-note 3 {{previous declaration}}
+  using a2=int; // expected-note 3 {{previous declaration}}
+
   // The initialization is safe, but the modifications are not.
   A(int f1, int f2, int f3, int f4) // expected-note-re 4 {{variable 'f{{[0-4]}}' is declared here}}
 	  : f1(f1) {
@@ -50,7 +62,29 @@
   void test() {
 char *field; // expected-warning {{declaration shadows a field of 'A'}}
 char *data; // expected-warning {{declaration shadows a static data member of 'A'}}
+char *a1; // expected-warning {{declaration shadows a typedef in 'A'}}
+char *a2; // expected-warning {{declaration shadows a type alias in 'A'}}
+char *jj; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+char *jjj; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
   }
+
+  void test2() {
+typedef char field; // expected-warning {{declaration shadows a field of 'A'}}
+typedef char data; // expected-warning {{declaration shadows a static data member of 'A'}}
+typedef char a1; // expected-warning {{declaration shadows a typedef in 'A'}}
+typedef char a2; // expected-warning {{declaration shadows a type alias in 'A'}}
+typedef char jj; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+typedef char jjj; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
+  }
+
+  void test3() {
+using field=char; // expected-warning {{declaration shadows a field of 'A'}}
+using data=char; // expected-warning {{declaration shadows a static data member of 'A'}}
+using a1=char; // expected-warning {{declaration shadows a typedef in 'A'}}
+using a2=char; // expected-warning {{declaration shadows a type alias in 'A'}}
+using jj=char; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+using jjj=char; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
+  }
 };
 
 // TODO: this should warn, 
@@ -63,6 +97,8 @@
 namespace rdar8900456 {
 struct Foo {
   static void Baz();
+  static void Baz1();
+  static void Baz2();
 private:
   int Bar;
 };
@@ -70,8 +106,16 @@
 void Foo::Baz() {
   double Bar = 12; // Don't warn.
 }
+
+void Foo::Baz1() {
+  typedef int Bar; // Don't warn.
 }
 
+void Foo::Baz2() {
+  using Bar=int; // Don't warn.
+}
+}
+
 // http://llvm.org/PR9160
 namespace PR9160 {
 struct V {
@@ -87,7 +131,9 @@
 };
 }
 
-extern int bob; // expected-note {{previous declaration is here}}
+extern int bob; // expected-note 3 {{previous declaration is here}}
+typedef int bob1; // expected-note 3 {{previous declaration is here}}
+using bob2=int; // expected-note 3 {{previous declaration is here}}
 
 // rdar://8883302
 void rdar8883302() {
@@ -96,8 +142,22 @@
 
 void test8() {
   int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
+  int bob1; // expected-warning {{declaration shadows a typedef in the global namespace}}
+  int bob2; // expected-warning {{declaration shadows a type alias in the global namespace}}
 }
 
+void test9() {
+  typedef int bob; // expected-warning {{declaration shadows a variable in the global namespace}

[PATCH] D31235: Enhance -Wshadow to warn when shadowing typedefs or type aliases

2017-03-22 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi updated this revision to Diff 92659.
ahmedasadi added a comment.

Updated diff to include context.


https://reviews.llvm.org/D31235

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/warn-shadow.cpp

Index: test/SemaCXX/warn-shadow.cpp
===
--- test/SemaCXX/warn-shadow.cpp
+++ test/SemaCXX/warn-shadow.cpp
@@ -1,20 +1,27 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow-all %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -Wshadow-all %s
 
 namespace {
   int i; // expected-note {{previous declaration is here}}
 }
 
 namespace one {
 namespace two {
   int j; // expected-note {{previous declaration is here}}
+  typedef int jj; // expected-note 3 {{previous declaration is here}}
+  using jjj=int; // expected-note 3 {{previous declaration is here}}
 }
 }
 
 namespace xx {
   int m;
+  typedef int mm;
+  using mmm=int;
+
 }
 namespace yy {
   int m;
+  typedef char mm;
+  using mmm=char;
 }
 
 using namespace one::two;
@@ -25,14 +32,19 @@
   int i; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
   int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
   int m;
+  int mm;
+  int mmm;
 }
 
 class A {
-  static int data; // expected-note {{previous declaration}}
-  // expected-note@+1 {{previous declaration}}
+  static int data; // expected-note 3 {{previous declaration}}
+  // expected-note@+1 3 {{previous declaration}}
   int field;
   int f1, f2, f3, f4; // expected-note 8 {{previous declaration is here}}
 
+  typedef int a1; // expected-note 3 {{previous declaration}}
+  using a2=int; // expected-note 3 {{previous declaration}}
+
   // The initialization is safe, but the modifications are not.
   A(int f1, int f2, int f3, int f4) // expected-note-re 4 {{variable 'f{{[0-4]}}' is declared here}}
 	  : f1(f1) {
@@ -50,6 +62,28 @@
   void test() {
 char *field; // expected-warning {{declaration shadows a field of 'A'}}
 char *data; // expected-warning {{declaration shadows a static data member of 'A'}}
+char *a1; // expected-warning {{declaration shadows a typedef in 'A'}}
+char *a2; // expected-warning {{declaration shadows a type alias in 'A'}}
+char *jj; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+char *jjj; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
+  }
+
+  void test2() {
+typedef char field; // expected-warning {{declaration shadows a field of 'A'}}
+typedef char data; // expected-warning {{declaration shadows a static data member of 'A'}}
+typedef char a1; // expected-warning {{declaration shadows a typedef in 'A'}}
+typedef char a2; // expected-warning {{declaration shadows a type alias in 'A'}}
+typedef char jj; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+typedef char jjj; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
+  }
+
+  void test3() {
+using field=char; // expected-warning {{declaration shadows a field of 'A'}}
+using data=char; // expected-warning {{declaration shadows a static data member of 'A'}}
+using a1=char; // expected-warning {{declaration shadows a typedef in 'A'}}
+using a2=char; // expected-warning {{declaration shadows a type alias in 'A'}}
+using jj=char; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+using jjj=char; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
   }
 };
 
@@ -63,13 +97,23 @@
 namespace rdar8900456 {
 struct Foo {
   static void Baz();
+  static void Baz1();
+  static void Baz2();
 private:
   int Bar;
 };
 
 void Foo::Baz() {
   double Bar = 12; // Don't warn.
 }
+
+void Foo::Baz1() {
+  typedef int Bar; // Don't warn.
+}
+
+void Foo::Baz2() {
+  using Bar=int; // Don't warn.
+}
 }
 
 // http://llvm.org/PR9160
@@ -87,23 +131,68 @@
 };
 }
 
-extern int bob; // expected-note {{previous declaration is here}}
+extern int bob; // expected-note 3 {{previous declaration is here}}
+typedef int bob1; // expected-note 3 {{previous declaration is here}}
+using bob2=int; // expected-note 3 {{previous declaration is here}}
 
 // rdar://8883302
 void rdar8883302() {
   extern int bob; // don't warn for shadowing.
 }
 
 void test8() {
   int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
+  int bob1; // expected-warning {{declaration shadows a typedef in the global namespace}}
+  int bob2; // expected-warning {{declaration shadows a type alias in the global namespace}}
+}
+
+void test9() {
+  typedef int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
+  typedef int bob1; // expected-warning {{declaration shadows a typedef in the global namespace}}
+  typedef int bob2; // expected-warning {{declaration shadows a 

[PATCH] D31235: Enhance -Wshadow to warn when shadowing typedefs or type aliases

2017-03-22 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi added inline comments.



Comment at: lib/Sema/SemaDecl.cpp:6753
 // the constructor initializes the field with the parameter.
-if (isa(NewDC) && isa(D)) {
-  // Remember that this was shadowed so we can either warn about its
-  // modification or its existence depending on warning settings.
-  D = D->getCanonicalDecl();
-  ShadowingDecls.insert({D, FD});
-  return;
-}
+if (isa(NewDC))
+  if (ParmVarDecl* PVD = dyn_cast(D)) {

arphaman wrote:
> Why is the change to this `if` necessary? It doesn't seem that related to the 
> main change.
VarDecl overrides getCanonicalDecl() to return a VarDecl*. As the type of D was 
changed from VarDecl* to NamedDecl*,  getCanonicalDecl() now returns a 
NamedDecl*. 

I created a new ParmVarDecl variable so getCanonicalDecl() returns a VarDecl* 
which can be inserted into ShadowingDecls.

Perhaps it might be better to just cast D->getCanonicalDecl() to a VarDecl when 
inserting it into ShadowingDecls?


https://reviews.llvm.org/D31235



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31235: Enhance -Wshadow to warn when shadowing typedefs or type aliases

2017-03-28 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi marked 3 inline comments as done.
ahmedasadi added inline comments.



Comment at: test/SemaCXX/warn-shadow.cpp:65
 char *data; // expected-warning {{declaration shadows a static data member 
of 'A'}}
+char *a1; // expected-warning {{declaration shadows a typedef in 'A'}}
+char *a2; // expected-warning {{declaration shadows a type alias in 'A'}}

arphaman wrote:
> It looks like previously this wouldn't have been a warning. Should we really 
> warn about local variables that shadow typedef names?
GCC does, though I agree the warning isn't that helpful as a variable typically 
can't be used in place of a type (only exception I can think of is sizeof).

I'll modify the patch to only warn when typedefs / type aliases shadow each 
other.


https://reviews.llvm.org/D31235



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31235: Enhance -Wshadow to warn when shadowing typedefs or type aliases

2017-03-28 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi updated this revision to Diff 93342.
ahmedasadi marked 4 inline comments as done.

https://reviews.llvm.org/D31235

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/warn-shadow.cpp

Index: test/SemaCXX/warn-shadow.cpp
===
--- test/SemaCXX/warn-shadow.cpp
+++ test/SemaCXX/warn-shadow.cpp
@@ -1,20 +1,27 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow-all %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -Wshadow-all %s
 
 namespace {
   int i; // expected-note {{previous declaration is here}}
 }
 
 namespace one {
 namespace two {
   int j; // expected-note {{previous declaration is here}}
+  typedef int jj; // expected-note 2 {{previous declaration is here}}
+  using jjj=int; // expected-note 2 {{previous declaration is here}}
 }
 }
 
 namespace xx {
   int m;
+  typedef int mm;
+  using mmm=int;
+
 }
 namespace yy {
   int m;
+  typedef char mm;
+  using mmm=char;
 }
 
 using namespace one::two;
@@ -25,14 +32,19 @@
   int i; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
   int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
   int m;
+  int mm;
+  int mmm;
 }
 
 class A {
-  static int data; // expected-note {{previous declaration}}
-  // expected-note@+1 {{previous declaration}}
+  static int data; // expected-note 1 {{previous declaration}}
+  // expected-note@+1 1 {{previous declaration}}
   int field;
   int f1, f2, f3, f4; // expected-note 8 {{previous declaration is here}}
 
+  typedef int a1; // expected-note 2 {{previous declaration}}
+  using a2=int; // expected-note 2 {{previous declaration}}
+
   // The initialization is safe, but the modifications are not.
   A(int f1, int f2, int f3, int f4) // expected-note-re 4 {{variable 'f{{[0-4]}}' is declared here}}
 	  : f1(f1) {
@@ -50,6 +62,28 @@
   void test() {
 char *field; // expected-warning {{declaration shadows a field of 'A'}}
 char *data; // expected-warning {{declaration shadows a static data member of 'A'}}
+char *a1; // no warning 
+char *a2; // no warning
+char *jj; // no warning
+char *jjj; // no warning
+  }
+
+  void test2() {
+typedef char field; // no warning
+typedef char data; // no warning
+typedef char a1; // expected-warning {{declaration shadows a typedef in 'A'}}
+typedef char a2; // expected-warning {{declaration shadows a type alias in 'A'}}
+typedef char jj; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+typedef char jjj; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
+  }
+
+  void test3() {
+using field=char; // no warning
+using data=char; // no warning
+using a1=char; // expected-warning {{declaration shadows a typedef in 'A'}}
+using a2=char; // expected-warning {{declaration shadows a type alias in 'A'}}
+using jj=char; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+using jjj=char; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
   }
 };
 
@@ -63,13 +97,23 @@
 namespace rdar8900456 {
 struct Foo {
   static void Baz();
+  static void Baz1();
+  static void Baz2();
 private:
   int Bar;
 };
 
 void Foo::Baz() {
   double Bar = 12; // Don't warn.
 }
+
+void Foo::Baz1() {
+  typedef int Bar; // Don't warn.
+}
+
+void Foo::Baz2() {
+  using Bar=int; // Don't warn.
+}
 }
 
 // http://llvm.org/PR9160
@@ -87,23 +131,68 @@
 };
 }
 
-extern int bob; // expected-note {{previous declaration is here}}
+extern int bob; // expected-note 1 {{previous declaration is here}}
+typedef int bob1; // expected-note 2 {{previous declaration is here}}
+using bob2=int; // expected-note 2 {{previous declaration is here}}
 
 // rdar://8883302
 void rdar8883302() {
   extern int bob; // don't warn for shadowing.
 }
 
 void test8() {
   int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
+  int bob1; //no warning
+  int bob2; // no warning
+}
+
+void test9() {
+  typedef int bob; // no warning
+  typedef int bob1; // expected-warning {{declaration shadows a typedef in the global namespace}}
+  typedef int bob2; // expected-warning {{declaration shadows a type alias in the global namespace}}
+}
+
+void test10() {
+  using bob=int; // no warning
+  using bob1=int; // expected-warning {{declaration shadows a typedef in the global namespace}}
+  using bob2=int; // expected-warning {{declaration shadows a type alias in the global namespace}}
 }
 
 namespace rdar29067894 {
 
 void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition is here}}
   int a = 0; // expected-note {{previous definition is here}}
   int a = 1; // expected-error {{redefinition of 'a'}}
   int b = 2; // expected-error {{redefinition of 'b'}}
+
+  using c=char; // expected-note {{previous definition is 

[PATCH] D31235: Enhance -Wshadow to warn when shadowing typedefs or type aliases

2017-03-30 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi added a comment.

Thanks for reviewing. Would you be able to commit this patch for me, as I do 
not have commit access?


https://reviews.llvm.org/D31235



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31235: Enhance -Wshadow to warn when shadowing typedefs or type aliases

2017-03-30 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi updated this revision to Diff 93583.
ahmedasadi marked an inline comment as done.
ahmedasadi added a comment.

Re-ordered the checks in shouldWarnIfShadowedDecl as suggested by rnk.


https://reviews.llvm.org/D31235

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/warn-shadow.cpp

Index: test/SemaCXX/warn-shadow.cpp
===
--- test/SemaCXX/warn-shadow.cpp
+++ test/SemaCXX/warn-shadow.cpp
@@ -1,20 +1,27 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow-all %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -Wshadow-all %s
 
 namespace {
   int i; // expected-note {{previous declaration is here}}
 }
 
 namespace one {
 namespace two {
   int j; // expected-note {{previous declaration is here}}
+  typedef int jj; // expected-note 2 {{previous declaration is here}}
+  using jjj=int; // expected-note 2 {{previous declaration is here}}
 }
 }
 
 namespace xx {
   int m;
+  typedef int mm;
+  using mmm=int;
+
 }
 namespace yy {
   int m;
+  typedef char mm;
+  using mmm=char;
 }
 
 using namespace one::two;
@@ -25,14 +32,19 @@
   int i; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
   int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
   int m;
+  int mm;
+  int mmm;
 }
 
 class A {
-  static int data; // expected-note {{previous declaration}}
-  // expected-note@+1 {{previous declaration}}
+  static int data; // expected-note 1 {{previous declaration}}
+  // expected-note@+1 1 {{previous declaration}}
   int field;
   int f1, f2, f3, f4; // expected-note 8 {{previous declaration is here}}
 
+  typedef int a1; // expected-note 2 {{previous declaration}}
+  using a2=int; // expected-note 2 {{previous declaration}}
+
   // The initialization is safe, but the modifications are not.
   A(int f1, int f2, int f3, int f4) // expected-note-re 4 {{variable 'f{{[0-4]}}' is declared here}}
 	  : f1(f1) {
@@ -50,6 +62,28 @@
   void test() {
 char *field; // expected-warning {{declaration shadows a field of 'A'}}
 char *data; // expected-warning {{declaration shadows a static data member of 'A'}}
+char *a1; // no warning 
+char *a2; // no warning
+char *jj; // no warning
+char *jjj; // no warning
+  }
+
+  void test2() {
+typedef char field; // no warning
+typedef char data; // no warning
+typedef char a1; // expected-warning {{declaration shadows a typedef in 'A'}}
+typedef char a2; // expected-warning {{declaration shadows a type alias in 'A'}}
+typedef char jj; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+typedef char jjj; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
+  }
+
+  void test3() {
+using field=char; // no warning
+using data=char; // no warning
+using a1=char; // expected-warning {{declaration shadows a typedef in 'A'}}
+using a2=char; // expected-warning {{declaration shadows a type alias in 'A'}}
+using jj=char; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
+using jjj=char; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
   }
 };
 
@@ -63,13 +97,23 @@
 namespace rdar8900456 {
 struct Foo {
   static void Baz();
+  static void Baz1();
+  static void Baz2();
 private:
   int Bar;
 };
 
 void Foo::Baz() {
   double Bar = 12; // Don't warn.
 }
+
+void Foo::Baz1() {
+  typedef int Bar; // Don't warn.
+}
+
+void Foo::Baz2() {
+  using Bar=int; // Don't warn.
+}
 }
 
 // http://llvm.org/PR9160
@@ -87,23 +131,68 @@
 };
 }
 
-extern int bob; // expected-note {{previous declaration is here}}
+extern int bob; // expected-note 1 {{previous declaration is here}}
+typedef int bob1; // expected-note 2 {{previous declaration is here}}
+using bob2=int; // expected-note 2 {{previous declaration is here}}
 
 // rdar://8883302
 void rdar8883302() {
   extern int bob; // don't warn for shadowing.
 }
 
 void test8() {
   int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
+  int bob1; //no warning
+  int bob2; // no warning
+}
+
+void test9() {
+  typedef int bob; // no warning
+  typedef int bob1; // expected-warning {{declaration shadows a typedef in the global namespace}}
+  typedef int bob2; // expected-warning {{declaration shadows a type alias in the global namespace}}
+}
+
+void test10() {
+  using bob=int; // no warning
+  using bob1=int; // expected-warning {{declaration shadows a typedef in the global namespace}}
+  using bob2=int; // expected-warning {{declaration shadows a type alias in the global namespace}}
 }
 
 namespace rdar29067894 {
 
 void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition is here}}
   int a = 0; // expected-note {{previous definition is here}}
   int a = 1; // expected-error {{redefinition of 'a'}}
   int b = 2; //

[PATCH] D31235: Enhance -Wshadow to warn when shadowing typedefs or type aliases

2017-04-03 Thread Ahmed Asadi via Phabricator via cfe-commits
ahmedasadi updated this revision to Diff 94007.
ahmedasadi added a comment.

Updated diff to address Eric's comment - it's best not to issue a warning if 
the shadowing declaration is part of a class (this is what GCC currently does).

I will need someone to commit this new patch for me.


https://reviews.llvm.org/D31235

Files:
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/warn-shadow.cpp


Index: test/SemaCXX/warn-shadow.cpp
===
--- test/SemaCXX/warn-shadow.cpp
+++ test/SemaCXX/warn-shadow.cpp
@@ -87,6 +87,16 @@
   }
 };
 
+struct path {
+  using value_type = char;
+  typedef char value_type2;
+  struct iterator {
+using value_type = path; // no warning
+typedef path value_type2; // no warning
+  };
+};
+
+
 // TODO: this should warn, 
 class B : A {
   int data;
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -6742,6 +6742,10 @@
 /// if it doesn't shadow any declaration or shadowing warnings are disabled.
 NamedDecl *Sema::getShadowedDeclaration(const TypedefNameDecl *D,
 const LookupResult &R) {
+  // Don't warn if typedef declaration is part of a class
+  if (D->getDeclContext()->isRecord())
+return nullptr;
+  
   if (!shouldWarnIfShadowedDecl(Diags, R))
 return nullptr;
 


Index: test/SemaCXX/warn-shadow.cpp
===
--- test/SemaCXX/warn-shadow.cpp
+++ test/SemaCXX/warn-shadow.cpp
@@ -87,6 +87,16 @@
   }
 };
 
+struct path {
+  using value_type = char;
+  typedef char value_type2;
+  struct iterator {
+using value_type = path; // no warning
+typedef path value_type2; // no warning
+  };
+};
+
+
 // TODO: this should warn, 
 class B : A {
   int data;
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -6742,6 +6742,10 @@
 /// if it doesn't shadow any declaration or shadowing warnings are disabled.
 NamedDecl *Sema::getShadowedDeclaration(const TypedefNameDecl *D,
 const LookupResult &R) {
+  // Don't warn if typedef declaration is part of a class
+  if (D->getDeclContext()->isRecord())
+return nullptr;
+  
   if (!shouldWarnIfShadowedDecl(Diags, R))
 return nullptr;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits