[PATCH] D31069: Don't warn about an unreachable fallthrough annotation in a template function
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
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
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
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
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
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
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
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
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
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