diff mbox

[v5,6/9] bug.h: Prevent double evaulation of in BUILD_BUG_ON

Message ID 1352844821-18952-6-git-send-email-daniel.santos@pobox.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Daniel Santos Nov. 13, 2012, 10:13 p.m. UTC
When calling BUILD_BUG_ON in an optimized build using gcc 4.3 and later,
the condition will be evaulated twice, possibily with side-effects.
This patch eliminates that error.

Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
---
 include/linux/bug.h |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

Comments

Borislav Petkov Nov. 15, 2012, 3:07 p.m. UTC | #1
On Tue, Nov 13, 2012 at 04:13:38PM -0600, danielfsantos@att.net wrote:
> When calling BUILD_BUG_ON in an optimized build using gcc 4.3 and later,
> the condition will be evaulated twice, possibily with side-effects.
> This patch eliminates that error.
> 
> Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
> ---
>  include/linux/bug.h |    5 +++--
>  1 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/bug.h b/include/linux/bug.h
> index 1b2465d..ccd44ce 100644
> --- a/include/linux/bug.h
> +++ b/include/linux/bug.h
> @@ -58,8 +58,9 @@ struct pt_regs;
>  extern int __build_bug_on_failed;
>  #define BUILD_BUG_ON(condition)					\
>  	do {							\
> -		((void)sizeof(char[1 - 2*!!(condition)]));	\
> -		if (condition) __build_bug_on_failed = 1;	\
> +		bool __cond = !!(condition);			\
> +		((void)sizeof(char[1 - 2*!!(__cond)]));		\

No need for the !!(__cond) here because you've done it in the line
above. IOW,

	bool __cond = !!(condition);
	((void)sizeof(char[1 - 2 * __cond]));

which is even a bit more readable, as a matter of fact.

> +		if (__cond) __build_bug_on_failed = 1;		\
>  	} while(0)
>  #endif

Thanks.
Daniel Santos Nov. 15, 2012, 7:11 p.m. UTC | #2
On 11/15/2012 09:07 AM, Borislav Petkov wrote:
> On Tue, Nov 13, 2012 at 04:13:38PM -0600, danielfsantos@att.net wrote:
>> When calling BUILD_BUG_ON in an optimized build using gcc 4.3 and later,
>> the condition will be evaulated twice, possibily with side-effects.
>> This patch eliminates that error.
>>
>> Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
>> ---
>>  include/linux/bug.h |    5 +++--
>>  1 files changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/bug.h b/include/linux/bug.h
>> index 1b2465d..ccd44ce 100644
>> --- a/include/linux/bug.h
>> +++ b/include/linux/bug.h
>> @@ -58,8 +58,9 @@ struct pt_regs;
>>  extern int __build_bug_on_failed;
>>  #define BUILD_BUG_ON(condition)					\
>>  	do {							\
>> -		((void)sizeof(char[1 - 2*!!(condition)]));	\
>> -		if (condition) __build_bug_on_failed = 1;	\
>> +		bool __cond = !!(condition);			\
>> +		((void)sizeof(char[1 - 2*!!(__cond)]));		\
> No need for the !!(__cond) here because you've done it in the line
> above. IOW,
>
> 	bool __cond = !!(condition);
> 	((void)sizeof(char[1 - 2 * __cond]));
>
> which is even a bit more readable, as a matter of fact.
Ah yes. I did notice that at one point, but I think it slipped my mind. 
Also, the kernel has introduced me to the usage of the !! construct, of
which I'm well versed in its affects in various situations and how gcc's
optimizer ends up treating its usage, so probably another reason I
didn't change it immediately. But it's basically shorthand for the
expression (condition ? 1 : 0), correct? Or are there other details in
the C standard that makes it different in some cases?

Thanks,
Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Borislav Petkov Nov. 17, 2012, 2:38 p.m. UTC | #3
On Thu, Nov 15, 2012 at 01:11:15PM -0600, Daniel Santos wrote:
> Ah yes. I did notice that at one point, but I think it slipped
> my mind. Also, the kernel has introduced me to the usage of the
> !! construct, of which I'm well versed in its affects in various
> situations and how gcc's optimizer ends up treating its usage, so
> probably another reason I didn't change it immediately. But it's
> basically shorthand for the expression (condition ? 1 : 0), correct?

I don't think so: "!!" is simply a double negation which turns the
whatever wild construct you have into either 0 or 1, depending on what
it evaluates to.

But I don't know what the standard says so you'll have to check :-)

Thanks.
diff mbox

Patch

diff --git a/include/linux/bug.h b/include/linux/bug.h
index 1b2465d..ccd44ce 100644
--- a/include/linux/bug.h
+++ b/include/linux/bug.h
@@ -58,8 +58,9 @@  struct pt_regs;
 extern int __build_bug_on_failed;
 #define BUILD_BUG_ON(condition)					\
 	do {							\
-		((void)sizeof(char[1 - 2*!!(condition)]));	\
-		if (condition) __build_bug_on_failed = 1;	\
+		bool __cond = !!(condition);			\
+		((void)sizeof(char[1 - 2*!!(__cond)]));		\
+		if (__cond) __build_bug_on_failed = 1;		\
 	} while(0)
 #endif