From 50205744c32d3925ba50d1bd69b1c9e6ab3a28b8 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 9 Sep 2010 00:06:07 +0000 Subject: [PATCH] Enhance -Wreturn-type to not warn when control-flow is most likely limited by a switch statement explicitly covering all the cases for an enum value. llvm-svn: 113450 --- clang/lib/Sema/AnalysisBasedWarnings.cpp | 14 +++++++++----- clang/test/Sema/return.c | 13 +++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index cfebed6a05b2..a46755bbd99a 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -108,11 +108,15 @@ static ControlFlowKind CheckFallThrough(AnalysisContext &AC) { bool HasFakeEdge = false; bool HasPlainEdge = false; bool HasAbnormalEdge = false; - for (CFGBlock::pred_iterator I=cfg->getExit().pred_begin(), - E = cfg->getExit().pred_end(); - I != E; - ++I) { - CFGBlock& B = **I; + + // Ignore default cases that aren't likely to be reachable because all + // enums in a switch(X) have explicit case statements. + CFGBlock::FilterOptions FO; + FO.IgnoreDefaultsWithCoveredEnums = 1; + + for (CFGBlock::filtered_pred_iterator + I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) { + const CFGBlock& B = **I; if (!live[B.getBlockID()]) continue; if (B.size() == 0) { diff --git a/clang/test/Sema/return.c b/clang/test/Sema/return.c index 54c340634d39..597b50214e43 100644 --- a/clang/test/Sema/return.c +++ b/clang/test/Sema/return.c @@ -242,3 +242,16 @@ static inline int si_forward() {} // expected-warning{{control reaches end of no // Test warnings on ignored qualifiers on return types. const int ignored_c_quals(); // expected-warning{{'const' type qualifier on return type has no effect}} const volatile int ignored_cv_quals(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}} + +// Test that for switch(enum) that if the switch statement covers all the cases +// that we don't consider that for -Wreturn-type. +enum Cases { C1, C2, C3, C4 }; +int test_enum_cases(enum Cases C) { + switch (C) { + case C1: return 1; + case C2: return 2; + case C4: return 3; + case C3: return 4; + } +} // no-warning +