diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-03-22 01:49:19 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-03-22 01:49:19 +0000 |
commit | 7532d3790f5fd0919dbad401b3f952b37c601a2a (patch) | |
tree | 4a234ee7e1718169c244b7e017b852e2f06614de | |
parent | 81ee1a59efd6ec2aaf53ad2e2b5f62f2a8da3b08 (diff) | |
download | bcm5719-llvm-7532d3790f5fd0919dbad401b3f952b37c601a2a.tar.gz bcm5719-llvm-7532d3790f5fd0919dbad401b3f952b37c601a2a.zip |
Suppress warning on unreachable [[clang::fallthrough]] within a template instantiation.
We don't know whether some other instantiation of the template might be able to
reach the annotation, so warning on it has a high chance of false positives.
Patch by Ahmed Asadi!
Differential Revision: https://reviews.llvm.org/D31069
llvm-svn: 298477
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 17 | ||||
-rw-r--r-- | clang/test/SemaCXX/P30636.cpp | 20 |
2 files changed, 33 insertions, 4 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index a987a8ce0b3..50ad113fc88 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -972,7 +972,8 @@ namespace { } } - 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 +1003,12 @@ namespace { ElemIt != ElemEnd; ++ElemIt) { if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>()) { 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 +1169,11 @@ static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC, int AnnotatedCnt; - if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt)) + bool IsTemplateInstantiation = false; + if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(AC.getDecl())) + IsTemplateInstantiation = Function->isTemplateInstantiation(); + if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt, + IsTemplateInstantiation)) continue; S.Diag(Label->getLocStart(), diff --git a/clang/test/SemaCXX/P30636.cpp b/clang/test/SemaCXX/P30636.cpp new file mode 100644 index 00000000000..2e2affb0cfd --- /dev/null +++ b/clang/test/SemaCXX/P30636.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s +// expected-no-diagnostics + +template<bool param> +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<true> case) in a template function + case 2: + return 4; + default: + return 5; + } +} + +template int fallthrough_template<true>(int); + |