My guess is that the preprocessor expands __has_attribute (__fallthrough__) to 
1 but the attribute does not actually work. Is that the case?

has_attribute is indeed 1.

Looking at the Clang 3.4 source code, I don't see how that could be, as 
clang-3.4/include/clang/Basic/Attr.td lists the clang::fallthrough attribute 
for CXX11 but not for C. Possibly I'm misunderstanding that file, but just to 
check, does your preprocessor version match your compiler version? or are you 
compiling with clang++?

No, this is the genuine C compiler of that version.  As provided by Ubuntu.

It turns out that __has_attribute is subtly broken in clang 3.4 and earlier; this is documented in the clang 3.5 release notes. I installed into Gnulib the attached simple workaround to attempt to work around the problem.

This doesn't solve the more-important issue that we have with older clang, but one thing at a time.
From a0ddbbd97816c52141c85deb4105a749703ce0ba Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Thu, 21 Jan 2021 13:40:16 -0800
Subject: [PATCH] Port FALLTHROUGH to clang 3.4 and earlier

Problem reported by Akim Demaille in:
https://lists.gnu.org/r/bug-gnulib/2021-01/msg00241.html
* lib/cdefs.h (__glibc_has_attribute):
* m4/gnulib-common.m4 (gl_COMMON_BODY):
Do not trust __has_attribute in clang 3.4 and earlier, as
<https://releases.llvm.org/3.5.0/tools/clang/docs/ReleaseNotes.html>
says that __has_attribute is unreliable in these old versions.
---
 ChangeLog           | 11 +++++++++++
 lib/cdefs.h         |  4 +++-
 m4/gnulib-common.m4 |  4 +++-
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8c5a0a757..8fa2e1535 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2021-01-21  Paul Eggert  <egg...@cs.ucla.edu>
+
+	Port FALLTHROUGH to clang 3.4 and earlier
+	Problem reported by Akim Demaille in:
+	https://lists.gnu.org/r/bug-gnulib/2021-01/msg00241.html
+	* lib/cdefs.h (__glibc_has_attribute):
+	* m4/gnulib-common.m4 (gl_COMMON_BODY):
+	Do not trust __has_attribute in clang 3.4 and earlier, as
+	<https://releases.llvm.org/3.5.0/tools/clang/docs/ReleaseNotes.html>
+	says that __has_attribute is unreliable in these old versions.
+
 2021-01-20  Bruno Haible  <br...@clisp.org>
 
 	gc-random: Fix link error in tests.
diff --git a/lib/cdefs.h b/lib/cdefs.h
index a22ae6db2..060a3d068 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -38,7 +38,9 @@
        #if defined __has_attribute && __has_attribute (...)
    even though they do not need to evaluate the right-hand side of the &&.
    Similarly for __has_builtin, etc.  */
-#ifdef __has_attribute
+#if (defined __has_attribute \
+     && (!defined __clang_minor__ \
+         || 3 < __clang_major__ + (5 <= __clang_minor__)))
 # define __glibc_has_attribute(attr) __has_attribute (attr)
 #else
 # define __glibc_has_attribute(attr) 0
diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index 3d87fd840..f2eff10de 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -67,7 +67,9 @@ AC_DEFUN([gl_COMMON_BODY], [
 #endif])
   AH_VERBATIM([attribute],
 [/* Attributes.  */
-#ifdef __has_attribute
+#if (defined __has_attribute \
+     && (!defined __clang_minor__ \
+         || 3 < __clang_major__ + (5 <= __clang_minor__)))
 # define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__)
 #else
 # define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr
-- 
2.27.0

Reply via email to