Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-Wsometimes-uninitialized in net/wireless/util.c #382

Closed
nickdesaulniers opened this issue Feb 26, 2019 · 9 comments
Closed

-Wsometimes-uninitialized in net/wireless/util.c #382

nickdesaulniers opened this issue Feb 26, 2019 · 9 comments
Assignees
Labels
-Wsometimes-uninitialized [ARCH] arm32 This bug impacts ARCH=arm [ARCH] arm64 This bug impacts ARCH=arm64 [BUG] linux A bug that should be fixed in the mainline kernel. [FIXED][LINUX] 5.1 This bug was fixed in Linux 5.1

Comments

@nickdesaulniers
Copy link
Member

reported from #381 :

net/wireless/util.c:1223:11: error: variable 'result' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
@nickdesaulniers nickdesaulniers added good first issue Good for newcomers [BUG] linux A bug that should be fixed in the mainline kernel. low priority This bug is not critical and not a priority [ARCH] arm32 This bug impacts ARCH=arm [ARCH] arm64 This bug impacts ARCH=arm64 -Wsometimes-uninitialized labels Feb 26, 2019
@nickdesaulniers
Copy link
Member Author

final branch should just be an else (no condition), with the WARN then a return statement. Clang is unhappy because if WARN() expands to something that evaluates to false, then the function wont return correctly.

@nathanchance
Copy link
Member

WARN(1, ...) should always be true according to its definition (last line):

With CONFIG_BUG:

#ifndef WARN
#define WARN(condition, format...) ({					\
	int __ret_warn_on = !!(condition);				\
	if (unlikely(__ret_warn_on))					\
		__WARN_printf(format);					\
	unlikely(__ret_warn_on);					\
})
#endif

Without CONFIG_BUG:

#ifndef WARN
#define WARN(condition, format...) ({					\
	int __ret_warn_on = !!(condition);				\
	no_printk(format);						\
	unlikely(__ret_warn_on);					\
})
#endif

However, I assume that all of this analysis occurs before optimization so Clang can't tell that the last else if will basically become an else (would help justify the change). The author was basically trying to conserve space by having the print out come from the conditional then the return be one line. We'll see how this change goes over:

diff --git a/net/wireless/util.c b/net/wireless/util.c
index e4b8db5e81ec..8c381ca22903 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1220,9 +1220,11 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
        else if (rate->bw == RATE_INFO_BW_HE_RU &&
                 rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_26)
                result = rates_26[rate->he_gi];
-       else if (WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
-                     rate->bw, rate->he_ru_alloc))
+       else {
+               WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
+                     rate->bw, rate->he_ru_alloc);
                return 0;
+       }
 
        /* now scale to the appropriate MCS */
        tmp = result;

@nathanchance
Copy link
Member

@nickdesaulniers Does the reasoning behind this make sense? Something tells me we're going to get some push back on some of these fixes so I want to make sure to convey that some of these warnings will be from how GCC and Clang differ in when semantic analysis and warnings occur:

From 1fa0abca80a0fdfec70d81ce79c54f03fe6189c7 Mon Sep 17 00:00:00 2001
From: Nathan Chancellor <natechancellor@gmail.com>
Date: Tue, 5 Mar 2019 13:37:00 -0700
Subject: [PATCH] cfg80211: Adjust an else if statement to avoid a clang
 warning

When building with -Wsometimes-uninitialized, Clang warns:

net/wireless/util.c:1223:11: warning: variable 'result' is used
uninitialized whenever 'if' condition is false
[-Wsometimes-uninitialized]
        else if (WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/asm-generic/bug.h:130:36: note: expanded from macro 'WARN'
#define WARN(condition, format...) ({
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/wireless/util.c:1228:8: note: uninitialized use occurs here
        tmp = result;
              ^~~~~~
net/wireless/util.c:1223:7: note: remove the 'if' if its condition is
always true
        else if (WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/wireless/util.c:1187:12: note: initialize the variable 'result' to
silence this warning
        u32 result;
                  ^
                   = 0
1 warning generated.

This is because Clang cannot evaluate at this point that WARN(1, ...)
always evaluates to true (which is why it suggests removing the 'if')
because semantic analysis happens in the front end before optimization
like constant folding occurs in the middle and backend. Turn this
'else if' into an else as it suggests to get rid of this warning.

Link: https://github.com/ClangBuiltLinux/linux/issues/382
Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
---
 net/wireless/util.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index e4b8db5e81ec..8c381ca22903 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1220,9 +1220,11 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
 	else if (rate->bw == RATE_INFO_BW_HE_RU &&
 		 rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_26)
 		result = rates_26[rate->he_gi];
-	else if (WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
-		      rate->bw, rate->he_ru_alloc))
+	else {
+		WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
+		      rate->bw, rate->he_ru_alloc);
 		return 0;
+	}
 
 	/* now scale to the appropriate MCS */
 	tmp = result;
-- 
2.21.0

@nickdesaulniers
Copy link
Member Author

I'd cut

This is because Clang cannot evaluate at this point that WARN(1, ...)
always evaluates to true (which is why it suggests removing the 'if')
because semantic analysis happens in the front end before optimization
like constant folding occurs in the middle and backend.

and say something to the effect that

if (WARN(... doesn't make a whole lot of sense and adds noise to otherwise helpful -Wsometimes-uninitialized warnings. else, rather than if else makes it clearer.

idk

@nathanchance
Copy link
Member

I don't necessarily agree with the comment about WARN(1, ... not making sense since the condition evaluation (int __ret_warn_on = !!(condition);) is always last in the macro (unlikely(__ret_warn_on);) so it will always be true. I'd like to avoid people coming back and telling us to fix the compiler rather than changing the code but I suppose it's unavoidable in this line of work :) I'll try to come up with a different wording.

@nathanchance
Copy link
Member

@nathanchance nathanchance added [PATCH] Submitted A patch has been submitted for review and removed good first issue Good for newcomers low priority This bug is not critical and not a priority labels Mar 7, 2019
@nathanchance nathanchance self-assigned this Mar 7, 2019
@arndb
Copy link

arndb commented Mar 22, 2019

I opened https://llvm.org/pr41197, I think this is one of those.

@nathanchance
Copy link
Member

@nathanchance nathanchance added [PATCH] Accepted A submitted patch has been accepted upstream and removed [PATCH] Submitted A patch has been submitted for review labels Apr 1, 2019
@nathanchance
Copy link
Member

@nathanchance nathanchance added [FIXED][LINUX] 5.1 This bug was fixed in Linux 5.1 and removed [PATCH] Accepted A submitted patch has been accepted upstream labels Apr 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
-Wsometimes-uninitialized [ARCH] arm32 This bug impacts ARCH=arm [ARCH] arm64 This bug impacts ARCH=arm64 [BUG] linux A bug that should be fixed in the mainline kernel. [FIXED][LINUX] 5.1 This bug was fixed in Linux 5.1
Projects
None yet
Development

No branches or pull requests

3 participants