This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] fix #19444 - build failures with -O1 due to -Wmaybe-uninitialized


The Glibc FAQ on the Wiki documents the limitation that the library
prevents users from building it without optimization (-O0).  However,
the mechanism in place doesn't prevent using -O1, and the FAQ doesn't
mention that this level cannot or should not be used.  Using a lower
level of optimization than -O2 can be helpful in debugging.

However, trunk fails to build with -O1 due to a number of warnings
about possibly uninitialized that are treated as errors.  It turns
out that the warnings are false positives caused by a documented
limitation of the GCC implementation (the value range propagation
optimization is disabled at -O1, which prevents GCC from seeing
that in some of the non-trivial cases of apparently uninitialized
variables the variables are in fact initialized when used).

In his comments on the bug, Carlos suggests to fix these instances
of false positives and to get -O1 to work.  The attached patch
does just that.  In the patch, to minimize the impact of the
(otherwise unnecessary) initialization, rather than initializing
them for all the code paths, I reduced the scope of the local
variables that are subject to the warning and added the redundant
initialization only for the problem code paths.  This led to more
changes that would otherwise be required but resulted in code
that's easier to follow.

The patch also adds -Wno-error=maybe-uninitialized to the warning
options when -O1 or lower is set in CFLAGS to prevent these false
positives from causing build failures.  This change renders the
changes above strictly unnecessary.  I include both since I think
both are worthwhile but I can remove one or the other if others
have a different preference.

Tested on x86_64.

Martin
2016-01-13  Martin Sebor  <msebor@redhat.com>

	[BZ #19444]
	* Makeconfig (gccwarn): Add -Wno-error=maybe-uninitialized when
	-O or -O1 is found in CFLAGS.
	* sysdeps/ieee754/dbl-64/e_jn.c (__ieee754_jn): Move variable
	declaration closer to its use and initialize to avoid false
	positive -Wmaybe-uninitialized warnings.
	* sysdeps/ieee754/dbl-64/s_sin.c (reduce_and_compute): Same.
	(do_sincos_1, do_sincos_2): Same.
	* sysdeps/ieee754/ldbl-96/e_jnl.c (__ieee754_jnl): Same.
	(__ieee754_ynl): Same.

diff --git a/Makeconfig b/Makeconfig
index 87a22e8..081ece6 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -750,7 +750,15 @@ endif
 +gccwarn += -Wundef
 ifeq ($(enable-werror),yes)
 +gccwarn += -Werror
+
+# GCC's -Wmaybe-uninitialized depends on optimization and is documented
+# to issue false positives at -O1 (or lower).  If -O1 or lower is found
+# in CFLAGS, prevent such warnings from being treated as errors.
+ifneq ($(filter-out -O -O1, $(CFLAGS)),$(CFLAGS))
+gccwarn += -Wno-error=maybe-uninitialized
+endif
 endif
+
 +gccwarn-c = -Wstrict-prototypes -Wold-style-definition
 
 # We do not depend on the address of constants in different files to be
diff --git a/sysdeps/ieee754/dbl-64/e_jn.c b/sysdeps/ieee754/dbl-64/e_jn.c
index 3fecf82..f6eceae 100644
--- a/sysdeps/ieee754/dbl-64/e_jn.c
+++ b/sysdeps/ieee754/dbl-64/e_jn.c
@@ -52,7 +52,7 @@ double
 __ieee754_jn (int n, double x)
 {
   int32_t i, hx, ix, lx, sgn;
-  double a, b, temp, di, ret;
+  double a, b, di, ret;
   double z, w;
 
   /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
@@ -100,6 +100,8 @@ __ieee754_jn (int n, double x)
 	    double s;
 	    double c;
 	    __sincos (x, &s, &c);
+
+	    double temp = 0;
 	    switch (n & 3)
 	      {
 	      case 0: temp = c + s; break;
@@ -115,7 +117,7 @@ __ieee754_jn (int n, double x)
 	    b = __ieee754_j1 (x);
 	    for (i = 1; i < n; i++)
 	      {
-		temp = b;
+		double temp = b;
 		b = b * ((double) (i + i) / x) - a; /* avoid underflow */
 		a = temp;
 	      }
@@ -131,7 +133,8 @@ __ieee754_jn (int n, double x)
 	      b = zero;
 	    else
 	      {
-		temp = x * 0.5; b = temp;
+		double temp = x * 0.5;
+                b = temp;
 		for (a = one, i = 2; i <= n; i++)
 		  {
 		    a *= (double) i;              /* a = n! */
@@ -202,7 +205,7 @@ __ieee754_jn (int n, double x)
 	      {
 		for (i = n - 1, di = (double) (i + i); i > 0; i--)
 		  {
-		    temp = b;
+		    double temp = b;
 		    b *= di;
 		    b = b / x - a;
 		    a = temp;
@@ -213,7 +216,7 @@ __ieee754_jn (int n, double x)
 	      {
 		for (i = n - 1, di = (double) (i + i); i > 0; i--)
 		  {
-		    temp = b;
+		    double temp = b;
 		    b *= di;
 		    b = b / x - a;
 		    a = temp;
@@ -261,7 +264,7 @@ __ieee754_yn (int n, double x)
 {
   int32_t i, hx, ix, lx;
   int32_t sign;
-  double a, b, temp, ret;
+  double a, b, ret;
 
   EXTRACT_WORDS (hx, lx, x);
   ix = 0x7fffffff & hx;
@@ -307,6 +310,8 @@ __ieee754_yn (int n, double x)
 	double c;
 	double s;
 	__sincos (x, &s, &c);
+
+        double temp = 0;
 	switch (n & 3)
 	  {
 	  case 0: temp = s - c; break;
@@ -325,7 +330,7 @@ __ieee754_yn (int n, double x)
 	GET_HIGH_WORD (high, b);
 	for (i = 1; i < n && high != 0xfff00000; i++)
 	  {
-	    temp = b;
+	    double temp = b;
 	    b = ((double) (i + i) / x) * b - a;
 	    GET_HIGH_WORD (high, b);
 	    a = temp;
diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
index ca2532f..3cd3e83 100644
--- a/sysdeps/ieee754/dbl-64/s_sin.c
+++ b/sysdeps/ieee754/dbl-64/s_sin.c
@@ -244,8 +244,11 @@ static inline double
 __always_inline
 reduce_and_compute (double x, unsigned int k)
 {
-  double retval = 0, a, da;
+  double a, da;
   unsigned int n = __branred (x, &a, &da);
+
+  double retval = 0;
+
   k = (n + k) % 4;
   switch (k)
     {
@@ -297,11 +300,13 @@ static double
 __always_inline
 do_sincos_1 (double a, double da, double x, int4 n, int4 k)
 {
-  double xx, retval, res, cor, y;
+  double xx, res, cor, y;
   mynumber u;
   int m;
   double eps = fabs (x) * 1.2e-30;
 
+  double retval = 0;
+
   int k1 = (n + k) & 3;
   switch (k1)
     {			/* quarter of unit circle */
@@ -387,11 +392,13 @@ static double
 __always_inline
 do_sincos_2 (double a, double da, double x, int4 n, int4 k)
 {
-  double res, retval, cor, xx;
+  double res, cor, xx;
   mynumber u;
 
   double eps = 1.0e-24;
 
+  double retval = 0;
+
   k = (n + k) & 3;
 
   switch (k)
diff --git a/sysdeps/ieee754/ldbl-96/e_jnl.c b/sysdeps/ieee754/ldbl-96/e_jnl.c
index 92f9692..66d467b 100644
--- a/sysdeps/ieee754/ldbl-96/e_jnl.c
+++ b/sysdeps/ieee754/ldbl-96/e_jnl.c
@@ -71,7 +71,7 @@ __ieee754_jnl (int n, long double x)
 {
   u_int32_t se, i0, i1;
   int32_t i, ix, sgn;
-  long double a, b, temp, di, ret;
+  long double a, b, di, ret;
   long double z, w;
 
   /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
@@ -126,6 +126,7 @@ __ieee754_jnl (int n, long double x)
 	     */
 	    long double s;
 	    long double c;
+            long double temp = 0;
 	    __sincosl (x, &s, &c);
 	    switch (n & 3)
 	      {
@@ -150,7 +151,7 @@ __ieee754_jnl (int n, long double x)
 	    b = __ieee754_j1l (x);
 	    for (i = 1; i < n; i++)
 	      {
-		temp = b;
+		long double temp = b;
 		b = b * ((long double) (i + i) / x) - a;	/* avoid underflow */
 		a = temp;
 	      }
@@ -167,7 +168,7 @@ __ieee754_jnl (int n, long double x)
 	      b = zero;
 	    else
 	      {
-		temp = x * 0.5;
+		long double temp = x * 0.5;
 		b = temp;
 		for (a = one, i = 2; i <= n; i++)
 		  {
@@ -246,7 +247,7 @@ __ieee754_jnl (int n, long double x)
 	      {
 		for (i = n - 1, di = (long double) (i + i); i > 0; i--)
 		  {
-		    temp = b;
+		    long double temp = b;
 		    b *= di;
 		    b = b / x - a;
 		    a = temp;
@@ -257,7 +258,7 @@ __ieee754_jnl (int n, long double x)
 	      {
 		for (i = n - 1, di = (long double) (i + i); i > 0; i--)
 		  {
-		    temp = b;
+		    long double temp = b;
 		    b *= di;
 		    b = b / x - a;
 		    a = temp;
@@ -305,7 +306,7 @@ __ieee754_ynl (int n, long double x)
   u_int32_t se, i0, i1;
   int32_t i, ix;
   int32_t sign;
-  long double a, b, temp, ret;
+  long double a, b, ret;
 
 
   GET_LDOUBLE_WORDS (se, i0, i1, x);
@@ -355,6 +356,7 @@ __ieee754_ynl (int n, long double x)
 	 */
 	long double s;
 	long double c;
+	long double temp = 0;
 	__sincosl (x, &s, &c);
 	switch (n & 3)
 	  {
@@ -382,7 +384,7 @@ __ieee754_ynl (int n, long double x)
 	/* Use 0xffffffff since GET_LDOUBLE_WORDS sign-extends SE.  */
 	for (i = 1; i < n && se != 0xffffffff; i++)
 	  {
-	    temp = b;
+	    long double temp = b;
 	    b = ((long double) (i + i) / x) * b - a;
 	    GET_LDOUBLE_WORDS (se, i0, i1, b);
 	    a = temp;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]