public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Add fallthrough attributes
@ 2018-02-08 22:57 Joshua Watt
  2018-02-08 23:30 ` [PATCH v2] " Joshua Watt
  0 siblings, 1 reply; 10+ messages in thread
From: Joshua Watt @ 2018-02-08 22:57 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Joshua Watt

Adds the __attribute__ ((fallthrough)) annotation to all the places
where switch case fallthrough was occurring. This allows the
-Wimplicit-fallthrough warning to be used even after the source has been
pre-processed.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 backends/i386_regs.c         |  3 +++
 backends/i386_retval.c       |  3 +++
 backends/m68k_retval.c       |  3 +++
 backends/ppc_regs.c          |  3 +++
 backends/x86_64_regs.c       |  3 +++
 configure.ac                 | 22 ++++++++++++++++++++++
 libcpu/i386_disasm.c         |  3 +++
 libdw/cfi.c                  |  6 ++++++
 libdw/dwarf_frame_register.c |  3 +++
 libdwfl/dwfl_report_elf.c    |  3 +++
 libdwfl/frame_unwind.c       |  3 +++
 libebl/eblobjnote.c          |  3 +++
 libelf/elf32_updatenull.c    |  3 +++
 libelf/elf_begin.c           |  6 ++++++
 libelf/elf_cntl.c            |  3 +++
 src/addr2line.c              |  3 +++
 src/elfcompress.c            |  3 +++
 src/elflint.c                | 12 ++++++++++++
 src/objdump.c                |  3 +++
 src/readelf.c                |  3 +++
 src/strings.c                |  3 +++
 tests/backtrace.c            |  3 +++
 tests/elfstrmerge.c          |  3 +++
 23 files changed, 103 insertions(+)

diff --git a/backends/i386_regs.c b/backends/i386_regs.c
index fd963a62..1488c1e7 100644
--- a/backends/i386_regs.c
+++ b/backends/i386_regs.c
@@ -92,6 +92,9 @@ i386_register_info (Ebl *ebl __attribute__ ((unused)),
     case 5:
     case 8:
       *type = DW_ATE_address;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     case 0 ... 3:
     case 6 ... 7:
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index 4aa646fe..56493a74 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -123,6 +123,9 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	if (size <= 8)
 	  return nloc_intregpair;
       }
+#ifdef HAVE_FALLTHROUGH
+    __attribute__ ((fallthrough));
+#endif
     /* Fallthrough */
 
     case DW_TAG_structure_type:
diff --git a/backends/m68k_retval.c b/backends/m68k_retval.c
index c68ed022..d9ff5cf6 100644
--- a/backends/m68k_retval.c
+++ b/backends/m68k_retval.c
@@ -135,6 +135,9 @@ m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	if (size <= 8)
 	  return nloc_intregpair;
       }
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
diff --git a/backends/ppc_regs.c b/backends/ppc_regs.c
index c2d50118..0e0fed20 100644
--- a/backends/ppc_regs.c
+++ b/backends/ppc_regs.c
@@ -140,6 +140,9 @@ ppc_register_info (Ebl *ebl __attribute__ ((unused)),
     case 100:
       if (*bits == 32)
 	return stpcpy (name, "mq") + 1 - name;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     case 102 ... 107:
       name[0] = 's';
diff --git a/backends/x86_64_regs.c b/backends/x86_64_regs.c
index 84304407..a867b0d3 100644
--- a/backends/x86_64_regs.c
+++ b/backends/x86_64_regs.c
@@ -87,6 +87,9 @@ x86_64_register_info (Ebl *ebl __attribute__ ((unused)),
 
     case 6 ... 7:
       *type = DW_ATE_address;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     case 0 ... 5:
       name[0] = 'r';
diff --git a/configure.ac b/configure.ac
index 4ab8816a..3e91b367 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,6 +143,28 @@ if test "$ac_cv_visibility" = "yes"; then
 		  [Defined if __attribute__((visibility())) is supported])
 fi
 
+AC_CACHE_CHECK([whether gcc supports __attribute__((fallthrough))],
+	ac_cv_fallthrough, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+void
+foo (int a)
+{
+  switch(a)
+    {
+    case 1:
+        __attribute__((fallthrough));
+    default:
+        break;
+    }
+}])], ac_cv_fallthrough=yes, ac_cv_fallthrough=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_fallthrough" = "yes"; then
+	AC_DEFINE([HAVE_FALLTHROUGH], [1],
+		  [Defined if __attribute__((fallthrough)) is supported])
+fi
+
 AC_CACHE_CHECK([whether gcc supports __attribute__((gcc_struct))],
 	ac_cv_gcc_struct, [dnl
 save_CFLAGS="$CFLAGS"
diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c
index 831afbe2..740a637a 100644
--- a/libcpu/i386_disasm.c
+++ b/libcpu/i386_disasm.c
@@ -819,6 +819,9 @@ i386_disasm (Ebl *ebl __attribute__((unused)),
 			      ++param_start;
 			      break;
 			    }
+#ifdef HAVE_FALLTHROUGH
+			  __attribute__ ((fallthrough));
+#endif
 			  /* Fallthrough */
 			default:
 			  assert (! "INVALID not handled");
diff --git a/libdw/cfi.c b/libdw/cfi.c
index daa845f3..b8f51266 100644
--- a/libdw/cfi.c
+++ b/libdw/cfi.c
@@ -138,6 +138,9 @@ execute_cfi (Dwarf_CFI *cache,
 
 	case DW_CFA_advance_loc1:
 	  operand = *program++;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* Fallthrough */
 	case DW_CFA_advance_loc + 0 ... DW_CFA_advance_loc + CFI_PRIMARY_MAX:
 	advance_loc:
@@ -301,6 +304,9 @@ execute_cfi (Dwarf_CFI *cache,
 
 	case DW_CFA_restore_extended:
 	  get_uleb128 (operand, program, end);
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* Fallthrough */
 	case DW_CFA_restore + 0 ... DW_CFA_restore + CFI_PRIMARY_MAX:
 
diff --git a/libdw/dwarf_frame_register.c b/libdw/dwarf_frame_register.c
index 37e8e917..5e4d689a 100644
--- a/libdw/dwarf_frame_register.c
+++ b/libdw/dwarf_frame_register.c
@@ -62,6 +62,9 @@ dwarf_frame_register (Dwarf_Frame *fs, int regno, Dwarf_Op *ops_mem,
       /* Use the default rule for registers not yet mentioned in CFI.  */
       if (fs->cache->default_same_value)
 	goto same_value;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /*FALLTHROUGH*/
     case reg_undefined:
       /* The value is known to be unavailable.  */
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 6950a37b..b7149bc3 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -174,6 +174,9 @@ __libdwfl_elf_address_range (Elf *elf, GElf_Addr base, bool add_p_vaddr,
       /* An assigned base address is meaningless for these.  */
       base = 0;
       add_p_vaddr = true;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough. */
     case ET_DYN:
     default:;
diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
index 4dc9c432..2a67de0d 100644
--- a/libdwfl/frame_unwind.c
+++ b/libdwfl/frame_unwind.c
@@ -442,6 +442,9 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
 	    }
 	  if (val1 == 0)
 	    break;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHRU */
 	case DW_OP_skip:;
 	  Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c
index f80a1a57..75525802 100644
--- a/libebl/eblobjnote.c
+++ b/libebl/eblobjnote.c
@@ -223,6 +223,9 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
 		free (buf);
 	      break;
 	    }
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHROUGH */
 
 	default:
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index d83c0b3f..c0265b53 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -232,6 +232,9 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
 		      __libelf_seterrno (ELF_E_GROUP_NOT_REL);
 		      return -1;
 		    }
+#ifdef HAVE_FALLTHROUGH
+		  __attribute__ ((fallthrough));
+#endif
 		  /* FALLTHROUGH */
 		case SHT_SYMTAB_SHNDX:
 		  sh_entsize = elf_typesize (32, ELF_T_WORD, 1);
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index fb3a5b57..3f7be100 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -611,6 +611,9 @@ read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd,
 			     ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
 	return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
 			      parent);
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* FALLTHROUGH */
 
     default:
@@ -1126,6 +1129,9 @@ elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
 	  retval = NULL;
 	  break;
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* FALLTHROUGH */
 
     case ELF_C_READ:
diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c
index ab13ffb6..ce3f5fc8 100644
--- a/libelf/elf_cntl.c
+++ b/libelf/elf_cntl.c
@@ -62,6 +62,9 @@ elf_cntl (Elf *elf, Elf_Cmd cmd)
 	  result = -1;
 	  break;
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* FALLTHROUGH */
 
     case ELF_C_FDDONE:
diff --git a/src/addr2line.c b/src/addr2line.c
index ba414a74..2a10344a 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -618,6 +618,9 @@ handle_address (const char *string, Dwfl *dwfl)
 	case 1:
 	  addr = 0;
 	  j = i;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* Fallthrough */
 	case 2:
 	  if (string[j] != '\0')
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 8e0d5c55..8b159362 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -149,6 +149,9 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
 		    N_("Only one input file allowed together with '-o'"));
       /* We only use this for checking the number of arguments, we don't
 	 actually want to consume them.  */
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     default:
       return ARGP_ERR_UNKNOWN;
diff --git a/src/elflint.c b/src/elflint.c
index 51e53c23..1273f9aa 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -1764,6 +1764,9 @@ section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '
 	  if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI)
 	    /* Value is no pointer.  */
 	    break;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHROUGH */
 
 	case DT_AUXILIARY:
@@ -3993,6 +3996,9 @@ section [%2zu] '%s': merge flag set but entry size is zero\n"),
 	    case SHT_NOBITS:
 	      if (is_debuginfo)
 		break;
+#ifdef HAVE_FALLTHROUGH
+	      __attribute__ ((fallthrough));
+#endif
 	      /* Fallthrough */
 	    default:
 	      ERROR (gettext ("\
@@ -4137,6 +4143,9 @@ section [%2zu] '%s': ELF header says this is the section header string table but
 	    ERROR (gettext ("\
 section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
 		   cnt, section_name (ebl, cnt));
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHROUGH */
 	case SHT_SYMTAB:
 	  check_symtab (ebl, ehdr, shdr, cnt);
@@ -4336,6 +4345,9 @@ section [%2d] '%s': unknown core file note type %" PRIu32
 	    if (nhdr.n_namesz == sizeof "Linux"
 		&& !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux"))
 	      break;
+#ifdef HAVE_FALLTHROUGH
+	    __attribute__ ((fallthrough));
+#endif
 	    /* Fallthrough */
 	  default:
 	    if (shndx == 0)
diff --git a/src/objdump.c b/src/objdump.c
index 860cfac6..bd651cf2 100644
--- a/src/objdump.c
+++ b/src/objdump.c
@@ -223,6 +223,9 @@ parse_opt (int key, char *arg,
 	}
       /* We only use this for checking the number of arguments, we don't
 	 actually want to consume them.  */
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     default:
       return ARGP_ERR_UNKNOWN;
diff --git a/src/readelf.c b/src/readelf.c
index 6c49d305..ead6f628 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -6081,6 +6081,9 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 			dwarf_form_name (form), (uintmax_t) num);
 	      return DWARF_CB_OK;
 	    }
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* else fallthrough */
 
 	/* These cases always take a loclistptr and no constant. */
diff --git a/src/strings.c b/src/strings.c
index d214356c..ff6e8824 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -246,6 +246,9 @@ parse_opt (int key, char *arg,
 	case 'b':
 	case 'B':
 	  big_endian = true;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHROUGH */
 
 	case 'l':
diff --git a/tests/backtrace.c b/tests/backtrace.c
index 21abe8af..f19fd02d 100644
--- a/tests/backtrace.c
+++ b/tests/backtrace.c
@@ -127,6 +127,9 @@ callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
 	  assert (symname2 == NULL || strcmp (symname2, "jmp") != 0);
 	  break;
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* FALLTHRU */
     case 4:
       /* Some simple frame unwinders get this wrong and think sigusr2
diff --git a/tests/elfstrmerge.c b/tests/elfstrmerge.c
index 6924d0e9..4d471ddd 100644
--- a/tests/elfstrmerge.c
+++ b/tests/elfstrmerge.c
@@ -578,6 +578,9 @@ main (int argc, char **argv)
 	      break;
 
 	    case SHT_DYNAMIC:
+#ifdef HAVE_FALLTHROUGH
+	      __attribute__ ((fallthrough));
+#endif
 	      /* Fallthrough.  There are string indexes in here, but
 		 they (should) point to a allocated string table,
 		 which we don't alter.  */
-- 
2.14.3

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] Add fallthrough attributes
  2018-02-08 22:57 [PATCH] Add fallthrough attributes Joshua Watt
@ 2018-02-08 23:30 ` Joshua Watt
  2018-02-09  9:08   ` Ulf Hermann
  2018-02-09 16:27   ` [PATCH v3] Use fallthrough attribute Joshua Watt
  0 siblings, 2 replies; 10+ messages in thread
From: Joshua Watt @ 2018-02-08 23:30 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Joshua Watt

Adds the __attribute__ ((fallthrough)) annotation to all the places
where switch case fallthrough was occurring. This allows the
-Wimplicit-fallthrough warning to be used even after the source has been
pre-processed.

If the fallthrough attribute is supported, the -Wimplicit-fallthrough
warning is strengthened so that it *only* allows the attribute; comments
alone are insufficient.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 backends/aarch64_retval.c    |  3 +++
 backends/alpha_retval.c      |  6 ++++++
 backends/arm_regs.c          |  3 +++
 backends/arm_retval.c        |  3 +++
 backends/i386_regs.c         |  3 +++
 backends/i386_retval.c       |  6 ++++++
 backends/ia64_retval.c       |  3 +++
 backends/linux-core-note.c   |  3 +++
 backends/m68k_retval.c       |  6 ++++++
 backends/ppc64_retval.c      |  9 +++++++++
 backends/ppc_regs.c          |  3 +++
 backends/ppc_retval.c        |  6 ++++++
 backends/s390_retval.c       |  6 ++++++
 backends/sh_retval.c         |  3 +++
 backends/sparc_retval.c      |  3 +++
 backends/tilegx_retval.c     |  6 ++++++
 backends/x86_64_regs.c       |  3 +++
 backends/x86_64_retval.c     |  3 +++
 config/eu.am                 |  4 ++++
 configure.ac                 | 24 ++++++++++++++++++++++++
 libcpu/i386_disasm.c         |  3 +++
 libdw/cfi.c                  |  6 ++++++
 libdw/dwarf_frame_register.c |  3 +++
 libdwfl/dwfl_report_elf.c    |  3 +++
 libdwfl/frame_unwind.c       |  3 +++
 libebl/eblobjnote.c          |  3 +++
 libelf/elf32_updatenull.c    |  3 +++
 libelf/elf_begin.c           |  6 ++++++
 libelf/elf_cntl.c            |  3 +++
 src/addr2line.c              |  3 +++
 src/elfcompress.c            |  3 +++
 src/elflint.c                | 12 ++++++++++++
 src/objdump.c                |  3 +++
 src/readelf.c                | 12 ++++++++++++
 src/strings.c                |  3 +++
 tests/backtrace.c            |  3 +++
 tests/elfstrmerge.c          |  3 +++
 37 files changed, 181 insertions(+)

diff --git a/backends/aarch64_retval.c b/backends/aarch64_retval.c
index 68de307e..4b4d7c54 100644
--- a/backends/aarch64_retval.c
+++ b/backends/aarch64_retval.c
@@ -292,6 +292,9 @@ aarch64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  assert (count > 0);
 	  if (count <= 4)
 	    return pass_hfa (locp, base_size, count);
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* Fall through.  */
 
 	case 1:
diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c
index 53dbfa45..f19c5e4a 100644
--- a/backends/alpha_retval.c
+++ b/backends/alpha_retval.c
@@ -85,6 +85,9 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
@@ -131,6 +134,9 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  }
       }
 
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Else fall through.  */
 
     case DW_TAG_structure_type:
diff --git a/backends/arm_regs.c b/backends/arm_regs.c
index 21c5ad3a..1c1ee8fd 100644
--- a/backends/arm_regs.c
+++ b/backends/arm_regs.c
@@ -77,6 +77,9 @@ arm_register_info (Ebl *ebl __attribute__ ((unused)),
 
     case 16 + 0 ... 16 + 7:
       regno += 96 - 16;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
     case 96 + 0 ... 96 + 7:
       *setname = "FPA";
diff --git a/backends/arm_retval.c b/backends/arm_retval.c
index 7aced742..7fe6e6a9 100644
--- a/backends/arm_retval.c
+++ b/backends/arm_retval.c
@@ -82,6 +82,9 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
diff --git a/backends/i386_regs.c b/backends/i386_regs.c
index fd963a62..1488c1e7 100644
--- a/backends/i386_regs.c
+++ b/backends/i386_regs.c
@@ -92,6 +92,9 @@ i386_register_info (Ebl *ebl __attribute__ ((unused)),
     case 5:
     case 8:
       *type = DW_ATE_address;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     case 0 ... 3:
     case 6 ... 7:
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index 4aa646fe..e36e6c4a 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -85,6 +85,9 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
@@ -123,6 +126,9 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	if (size <= 8)
 	  return nloc_intregpair;
       }
+#ifdef HAVE_FALLTHROUGH
+    __attribute__ ((fallthrough));
+#endif
     /* Fallthrough */
 
     case DW_TAG_structure_type:
diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c
index dcd5f28d..25a02a36 100644
--- a/backends/ia64_retval.c
+++ b/backends/ia64_retval.c
@@ -260,6 +260,9 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
diff --git a/backends/linux-core-note.c b/backends/linux-core-note.c
index 08282ba4..f5714803 100644
--- a/backends/linux-core-note.c
+++ b/backends/linux-core-note.c
@@ -226,6 +226,9 @@ EBLHOOK(core_note) (const GElf_Nhdr *nhdr, const char *name,
       if (memcmp (name, "CORE", nhdr->n_namesz) == 0)
 	break;
       /* Buggy old Linux kernels didn't terminate "LINUX".  */
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through. */
 
     case sizeof "LINUX":
diff --git a/backends/m68k_retval.c b/backends/m68k_retval.c
index c68ed022..ebbcdf68 100644
--- a/backends/m68k_retval.c
+++ b/backends/m68k_retval.c
@@ -92,6 +92,9 @@ m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
@@ -135,6 +138,9 @@ m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	if (size <= 8)
 	  return nloc_intregpair;
       }
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c
index a2519839..da26969b 100644
--- a/backends/ppc64_retval.c
+++ b/backends/ppc64_retval.c
@@ -96,6 +96,9 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
@@ -141,6 +144,9 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  return nloc_intreg;
 	}
 
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Else fall through.  */
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
@@ -161,6 +167,9 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	    return nloc_vmxreg;
 	  }
       }
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_string_type:
diff --git a/backends/ppc_regs.c b/backends/ppc_regs.c
index c2d50118..0e0fed20 100644
--- a/backends/ppc_regs.c
+++ b/backends/ppc_regs.c
@@ -140,6 +140,9 @@ ppc_register_info (Ebl *ebl __attribute__ ((unused)),
     case 100:
       if (*bits == 32)
 	return stpcpy (name, "mq") + 1 - name;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     case 102 ... 107:
       name[0] = 's';
diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c
index b14a99f1..8f788d22 100644
--- a/backends/ppc_retval.c
+++ b/backends/ppc_retval.c
@@ -108,6 +108,9 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
@@ -172,6 +175,9 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	      return nloc_intregquad;
 	    }
       }
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_structure_type:
diff --git a/backends/s390_retval.c b/backends/s390_retval.c
index a927d46a..8b931299 100644
--- a/backends/s390_retval.c
+++ b/backends/s390_retval.c
@@ -87,6 +87,9 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
@@ -127,6 +130,9 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	    return size <= asize ? nloc_intreg : nloc_intregpair;
 	  }
       }
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_structure_type:
diff --git a/backends/sh_retval.c b/backends/sh_retval.c
index d44f2601..4a68977c 100644
--- a/backends/sh_retval.c
+++ b/backends/sh_retval.c
@@ -84,6 +84,9 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c
index e1b17753..02bde22b 100644
--- a/backends/sparc_retval.c
+++ b/backends/sparc_retval.c
@@ -91,6 +91,9 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
diff --git a/backends/tilegx_retval.c b/backends/tilegx_retval.c
index db81a20b..42db8332 100644
--- a/backends/tilegx_retval.c
+++ b/backends/tilegx_retval.c
@@ -79,6 +79,9 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
@@ -113,6 +116,9 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  return nloc_intreg;
 	}
 
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Else fall through.  */
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
diff --git a/backends/x86_64_regs.c b/backends/x86_64_regs.c
index 84304407..a867b0d3 100644
--- a/backends/x86_64_regs.c
+++ b/backends/x86_64_regs.c
@@ -87,6 +87,9 @@ x86_64_register_info (Ebl *ebl __attribute__ ((unused)),
 
     case 6 ... 7:
       *type = DW_ATE_address;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     case 0 ... 5:
       name[0] = 'r';
diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c
index b3799ae0..90d9472c 100644
--- a/backends/x86_64_retval.c
+++ b/backends/x86_64_retval.c
@@ -100,6 +100,9 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
 
     case DW_TAG_base_type:
diff --git a/config/eu.am b/config/eu.am
index 05c27f02..34a7a6df 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -62,7 +62,11 @@ NULL_DEREFERENCE_WARNING=
 endif
 
 if HAVE_IMPLICIT_FALLTHROUGH_WARNING
+if HAVE_FALLTHROUGH
+IMPLICIT_FALLTHROUGH_WARNING=-Wimplicit-fallthrough=5
+else
 IMPLICIT_FALLTHROUGH_WARNING=-Wimplicit-fallthrough
+endif
 else
 IMPLICIT_FALLTHROUGH_WARNING=
 endif
diff --git a/configure.ac b/configure.ac
index 4ab8816a..007fb0e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,6 +143,30 @@ if test "$ac_cv_visibility" = "yes"; then
 		  [Defined if __attribute__((visibility())) is supported])
 fi
 
+AC_CACHE_CHECK([whether gcc supports __attribute__((fallthrough))],
+	ac_cv_fallthrough, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+void
+foo (int a)
+{
+  switch(a)
+    {
+    case 1:
+        __attribute__((fallthrough));
+    default:
+        break;
+    }
+}])], ac_cv_fallthrough=yes, ac_cv_fallthrough=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_fallthrough" = "yes"; then
+	AC_DEFINE([HAVE_FALLTHROUGH], [1],
+		  [Defined if __attribute__((fallthrough)) is supported])
+fi
+AM_CONDITIONAL(HAVE_FALLTHROUGH,
+	       [test "$ac_cv_fallthrough" == "yes"])
+
 AC_CACHE_CHECK([whether gcc supports __attribute__((gcc_struct))],
 	ac_cv_gcc_struct, [dnl
 save_CFLAGS="$CFLAGS"
diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c
index 831afbe2..740a637a 100644
--- a/libcpu/i386_disasm.c
+++ b/libcpu/i386_disasm.c
@@ -819,6 +819,9 @@ i386_disasm (Ebl *ebl __attribute__((unused)),
 			      ++param_start;
 			      break;
 			    }
+#ifdef HAVE_FALLTHROUGH
+			  __attribute__ ((fallthrough));
+#endif
 			  /* Fallthrough */
 			default:
 			  assert (! "INVALID not handled");
diff --git a/libdw/cfi.c b/libdw/cfi.c
index daa845f3..b8f51266 100644
--- a/libdw/cfi.c
+++ b/libdw/cfi.c
@@ -138,6 +138,9 @@ execute_cfi (Dwarf_CFI *cache,
 
 	case DW_CFA_advance_loc1:
 	  operand = *program++;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* Fallthrough */
 	case DW_CFA_advance_loc + 0 ... DW_CFA_advance_loc + CFI_PRIMARY_MAX:
 	advance_loc:
@@ -301,6 +304,9 @@ execute_cfi (Dwarf_CFI *cache,
 
 	case DW_CFA_restore_extended:
 	  get_uleb128 (operand, program, end);
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* Fallthrough */
 	case DW_CFA_restore + 0 ... DW_CFA_restore + CFI_PRIMARY_MAX:
 
diff --git a/libdw/dwarf_frame_register.c b/libdw/dwarf_frame_register.c
index 37e8e917..5e4d689a 100644
--- a/libdw/dwarf_frame_register.c
+++ b/libdw/dwarf_frame_register.c
@@ -62,6 +62,9 @@ dwarf_frame_register (Dwarf_Frame *fs, int regno, Dwarf_Op *ops_mem,
       /* Use the default rule for registers not yet mentioned in CFI.  */
       if (fs->cache->default_same_value)
 	goto same_value;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /*FALLTHROUGH*/
     case reg_undefined:
       /* The value is known to be unavailable.  */
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 6950a37b..b7149bc3 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -174,6 +174,9 @@ __libdwfl_elf_address_range (Elf *elf, GElf_Addr base, bool add_p_vaddr,
       /* An assigned base address is meaningless for these.  */
       base = 0;
       add_p_vaddr = true;
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough. */
     case ET_DYN:
     default:;
diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
index 4dc9c432..2a67de0d 100644
--- a/libdwfl/frame_unwind.c
+++ b/libdwfl/frame_unwind.c
@@ -442,6 +442,9 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
 	    }
 	  if (val1 == 0)
 	    break;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHRU */
 	case DW_OP_skip:;
 	  Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c
index f80a1a57..75525802 100644
--- a/libebl/eblobjnote.c
+++ b/libebl/eblobjnote.c
@@ -223,6 +223,9 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
 		free (buf);
 	      break;
 	    }
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHROUGH */
 
 	default:
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index d83c0b3f..c0265b53 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -232,6 +232,9 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
 		      __libelf_seterrno (ELF_E_GROUP_NOT_REL);
 		      return -1;
 		    }
+#ifdef HAVE_FALLTHROUGH
+		  __attribute__ ((fallthrough));
+#endif
 		  /* FALLTHROUGH */
 		case SHT_SYMTAB_SHNDX:
 		  sh_entsize = elf_typesize (32, ELF_T_WORD, 1);
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index fb3a5b57..3f7be100 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -611,6 +611,9 @@ read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd,
 			     ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
 	return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
 			      parent);
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* FALLTHROUGH */
 
     default:
@@ -1126,6 +1129,9 @@ elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
 	  retval = NULL;
 	  break;
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* FALLTHROUGH */
 
     case ELF_C_READ:
diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c
index ab13ffb6..ce3f5fc8 100644
--- a/libelf/elf_cntl.c
+++ b/libelf/elf_cntl.c
@@ -62,6 +62,9 @@ elf_cntl (Elf *elf, Elf_Cmd cmd)
 	  result = -1;
 	  break;
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* FALLTHROUGH */
 
     case ELF_C_FDDONE:
diff --git a/src/addr2line.c b/src/addr2line.c
index ba414a74..2a10344a 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -618,6 +618,9 @@ handle_address (const char *string, Dwfl *dwfl)
 	case 1:
 	  addr = 0;
 	  j = i;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* Fallthrough */
 	case 2:
 	  if (string[j] != '\0')
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 8e0d5c55..8b159362 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -149,6 +149,9 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
 		    N_("Only one input file allowed together with '-o'"));
       /* We only use this for checking the number of arguments, we don't
 	 actually want to consume them.  */
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     default:
       return ARGP_ERR_UNKNOWN;
diff --git a/src/elflint.c b/src/elflint.c
index 51e53c23..1273f9aa 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -1764,6 +1764,9 @@ section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '
 	  if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI)
 	    /* Value is no pointer.  */
 	    break;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHROUGH */
 
 	case DT_AUXILIARY:
@@ -3993,6 +3996,9 @@ section [%2zu] '%s': merge flag set but entry size is zero\n"),
 	    case SHT_NOBITS:
 	      if (is_debuginfo)
 		break;
+#ifdef HAVE_FALLTHROUGH
+	      __attribute__ ((fallthrough));
+#endif
 	      /* Fallthrough */
 	    default:
 	      ERROR (gettext ("\
@@ -4137,6 +4143,9 @@ section [%2zu] '%s': ELF header says this is the section header string table but
 	    ERROR (gettext ("\
 section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
 		   cnt, section_name (ebl, cnt));
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHROUGH */
 	case SHT_SYMTAB:
 	  check_symtab (ebl, ehdr, shdr, cnt);
@@ -4336,6 +4345,9 @@ section [%2d] '%s': unknown core file note type %" PRIu32
 	    if (nhdr.n_namesz == sizeof "Linux"
 		&& !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux"))
 	      break;
+#ifdef HAVE_FALLTHROUGH
+	    __attribute__ ((fallthrough));
+#endif
 	    /* Fallthrough */
 	  default:
 	    if (shndx == 0)
diff --git a/src/objdump.c b/src/objdump.c
index 860cfac6..bd651cf2 100644
--- a/src/objdump.c
+++ b/src/objdump.c
@@ -223,6 +223,9 @@ parse_opt (int key, char *arg,
 	}
       /* We only use this for checking the number of arguments, we don't
 	 actually want to consume them.  */
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fallthrough */
     default:
       return ARGP_ERR_UNKNOWN;
diff --git a/src/readelf.c b/src/readelf.c
index 6c49d305..fd8a6443 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -480,6 +480,9 @@ parse_opt (int key, char *arg,
 	  print_string_sections = true;
 	  break;
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* Fall through.  */
     case 'x':
       add_dump_section (arg, false);
@@ -6081,6 +6084,9 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 			dwarf_form_name (form), (uintmax_t) num);
 	      return DWARF_CB_OK;
 	    }
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* else fallthrough */
 
 	/* These cases always take a loclistptr and no constant. */
@@ -6269,6 +6275,9 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	      print_block (block.length, block.data);
 	      break;
 	    }
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* Fall through.  */
 
 	case DW_AT_location:
@@ -9326,6 +9335,9 @@ handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
 		printf ("    %s\n", name);
 		break;
 	      }
+#ifdef HAVE_FALLTHROUGH
+	    __attribute__ ((fallthrough));
+#endif
 	    /* Fall through */
 	  case 'x':		/* hex */
 	  case 'p':		/* address */
diff --git a/src/strings.c b/src/strings.c
index d214356c..ff6e8824 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -246,6 +246,9 @@ parse_opt (int key, char *arg,
 	case 'b':
 	case 'B':
 	  big_endian = true;
+#ifdef HAVE_FALLTHROUGH
+	  __attribute__ ((fallthrough));
+#endif
 	  /* FALLTHROUGH */
 
 	case 'l':
diff --git a/tests/backtrace.c b/tests/backtrace.c
index 21abe8af..f19fd02d 100644
--- a/tests/backtrace.c
+++ b/tests/backtrace.c
@@ -127,6 +127,9 @@ callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
 	  assert (symname2 == NULL || strcmp (symname2, "jmp") != 0);
 	  break;
 	}
+#ifdef HAVE_FALLTHROUGH
+      __attribute__ ((fallthrough));
+#endif
       /* FALLTHRU */
     case 4:
       /* Some simple frame unwinders get this wrong and think sigusr2
diff --git a/tests/elfstrmerge.c b/tests/elfstrmerge.c
index 6924d0e9..4d471ddd 100644
--- a/tests/elfstrmerge.c
+++ b/tests/elfstrmerge.c
@@ -578,6 +578,9 @@ main (int argc, char **argv)
 	      break;
 
 	    case SHT_DYNAMIC:
+#ifdef HAVE_FALLTHROUGH
+	      __attribute__ ((fallthrough));
+#endif
 	      /* Fallthrough.  There are string indexes in here, but
 		 they (should) point to a allocated string table,
 		 which we don't alter.  */
-- 
2.14.3

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] Add fallthrough attributes
  2018-02-08 23:30 ` [PATCH v2] " Joshua Watt
@ 2018-02-09  9:08   ` Ulf Hermann
  2018-02-09  9:27     ` Mark Wielaard
  2018-02-09 16:27   ` [PATCH v3] Use fallthrough attribute Joshua Watt
  1 sibling, 1 reply; 10+ messages in thread
From: Ulf Hermann @ 2018-02-09  9:08 UTC (permalink / raw)
  To: elfutils-devel, jpewhacker

> [...]
> +#ifdef HAVE_FALLTHROUGH
> +      __attribute__ ((fallthrough));
> +#endif
> [...]

I would like to see this stanza wrapped in a macro, so that we only have one "#ifdef HAVE_FALLTHROUGH" in the code, not another one in every place we want to fall through. See the "internal_function" macro defined in lib/eu-config.h for a similar case.

Ulf

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] Add fallthrough attributes
  2018-02-09  9:08   ` Ulf Hermann
@ 2018-02-09  9:27     ` Mark Wielaard
  2018-02-09 14:19       ` Joshua Watt
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Wielaard @ 2018-02-09  9:27 UTC (permalink / raw)
  To: Ulf Hermann; +Cc: elfutils-devel, jpewhacker

On Fri, Feb 09, 2018 at 10:08:09AM +0100, Ulf Hermann wrote:
> > [...]
> > +#ifdef HAVE_FALLTHROUGH
> > +      __attribute__ ((fallthrough));
> > +#endif
> > [...]
> 
> I would like to see this stanza wrapped in a macro, so that we only have one "#ifdef HAVE_FALLTHROUGH" in the code, not another one in every place we want to fall through. See the "internal_function" macro defined in lib/eu-config.h for a similar case.

Agreed. Having 4 lines for a fallthrough instead of 1 is really too
much. Also could you explain a bit more why you would like this?
The advantage of the comments really is that they should work
everywhere.

If the comment really doesn't work in your situation maybe we could do
like gnulib did:
http://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=11fdf80b21f2b40a10687b9a3d16c852b19d512c

The idea is that those versions of GCC that support
-Wimplicit-fallthrough also have support for the __attribute__
((fallthrough)) statement. So they can always be used together.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] Add fallthrough attributes
  2018-02-09  9:27     ` Mark Wielaard
@ 2018-02-09 14:19       ` Joshua Watt
  0 siblings, 0 replies; 10+ messages in thread
From: Joshua Watt @ 2018-02-09 14:19 UTC (permalink / raw)
  To: Mark Wielaard, Ulf Hermann; +Cc: elfutils-devel

On Fri, 2018-02-09 at 10:26 +0100, Mark Wielaard wrote:
> On Fri, Feb 09, 2018 at 10:08:09AM +0100, Ulf Hermann wrote:
> > > [...]
> > > +#ifdef HAVE_FALLTHROUGH
> > > +      __attribute__ ((fallthrough));
> > > +#endif
> > > [...]
> > 
> > I would like to see this stanza wrapped in a macro, so that we only
> > have one "#ifdef HAVE_FALLTHROUGH" in the code, not another one in
> > every place we want to fall through. See the "internal_function"
> > macro defined in lib/eu-config.h for a similar case.
> 
> Agreed. Having 4 lines for a fallthrough instead of 1 is really too
> much. Also could you explain a bit more why you would like this?
> The advantage of the comments really is that they should work
> everywhere.

I'm attempting to build Yocto using Icecream to do distributed
compiling. Icecream pre-processes the file before sending it to the
remote compiling node, thus removing the comments and triggering the
error.

There is a fix in Icecream to allow it to not remove comments when pre-
processing, but it will be a while before that change (which hasn't
been released yet) trickles down to all the end Icecream users. I
figured making the change here wouldn't hurt in the meantime.

> 
> If the comment really doesn't work in your situation maybe we could
> do
> like gnulib did:
> http://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=11fdf80b21f2b4
> 0a10687b9a3d16c852b19d512c
> 
> The idea is that those versions of GCC that support
> -Wimplicit-fallthrough also have support for the __attribute__
> ((fallthrough)) statement. So they can always be used together.

Yes, that is cleaner and makes more sense. I will change my patch to do
that.

Thanks,
Joshua Watt

> 
> Cheers,
> 
> Mark

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v3] Use fallthrough attribute
  2018-02-08 23:30 ` [PATCH v2] " Joshua Watt
  2018-02-09  9:08   ` Ulf Hermann
@ 2018-02-09 16:27   ` Joshua Watt
  2018-02-10  2:26     ` Mark Wielaard
  1 sibling, 1 reply; 10+ messages in thread
From: Joshua Watt @ 2018-02-09 16:27 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Joshua Watt

Use __attribute__ ((fallthrough)) to indicate switch case fall through
instead of a comment. This ensure that the fallthrough warning is not
triggered even if the file is pre-processed (hence stripping the
comments) before it is compiled.

The actual fallback implementation is hidden behind a FALLBACK macro in
case the compiler doesn't support it.

Finally, the -Wimplict-fallthrough warning was upgraded to only allow
the attribute to satisfy it; a comment alone is no longer sufficient.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 backends/aarch64_retval.c    | 2 +-
 backends/alpha_retval.c      | 4 ++--
 backends/arm_regs.c          | 2 +-
 backends/arm_retval.c        | 2 +-
 backends/i386_regs.c         | 2 +-
 backends/i386_retval.c       | 4 ++--
 backends/ia64_retval.c       | 2 +-
 backends/linux-core-note.c   | 2 +-
 backends/m68k_retval.c       | 4 ++--
 backends/ppc64_retval.c      | 6 +++---
 backends/ppc_regs.c          | 2 +-
 backends/ppc_retval.c        | 4 ++--
 backends/s390_retval.c       | 4 ++--
 backends/sh_retval.c         | 2 +-
 backends/sparc_retval.c      | 2 +-
 backends/tilegx_retval.c     | 4 ++--
 backends/x86_64_regs.c       | 2 +-
 backends/x86_64_retval.c     | 2 +-
 config/eu.am                 | 4 +++-
 configure.ac                 | 6 ++++++
 lib/eu-config.h              | 7 +++++++
 libcpu/i386_disasm.c         | 2 +-
 libdw/cfi.c                  | 4 ++--
 libdw/dwarf_frame_register.c | 2 +-
 libdwfl/dwfl_report_elf.c    | 2 +-
 libdwfl/frame_unwind.c       | 2 +-
 libebl/eblobjnote.c          | 2 +-
 libelf/elf32_updatenull.c    | 2 +-
 libelf/elf_begin.c           | 4 ++--
 libelf/elf_cntl.c            | 2 +-
 src/addr2line.c              | 2 +-
 src/elfcompress.c            | 2 +-
 src/elflint.c                | 8 ++++----
 src/objdump.c                | 2 +-
 src/readelf.c                | 8 ++++----
 src/strings.c                | 2 +-
 tests/backtrace.c            | 2 +-
 tests/elfstrmerge.c          | 3 ++-
 38 files changed, 68 insertions(+), 52 deletions(-)

diff --git a/backends/aarch64_retval.c b/backends/aarch64_retval.c
index 68de307e..1308340b 100644
--- a/backends/aarch64_retval.c
+++ b/backends/aarch64_retval.c
@@ -292,7 +292,7 @@ aarch64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  assert (count > 0);
 	  if (count <= 4)
 	    return pass_hfa (locp, base_size, count);
-	  /* Fall through.  */
+	  FALLTHROUGH;
 
 	case 1:
 	  /* Not a HFA.  */
diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c
index 53dbfa45..d9bae3bc 100644
--- a/backends/alpha_retval.c
+++ b/backends/alpha_retval.c
@@ -85,7 +85,7 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
@@ -131,7 +131,7 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  }
       }
 
-      /* Else fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
diff --git a/backends/arm_regs.c b/backends/arm_regs.c
index 21c5ad3a..a46a4c99 100644
--- a/backends/arm_regs.c
+++ b/backends/arm_regs.c
@@ -77,7 +77,7 @@ arm_register_info (Ebl *ebl __attribute__ ((unused)),
 
     case 16 + 0 ... 16 + 7:
       regno += 96 - 16;
-      /* Fall through.  */
+      FALLTHROUGH;
     case 96 + 0 ... 96 + 7:
       *setname = "FPA";
       *type = DW_ATE_float;
diff --git a/backends/arm_retval.c b/backends/arm_retval.c
index 7aced742..1c28f016 100644
--- a/backends/arm_retval.c
+++ b/backends/arm_retval.c
@@ -82,7 +82,7 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
diff --git a/backends/i386_regs.c b/backends/i386_regs.c
index fd963a62..7ec93bb9 100644
--- a/backends/i386_regs.c
+++ b/backends/i386_regs.c
@@ -92,7 +92,7 @@ i386_register_info (Ebl *ebl __attribute__ ((unused)),
     case 5:
     case 8:
       *type = DW_ATE_address;
-      /* Fallthrough */
+      FALLTHROUGH;
     case 0 ... 3:
     case 6 ... 7:
       name[0] = 'e';
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index 4aa646fe..32fec728 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -85,7 +85,7 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
@@ -123,7 +123,7 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	if (size <= 8)
 	  return nloc_intregpair;
       }
-    /* Fallthrough */
+    FALLTHROUGH;
 
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c
index dcd5f28d..03ea4d89 100644
--- a/backends/ia64_retval.c
+++ b/backends/ia64_retval.c
@@ -260,7 +260,7 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
diff --git a/backends/linux-core-note.c b/backends/linux-core-note.c
index 08282ba4..9faae4c3 100644
--- a/backends/linux-core-note.c
+++ b/backends/linux-core-note.c
@@ -226,7 +226,7 @@ EBLHOOK(core_note) (const GElf_Nhdr *nhdr, const char *name,
       if (memcmp (name, "CORE", nhdr->n_namesz) == 0)
 	break;
       /* Buggy old Linux kernels didn't terminate "LINUX".  */
-      /* Fall through. */
+      FALLTHROUGH;
 
     case sizeof "LINUX":
       if (memcmp (name, "LINUX", nhdr->n_namesz) == 0)
diff --git a/backends/m68k_retval.c b/backends/m68k_retval.c
index c68ed022..a653ba3a 100644
--- a/backends/m68k_retval.c
+++ b/backends/m68k_retval.c
@@ -92,7 +92,7 @@ m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
@@ -135,7 +135,7 @@ m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	if (size <= 8)
 	  return nloc_intregpair;
       }
-      /* Fallthrough */
+      FALLTHROUGH;
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
     case DW_TAG_union_type:
diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c
index a2519839..eb1c11ec 100644
--- a/backends/ppc64_retval.c
+++ b/backends/ppc64_retval.c
@@ -96,7 +96,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
@@ -141,7 +141,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  return nloc_intreg;
 	}
 
-      /* Else fall through.  */
+      FALLTHROUGH;
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
     case DW_TAG_union_type:
@@ -161,7 +161,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	    return nloc_vmxreg;
 	  }
       }
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_string_type:
       if (dwarf_aggregate_size (typedie, &size) == 0 && size <= 8)
diff --git a/backends/ppc_regs.c b/backends/ppc_regs.c
index c2d50118..43d2534f 100644
--- a/backends/ppc_regs.c
+++ b/backends/ppc_regs.c
@@ -140,7 +140,7 @@ ppc_register_info (Ebl *ebl __attribute__ ((unused)),
     case 100:
       if (*bits == 32)
 	return stpcpy (name, "mq") + 1 - name;
-      /* Fallthrough */
+      FALLTHROUGH;
     case 102 ... 107:
       name[0] = 's';
       name[1] = 'p';
diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c
index b14a99f1..39b42da1 100644
--- a/backends/ppc_retval.c
+++ b/backends/ppc_retval.c
@@ -108,7 +108,7 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
@@ -172,7 +172,7 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	      return nloc_intregquad;
 	    }
       }
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
diff --git a/backends/s390_retval.c b/backends/s390_retval.c
index a927d46a..2043f985 100644
--- a/backends/s390_retval.c
+++ b/backends/s390_retval.c
@@ -87,7 +87,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
@@ -127,7 +127,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	    return size <= asize ? nloc_intreg : nloc_intregpair;
 	  }
       }
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
diff --git a/backends/sh_retval.c b/backends/sh_retval.c
index d44f2601..33d7d964 100644
--- a/backends/sh_retval.c
+++ b/backends/sh_retval.c
@@ -84,7 +84,7 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c
index e1b17753..fb81cdce 100644
--- a/backends/sparc_retval.c
+++ b/backends/sparc_retval.c
@@ -91,7 +91,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
diff --git a/backends/tilegx_retval.c b/backends/tilegx_retval.c
index db81a20b..7f7d24b0 100644
--- a/backends/tilegx_retval.c
+++ b/backends/tilegx_retval.c
@@ -79,7 +79,7 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
@@ -113,7 +113,7 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  return nloc_intreg;
 	}
 
-      /* Else fall through.  */
+      FALLTHROUGH;
     case DW_TAG_structure_type:
     case DW_TAG_class_type:
     case DW_TAG_union_type:
diff --git a/backends/x86_64_regs.c b/backends/x86_64_regs.c
index 84304407..ef987daf 100644
--- a/backends/x86_64_regs.c
+++ b/backends/x86_64_regs.c
@@ -87,7 +87,7 @@ x86_64_register_info (Ebl *ebl __attribute__ ((unused)),
 
     case 6 ... 7:
       *type = DW_ATE_address;
-      /* Fallthrough */
+      FALLTHROUGH;
     case 0 ... 5:
       name[0] = 'r';
       name[1] = baseregs[regno][0];
diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c
index b3799ae0..f9114cb1 100644
--- a/backends/x86_64_retval.c
+++ b/backends/x86_64_retval.c
@@ -100,7 +100,7 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	  typedie = dwarf_formref_die (attr, &die_mem);
 	  tag = DWARF_TAG_OR_RETURN (typedie);
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
 
     case DW_TAG_base_type:
     case DW_TAG_enumeration_type:
diff --git a/config/eu.am b/config/eu.am
index 05c27f02..c2cc349c 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -62,7 +62,9 @@ NULL_DEREFERENCE_WARNING=
 endif
 
 if HAVE_IMPLICIT_FALLTHROUGH_WARNING
-IMPLICIT_FALLTHROUGH_WARNING=-Wimplicit-fallthrough
+# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the
+# warning
+IMPLICIT_FALLTHROUGH_WARNING=-Wimplicit-fallthrough=5
 else
 IMPLICIT_FALLTHROUGH_WARNING=
 endif
diff --git a/configure.ac b/configure.ac
index 4ab8816a..4cdb12af 100644
--- a/configure.ac
+++ b/configure.ac
@@ -456,6 +456,12 @@ CFLAGS="$old_CFLAGS"])
 AM_CONDITIONAL(HAVE_IMPLICIT_FALLTHROUGH_WARNING,
 	       [test "x$ac_cv_implicit_fallthrough" != "xno"])
 
+# Assume the fallthrough attribute is supported if -Wimplict-fallthrough is supported
+if test "$ac_cv_implicit_fallthrough" = "yes"; then
+	AC_DEFINE([HAVE_FALLTHROUGH], [1],
+		  [Defined if __attribute__((fallthrough)) is supported])
+fi
+
 dnl Check if we have argp available from our libc
 AC_LINK_IFELSE(
 	[AC_LANG_PROGRAM(
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 135803e7..84b22d7c 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -198,5 +198,12 @@ asm (".section predict_data, \"aw\"; .previous\n"
 # define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SYMBOL_VERSIONING"
 #endif
 
+#ifndef FALLTHROUGH
+# ifdef HAVE_FALLTHROUGH
+#  define FALLTHROUGH __attribute__ ((fallthrough))
+# else
+#  define FALLTHROUGH ((void) 0)
+# endif
+#endif
 
 #endif	/* eu-config.h */
diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c
index 831afbe2..a7e03f95 100644
--- a/libcpu/i386_disasm.c
+++ b/libcpu/i386_disasm.c
@@ -819,7 +819,7 @@ i386_disasm (Ebl *ebl __attribute__((unused)),
 			      ++param_start;
 			      break;
 			    }
-			  /* Fallthrough */
+			  FALLTHROUGH;
 			default:
 			  assert (! "INVALID not handled");
 			}
diff --git a/libdw/cfi.c b/libdw/cfi.c
index daa845f3..341e055b 100644
--- a/libdw/cfi.c
+++ b/libdw/cfi.c
@@ -138,7 +138,7 @@ execute_cfi (Dwarf_CFI *cache,
 
 	case DW_CFA_advance_loc1:
 	  operand = *program++;
-	  /* Fallthrough */
+	  FALLTHROUGH;
 	case DW_CFA_advance_loc + 0 ... DW_CFA_advance_loc + CFI_PRIMARY_MAX:
 	advance_loc:
 	  loc += operand * cie->code_alignment_factor;
@@ -301,7 +301,7 @@ execute_cfi (Dwarf_CFI *cache,
 
 	case DW_CFA_restore_extended:
 	  get_uleb128 (operand, program, end);
-	  /* Fallthrough */
+	  FALLTHROUGH;
 	case DW_CFA_restore + 0 ... DW_CFA_restore + CFI_PRIMARY_MAX:
 
 	  if (unlikely (abi_cfi) && likely (opcode == DW_CFA_restore))
diff --git a/libdw/dwarf_frame_register.c b/libdw/dwarf_frame_register.c
index 37e8e917..d0159fb8 100644
--- a/libdw/dwarf_frame_register.c
+++ b/libdw/dwarf_frame_register.c
@@ -62,7 +62,7 @@ dwarf_frame_register (Dwarf_Frame *fs, int regno, Dwarf_Op *ops_mem,
       /* Use the default rule for registers not yet mentioned in CFI.  */
       if (fs->cache->default_same_value)
 	goto same_value;
-      /*FALLTHROUGH*/
+      FALLTHROUGH;
     case reg_undefined:
       /* The value is known to be unavailable.  */
       break;
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 6950a37b..3fc9384a 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -174,7 +174,7 @@ __libdwfl_elf_address_range (Elf *elf, GElf_Addr base, bool add_p_vaddr,
       /* An assigned base address is meaningless for these.  */
       base = 0;
       add_p_vaddr = true;
-      /* Fallthrough. */
+      FALLTHROUGH;
     case ET_DYN:
     default:;
       size_t phnum;
diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
index 4dc9c432..eaea495f 100644
--- a/libdwfl/frame_unwind.c
+++ b/libdwfl/frame_unwind.c
@@ -442,7 +442,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
 	    }
 	  if (val1 == 0)
 	    break;
-	  /* FALLTHRU */
+	  FALLTHROUGH;
 	case DW_OP_skip:;
 	  Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
 	  const Dwarf_Op *found = bsearch ((void *) (uintptr_t) offset, ops, nops,
diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c
index f80a1a57..ca4f155d 100644
--- a/libebl/eblobjnote.c
+++ b/libebl/eblobjnote.c
@@ -223,7 +223,7 @@ ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
 		free (buf);
 	      break;
 	    }
-	  /* FALLTHROUGH */
+	  FALLTHROUGH;
 
 	default:
 	  /* Unknown type.  */
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index d83c0b3f..3e9ef61b 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -232,7 +232,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
 		      __libelf_seterrno (ELF_E_GROUP_NOT_REL);
 		      return -1;
 		    }
-		  /* FALLTHROUGH */
+		  FALLTHROUGH;
 		case SHT_SYMTAB_SHNDX:
 		  sh_entsize = elf_typesize (32, ELF_T_WORD, 1);
 		  break;
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index fb3a5b57..b20ab4f3 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -611,7 +611,7 @@ read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd,
 			     ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
 	return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
 			      parent);
-      /* FALLTHROUGH */
+      FALLTHROUGH;
 
     default:
       break;
@@ -1126,7 +1126,7 @@ elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
 	  retval = NULL;
 	  break;
 	}
-      /* FALLTHROUGH */
+      FALLTHROUGH;
 
     case ELF_C_READ:
     case ELF_C_READ_MMAP:
diff --git a/libelf/elf_cntl.c b/libelf/elf_cntl.c
index ab13ffb6..fd681789 100644
--- a/libelf/elf_cntl.c
+++ b/libelf/elf_cntl.c
@@ -62,7 +62,7 @@ elf_cntl (Elf *elf, Elf_Cmd cmd)
 	  result = -1;
 	  break;
 	}
-      /* FALLTHROUGH */
+      FALLTHROUGH;
 
     case ELF_C_FDDONE:
       /* Mark the file descriptor as not usable.  */
diff --git a/src/addr2line.c b/src/addr2line.c
index ba414a74..444ee52c 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -618,7 +618,7 @@ handle_address (const char *string, Dwfl *dwfl)
 	case 1:
 	  addr = 0;
 	  j = i;
-	  /* Fallthrough */
+	  FALLTHROUGH;
 	case 2:
 	  if (string[j] != '\0')
 	    break;
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 8e0d5c55..25378a45 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -149,7 +149,7 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
 		    N_("Only one input file allowed together with '-o'"));
       /* We only use this for checking the number of arguments, we don't
 	 actually want to consume them.  */
-      /* Fallthrough */
+      FALLTHROUGH;
     default:
       return ARGP_ERR_UNKNOWN;
     }
diff --git a/src/elflint.c b/src/elflint.c
index 51e53c23..df1b3a03 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -1764,7 +1764,7 @@ section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '
 	  if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI)
 	    /* Value is no pointer.  */
 	    break;
-	  /* FALLTHROUGH */
+	  FALLTHROUGH;
 
 	case DT_AUXILIARY:
 	case DT_FILTER:
@@ -3993,7 +3993,7 @@ section [%2zu] '%s': merge flag set but entry size is zero\n"),
 	    case SHT_NOBITS:
 	      if (is_debuginfo)
 		break;
-	      /* Fallthrough */
+	      FALLTHROUGH;
 	    default:
 	      ERROR (gettext ("\
 section [%2zu] '%s' has unexpected type %d for an executable section\n"),
@@ -4137,7 +4137,7 @@ section [%2zu] '%s': ELF header says this is the section header string table but
 	    ERROR (gettext ("\
 section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
 		   cnt, section_name (ebl, cnt));
-	  /* FALLTHROUGH */
+	  FALLTHROUGH;
 	case SHT_SYMTAB:
 	  check_symtab (ebl, ehdr, shdr, cnt);
 	  break;
@@ -4336,7 +4336,7 @@ section [%2d] '%s': unknown core file note type %" PRIu32
 	    if (nhdr.n_namesz == sizeof "Linux"
 		&& !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux"))
 	      break;
-	    /* Fallthrough */
+	    FALLTHROUGH;
 	  default:
 	    if (shndx == 0)
 	      ERROR (gettext ("\
diff --git a/src/objdump.c b/src/objdump.c
index 860cfac6..0dd9a6aa 100644
--- a/src/objdump.c
+++ b/src/objdump.c
@@ -223,7 +223,7 @@ parse_opt (int key, char *arg,
 	}
       /* We only use this for checking the number of arguments, we don't
 	 actually want to consume them.  */
-      /* Fallthrough */
+      FALLTHROUGH;
     default:
       return ARGP_ERR_UNKNOWN;
     }
diff --git a/src/readelf.c b/src/readelf.c
index 6c49d305..d606cf5a 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -480,7 +480,7 @@ parse_opt (int key, char *arg,
 	  print_string_sections = true;
 	  break;
 	}
-      /* Fall through.  */
+      FALLTHROUGH;
     case 'x':
       add_dump_section (arg, false);
       any_control_option = true;
@@ -6081,7 +6081,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 			dwarf_form_name (form), (uintmax_t) num);
 	      return DWARF_CB_OK;
 	    }
-	  /* else fallthrough */
+	  FALLTHROUGH;
 
 	/* These cases always take a loclistptr and no constant. */
 	case DW_AT_location:
@@ -6269,7 +6269,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	      print_block (block.length, block.data);
 	      break;
 	    }
-	  /* Fall through.  */
+	  FALLTHROUGH;
 
 	case DW_AT_location:
 	case DW_AT_data_location:
@@ -9326,7 +9326,7 @@ handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
 		printf ("    %s\n", name);
 		break;
 	      }
-	    /* Fall through */
+	    FALLTHROUGH;
 	  case 'x':		/* hex */
 	  case 'p':		/* address */
 	  case 's':		/* address of string */
diff --git a/src/strings.c b/src/strings.c
index d214356c..03d0f133 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -246,7 +246,7 @@ parse_opt (int key, char *arg,
 	case 'b':
 	case 'B':
 	  big_endian = true;
-	  /* FALLTHROUGH */
+	  FALLTHROUGH;
 
 	case 'l':
 	case 'L':
diff --git a/tests/backtrace.c b/tests/backtrace.c
index 21abe8af..f5dd761f 100644
--- a/tests/backtrace.c
+++ b/tests/backtrace.c
@@ -127,7 +127,7 @@ callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
 	  assert (symname2 == NULL || strcmp (symname2, "jmp") != 0);
 	  break;
 	}
-      /* FALLTHRU */
+      FALLTHROUGH;
     case 4:
       /* Some simple frame unwinders get this wrong and think sigusr2
 	 is calling itself again. Allow it and just pretend there is
diff --git a/tests/elfstrmerge.c b/tests/elfstrmerge.c
index 6924d0e9..3bb90c42 100644
--- a/tests/elfstrmerge.c
+++ b/tests/elfstrmerge.c
@@ -578,7 +578,8 @@ main (int argc, char **argv)
 	      break;
 
 	    case SHT_DYNAMIC:
-	      /* Fallthrough.  There are string indexes in here, but
+	      FALLTHROUGH;
+	      /* There are string indexes in here, but
 		 they (should) point to a allocated string table,
 		 which we don't alter.  */
 	    default:
-- 
2.14.3

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3] Use fallthrough attribute
  2018-02-09 16:27   ` [PATCH v3] Use fallthrough attribute Joshua Watt
@ 2018-02-10  2:26     ` Mark Wielaard
  2018-02-10  3:36       ` Frank Ch. Eigler
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Wielaard @ 2018-02-10  2:26 UTC (permalink / raw)
  To: Joshua Watt; +Cc: elfutils-devel

Hi Joshua,

On Fri, Feb 09, 2018 at 10:27:18AM -0600, Joshua Watt wrote:
> Use __attribute__ ((fallthrough)) to indicate switch case fall through
> instead of a comment. This ensure that the fallthrough warning is not
> triggered even if the file is pre-processed (hence stripping the
> comments) before it is compiled.
> 
> The actual fallback implementation is hidden behind a FALLBACK macro in
> case the compiler doesn't support it.
> 
> Finally, the -Wimplict-fallthrough warning was upgraded to only allow
> the attribute to satisfy it; a comment alone is no longer sufficient.

Thanks, this look good.
I added ChangeLog entries and pushed it to master.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3] Use fallthrough attribute
  2018-02-10  2:26     ` Mark Wielaard
@ 2018-02-10  3:36       ` Frank Ch. Eigler
  2018-02-10 12:39         ` ChangeLog entries (Was: [PATCH v3] Use fallthrough attribute) Mark Wielaard
  0 siblings, 1 reply; 10+ messages in thread
From: Frank Ch. Eigler @ 2018-02-10  3:36 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: elfutils-devel

Hi -

On Sat, Feb 10, 2018 at 03:26:43AM +0100, Mark Wielaard wrote:

> I added ChangeLog entries and pushed it to master.

What's a ChangeLog entry?  :-)

- FChE

^ permalink raw reply	[flat|nested] 10+ messages in thread

* ChangeLog entries (Was: [PATCH v3] Use fallthrough attribute)
  2018-02-10  3:36       ` Frank Ch. Eigler
@ 2018-02-10 12:39         ` Mark Wielaard
  2018-02-12  9:34           ` Ulf Hermann
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Wielaard @ 2018-02-10 12:39 UTC (permalink / raw)
  To: Frank Ch. Eigler; +Cc: elfutils-devel

On Fri, 2018-02-09 at 22:36 -0500, Frank Ch. Eigler wrote:
> On Sat, Feb 10, 2018 at 03:26:43AM +0100, Mark Wielaard wrote:
> 
> > I added ChangeLog entries and pushed it to master.
> 
> What's a ChangeLog entry?  :-)

Yeah, yeah, I know. I am the last one to care.
Really, it helps me review code (even my own - actually writing them
makes me happy - o, right I did that!). If only to know a change is
really intended to be there.

To me the problem with dropping them is that there is no description
anymore what changed. The commit message normally describes why
something changed, not how. You of course have the diff to see what
changed, but not in a summary form. And I really like to have a summary
to cross check that what changed was intended to change.

For people that don't like them, what exactly is it about them that you
don't like? And what would you suggest as replacement?

Thanks,

Mark

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: ChangeLog entries (Was: [PATCH v3] Use fallthrough attribute)
  2018-02-10 12:39         ` ChangeLog entries (Was: [PATCH v3] Use fallthrough attribute) Mark Wielaard
@ 2018-02-12  9:34           ` Ulf Hermann
  0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hermann @ 2018-02-12  9:34 UTC (permalink / raw)
  To: elfutils-devel

> For people that don't like them, what exactly is it about them that you
> don't like? And what would you suggest as replacement?

I don't like them because they constantly give me problems when merging and for me at least they only repeat, in a less convenient form, what the commit message already states. I like to put the "what" part in the commit message, too. And there I can write paragraphs of text that describe changes that span multiple directories. In ChangeLog I have to restrict myself to only that directory, which often doesn't make sense. So, the ChangeLog entries often are glorified "change line X in file Y", which doesn't really tell you what's going on. Also, the format encourages you to keep the ChangeLog entries overly short, which, especially in combination with the other problems, IMO makes them mostly unreadable.

So, as a replacement: Write more verbose commit messages.

br,
Ulf

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-02-12  9:34 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-08 22:57 [PATCH] Add fallthrough attributes Joshua Watt
2018-02-08 23:30 ` [PATCH v2] " Joshua Watt
2018-02-09  9:08   ` Ulf Hermann
2018-02-09  9:27     ` Mark Wielaard
2018-02-09 14:19       ` Joshua Watt
2018-02-09 16:27   ` [PATCH v3] Use fallthrough attribute Joshua Watt
2018-02-10  2:26     ` Mark Wielaard
2018-02-10  3:36       ` Frank Ch. Eigler
2018-02-10 12:39         ` ChangeLog entries (Was: [PATCH v3] Use fallthrough attribute) Mark Wielaard
2018-02-12  9:34           ` Ulf Hermann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).