Add -Wimplicit-fallthrough command line option to clang in

the xcode project file to catch switch statements that have a
case that falls through unintentionally.

Define LLVM_FALLTHROUGH to indicate instances where a case has code
and intends to fall through.  This should be in llvm/Support/Compiler.h;
Peter Collingbourne originally checked in there (r237766), then
reverted (r237941) because he didn't have time to mark up all the
'case' statements that were intended to fall through.  I put together
a patch to get this back in llvm http://reviews.llvm.org/D17063 but
it hasn't been approved in the past week.  I added a new
lldb-private-defines.h to hold the definition for now.

Every place in lldb where there is a comment that the fall-through
is intentional, I added LLVM_FALLTHROUGH to silence the warning.
I haven't tried to identify whether the fallthrough is a bug or
not in the other places.

I haven't tried to add this to the cmake option build flags.
This warning will only work for clang.

This build cleanly (with some new warnings) on macosx with clang
under xcodebuild, but if this causes problems for people on other
configurations, I'll back it out.

llvm-svn: 260930
This commit is contained in:
Jason Molenda 2016-02-16 04:14:33 +00:00
parent 75a18c20b1
commit 62e0681afb
28 changed files with 88 additions and 29 deletions

View File

@ -0,0 +1,39 @@
//===-- lldb-private-defines.h ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_lldb_private_defines_h_
#define liblldb_lldb_private_defines_h_
#if defined(__cplusplus)
// Include Compiler.h here so we don't define LLVM_FALLTHROUGH and then Compiler.h
// later tries to redefine it.
#include "llvm/Support/Compiler.h"
#ifndef LLVM_FALLTHROUGH
#ifndef __has_cpp_attribute
# define __has_cpp_attribute(x) 0
#endif
/// \macro LLVM_FALLTHROUGH
/// \brief Marks an empty statement preceding a deliberate switch fallthrough.
#if __has_cpp_attribute(clang::fallthrough)
#define LLVM_FALLTHROUGH [[clang::fallthrough]]
#else
#define LLVM_FALLTHROUGH
#endif
#endif // ifndef LLVM_FALLTHROUGH
#endif // #if defined(__cplusplus)
#endif // liblldb_lldb_private_defines_h_

View File

@ -24,6 +24,7 @@
#include "lldb/lldb-private-enumerations.h"
#include "lldb/lldb-private-interfaces.h"
#include "lldb/lldb-private-types.h"
#include "lldb/lldb-private-defines.h"
namespace lldb_private {

View File

@ -7289,6 +7289,7 @@
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
"-Wimplicit-fallthrough",
);
OTHER_LDFLAGS = (
"$(LLDB_COMPRESSION_LDFLAGS)",
@ -7374,6 +7375,7 @@
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
"-Wimplicit-fallthrough",
);
OTHER_LDFLAGS = (
"$(LLDB_COMPRESSION_LDFLAGS)",
@ -8079,6 +8081,7 @@
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
"-Wimplicit-fallthrough",
);
OTHER_LDFLAGS = (
"$(LLDB_COMPRESSION_LDFLAGS)",
@ -8789,6 +8792,7 @@
"-Wparentheses",
"$(LLDB_ZLIB_CFLAGS)",
"$(LLDB_COMPRESSION_CFLAGS)",
"-Wimplicit-fallthrough",
);
OTHER_LDFLAGS = (
"$(LLDB_COMPRESSION_LDFLAGS)",

View File

@ -15,6 +15,7 @@
// C++ Includes
// Other libraries and framework includes
#include "clang/AST/Decl.h"
// Project includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
@ -41,6 +42,8 @@
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb-private.h"
using namespace lldb;
using namespace lldb_private;
@ -488,7 +491,7 @@ protected:
{
case '*':
++pointer_count;
// fall through...
LLVM_FALLTHROUGH;
case ' ':
case '\t':
type_str.erase(type_str.size()-1);

View File

@ -448,7 +448,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
else
s->Printf("%s[","<Unknown>");
}
// Fall through
LLVM_FALLTHROUGH;
case DumpStyleFileAddress:
{
addr_t file_addr = GetFileAddress();

View File

@ -163,7 +163,7 @@ AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style, Address:
case Address::DumpStyleModuleWithFileAddress:
show_module = true;
// fall through
LLVM_FALLTHROUGH;
case Address::DumpStyleFileAddress:
vmaddr = m_base_addr.GetFileAddress();
break;

View File

@ -1050,7 +1050,7 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in
case ArchSpec::eCore_arm_generic:
if (enforce_exact_match)
break;
// Fall through to case below
LLVM_FALLTHROUGH;
case ArchSpec::kCore_arm_any:
if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last)
return true;

View File

@ -403,7 +403,7 @@ Communication::ReadThread (lldb::thread_arg_t p)
case eConnectionStatusNoConnection: // No connection
case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection
done = true;
// Fall through...
LLVM_FALLTHROUGH;
case eConnectionStatusTimedOut: // Request timed out
if (log)
error.LogIfError (log,

View File

@ -22,6 +22,8 @@
#include "llvm/Support/Compiler.h" // LLVM_{NOEXCEPT, CONSTEXPR, ALIGNAS}
#undef _LIBCPP_EXTERN_TEMPLATE // Avoid warning below
#include "lldb/lldb-private.h"
//===-------------------------- cxa_demangle.cpp --------------------------===//
//
// The LLVM Compiler Infrastructure
@ -2262,7 +2264,7 @@ parse_type(const char* first, const char* last, C& db)
break;
}
}
// drop through
LLVM_FALLTHROUGH;
default:
// must check for builtin-types before class-enum-types to avoid
// ambiguities with operator-names

View File

@ -11,6 +11,8 @@
#include <string.h>
#include <stdlib.h>
#include "lldb/lldb-private.h"
//#define DEBUG_FAILURES 1
//#define DEBUG_SUBSTITUTIONS 1
//#define DEBUG_TEMPLATE_ARGS 1
@ -1627,7 +1629,7 @@ private:
return Parse('E');
}
--m_read_ptr;
// fallthrough
LLVM_FALLTHROUGH;
case 'w':
case 'c':
case 'a':
@ -1827,7 +1829,7 @@ private:
if (*m_read_ptr++ == 'r')
return ParseUnresolvedName();
--m_read_ptr;
// fallthrough
LLVM_FALLTHROUGH;
default:
return ParseExpressionPrimary();
}
@ -2099,7 +2101,7 @@ private:
}
case 'L':
++m_read_ptr;
// fallthrough
LLVM_FALLTHROUGH;
default:
{
if (!ParseUnscopedName(name_state))
@ -2293,7 +2295,7 @@ private:
m_read_ptr += strlen(m_read_ptr);
break;
}
// fallthrough
LLVM_FALLTHROUGH;
default:
if (first_param)
first_param = false;

View File

@ -751,7 +751,7 @@ DumpValue (Stream &s,
case FormatEntity::Entry::Type::ScriptVariableSynthetic:
is_script = true;
// Fall through
LLVM_FALLTHROUGH;
case FormatEntity::Entry::Type::VariableSynthetic:
custom_format = entry.fmt;
val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;

View File

@ -410,7 +410,7 @@ REPL::IOHandlerInputComplete (IOHandler &io_handler, std::string &code)
case lldb::eExpressionSetupError:
case lldb::eExpressionParseError:
add_to_code = false;
// Fall through
LLVM_FALLTHROUGH;
case lldb::eExpressionDiscarded:
error_sp->Printf("%s\n", error.AsCString());
break;

View File

@ -316,6 +316,7 @@ OptionValueArray::SetArgs (const Args &args, VarSetOperationType op)
case eVarSetOperationAssign:
m_values.clear();
// Fall through to append case
LLVM_FALLTHROUGH;
case eVarSetOperationAppend:
for (size_t i=0; i<argc; ++i)
{

View File

@ -88,6 +88,7 @@ OptionValueFileSpecList::SetValueFromString (llvm::StringRef value, VarSetOperat
case eVarSetOperationAssign:
m_current_value.Clear();
// Fall through to append case
LLVM_FALLTHROUGH;
case eVarSetOperationAppend:
if (argc > 0)
{

View File

@ -85,6 +85,7 @@ OptionValuePathMappings::SetValueFromString (llvm::StringRef value, VarSetOperat
}
m_path_mappings.Clear(m_notify_changes);
// Fall through to append case
LLVM_FALLTHROUGH;
case eVarSetOperationAppend:
if (argc < 2 || (argc & 1))
{

View File

@ -295,7 +295,7 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
case lldb::eLanguageTypeC_plus_plus_14:
m_compiler->getLangOpts().CPlusPlus11 = true;
m_compiler->getHeaderSearchOpts().UseLibcxx = true;
// fall thru ...
LLVM_FALLTHROUGH;
case lldb::eLanguageTypeC_plus_plus_03:
m_compiler->getLangOpts().CPlusPlus = true;
// FIXME: the following language option is a temporary workaround,

View File

@ -4090,7 +4090,7 @@ ObjectFileMachO::ParseSymtab ()
case N_ECOML:
// end common (local name): 0,,n_sect,0,address
symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
// Fall through
LLVM_FALLTHROUGH;
case N_ECOMM:
// end common: name,,n_sect,0,0
@ -4146,7 +4146,8 @@ ObjectFileMachO::ParseSymtab ()
ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0));
undefined_name_to_desc[undefined_name] = nlist.n_desc;
}
// Fall through
LLVM_FALLTHROUGH;
case N_PBUD:
type = eSymbolTypeUndefined;
break;

View File

@ -611,7 +611,8 @@ PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite
break;
case llvm::Triple::thumb:
bp_is_thumb = true; // Fall through...
bp_is_thumb = true;
LLVM_FALLTHROUGH;
case llvm::Triple::arm:
{
static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };

View File

@ -326,6 +326,7 @@ CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtrac
SendRequestPacketNoLock (request_ack_packet);
}
// Fall through to case below to get packet contents
LLVM_FALLTHROUGH;
case ePacketTypeReply | KDP_CONNECT:
case ePacketTypeReply | KDP_DISCONNECT:
case ePacketTypeReply | KDP_HOSTINFO:

View File

@ -845,7 +845,7 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri
case '%': // Async notify packet
isNotifyPacket = true;
// Intentional fall through
LLVM_FALLTHROUGH;
case '$':
// Look for a standard gdb packet?

View File

@ -4418,7 +4418,7 @@ GDBRemoteCommunicationClient::ReadExtFeature (const lldb_private::ConstString ob
// last chunk
case ( 'l' ):
active = false;
// fall through intentional
LLVM_FALLTHROUGH;
// more chunks
case ( 'm' ) :

View File

@ -1367,7 +1367,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet
thread_action.signal = packet.GetHexMaxU32 (false, 0);
if (thread_action.signal == 0)
return SendIllFormedResponse (packet, "Could not parse signal in vCont packet C action");
// Fall through to next case...
LLVM_FALLTHROUGH;
case 'c':
// Continue
@ -1378,7 +1378,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet
thread_action.signal = packet.GetHexMaxU32 (false, 0);
if (thread_action.signal == 0)
return SendIllFormedResponse (packet, "Could not parse signal in vCont packet S action");
// Fall through to next case...
LLVM_FALLTHROUGH;
case 's':
// Step

View File

@ -345,6 +345,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
break;
}
// Fall through to base type below in case we can handle the type there...
LLVM_FALLTHROUGH;
case DW_TAG_base_type:
resolve_state = Type::eResolveStateFull;

View File

@ -942,7 +942,7 @@ DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* cu,
// referencing this DIE because curr_depth is not zero
break;
}
// Fall through...
LLVM_FALLTHROUGH;
default:
attributes.Append(cu, offset, attr, form);
break;

View File

@ -220,7 +220,7 @@ DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
hash_data_has_fixed_byte_size = false;
// Fall through to the cases below...
LLVM_FALLTHROUGH;
case DW_FORM_flag:
case DW_FORM_data1:
case DW_FORM_ref1:
@ -230,7 +230,7 @@ DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
case DW_FORM_block2:
hash_data_has_fixed_byte_size = false;
// Fall through to the cases below...
LLVM_FALLTHROUGH;
case DW_FORM_data2:
case DW_FORM_ref2:
min_hash_data_byte_size += 2;
@ -238,7 +238,7 @@ DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
case DW_FORM_block4:
hash_data_has_fixed_byte_size = false;
// Fall through to the cases below...
LLVM_FALLTHROUGH;
case DW_FORM_data4:
case DW_FORM_ref4:
case DW_FORM_addr:

View File

@ -4728,7 +4728,7 @@ ClangASTContext::GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContext
}
}
}
// fallthrough
LLVM_FALLTHROUGH;
default:
const uint32_t bit_size = getASTContext()->getTypeSize (qual_type);
if (bit_size == 0)
@ -9299,6 +9299,7 @@ ClangASTContext::DumpTypeValue (lldb::opaque_compiler_type_t type, Stream *s,
return true;
}
// format was not enum, just fall through and dump the value as requested....
LLVM_FALLTHROUGH;
default:
// We are down to a scalar type that we just need to display.

View File

@ -3884,7 +3884,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
m_stdio_communication.StopReadThread();
m_stdin_forward = false;
// fall-through
LLVM_FALLTHROUGH;
case eStateConnected:
case eStateAttaching:
case eStateLaunching:

View File

@ -756,7 +756,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
}
}
var_path.erase (0, 1); // Remove the '-'
// Fall through
LLVM_FALLTHROUGH;
case '.':
{
const bool expr_is_ptr = var_path[0] == '>';
@ -1554,12 +1554,12 @@ StackFrame::GetStatus (Stream& strm,
case Debugger::eStopDisassemblyTypeNoDebugInfo:
if (have_debuginfo)
break;
// Fall through to next case
LLVM_FALLTHROUGH;
case Debugger::eStopDisassemblyTypeNoSource:
if (have_source)
break;
// Fall through to next case
LLVM_FALLTHROUGH;
case Debugger::eStopDisassemblyTypeAlways:
if (target)