ash mis-compiles with clang

Denys Vlasenko vda.linux at googlemail.com
Thu Jul 27 13:32:37 UTC 2017


On Wed, Jul 26, 2017 at 10:40 PM, Yunlian Jiang <yunlian at google.com> wrote:
> Hi,
>    When I try to build busybox with clang, I got some errors on ash at
> runtime.
>    https://bugs.chromium.org/p/chromium/issues/detail?id=659834
>
>    It seems that root cause is clang adds the attribute __noreturn__ to
> the function evaltree.
>
>    Can we fix this to make it build with clang? I can provide a patch to
> remove
> the attribute  __noreturn__ from evaltreenr if the compiler is clang.
>
>    Does that sounds a reasonable fix?

Tried that, it throws more warning about uninited variables.

Does this patch help?
-------------- next part --------------
diff --git a/include/platform.h b/include/platform.h
index 8210e5c..ea49c7e 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -45,6 +45,13 @@
 
 #define UNUSED_PARAM __attribute__ ((__unused__))
 #define NORETURN __attribute__ ((__noreturn__))
+
+#if __GNUC_PREREQ(4,5)
+# define bb_unreachable(altcode) __builtin_unreachable()
+#else
+# define bb_unreachable(altcode) altcode
+#endif
+
 /* "The malloc attribute is used to tell the compiler that a function
  * may be treated as if any non-NULL pointer it returns cannot alias
  * any other pointer valid when the function returns. This will often
diff --git a/shell/ash.c b/shell/ash.c
index f74fbd7..17dc4e6 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -6137,6 +6137,15 @@ struct backcmd {                /* result of evalbackcmd */
 #define EV_TESTED  02           /* exit status is checked; ignore -e flag */
 static int evaltree(union node *, int);
 
+/* An evaltree() which is known to never return */
+static ALWAYS_INLINE NORETURN void
+evaltreenr(union node *n, int flags)
+{
+	evaltree(n, flags);
+	bb_unreachable(abort());
+	/* NOTREACHED */
+}
+
 static void FAST_FUNC
 evalbackcmd(union node *n, struct backcmd *result)
 {
@@ -6173,7 +6182,7 @@ evalbackcmd(union node *n, struct backcmd *result)
  */
 		eflag = 0;
 		ifsfree();
-		evaltree(n, EV_EXIT); /* actually evaltreenr... */
+		evaltreenr(n, EV_EXIT);
 		/* NOTREACHED */
 	}
 	/* parent */
@@ -8796,11 +8805,6 @@ evaltree(union node *n, int flags)
 	return exitstatus;
 }
 
-#if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
-static
-#endif
-int evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__));
-
 static int
 skiploop(void)
 {


More information about the busybox mailing list