From owner-freebsd-current@FreeBSD.ORG Sat Jul 14 13:12:54 2012 Return-Path: Delivered-To: current@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CF03B106566C; Sat, 14 Jul 2012 13:12:54 +0000 (UTC) (envelope-from jilles@stack.nl) Received: from mx1.stack.nl (relay02.stack.nl [IPv6:2001:610:1108:5010::104]) by mx1.freebsd.org (Postfix) with ESMTP id 672A68FC0A; Sat, 14 Jul 2012 13:12:54 +0000 (UTC) Received: from snail.stack.nl (snail.stack.nl [IPv6:2001:610:1108:5010::131]) by mx1.stack.nl (Postfix) with ESMTP id C142C3592E4; Sat, 14 Jul 2012 15:12:53 +0200 (CEST) Received: by snail.stack.nl (Postfix, from userid 1677) id 9D3CB2847B; Sat, 14 Jul 2012 15:12:53 +0200 (CEST) Date: Sat, 14 Jul 2012 15:12:53 +0200 From: Jilles Tjoelker To: "Justin T. Gibbs" Message-ID: <20120714131253.GA82559@stack.nl> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Cc: current@FreeBSD.org, des@FreeBSD.org Subject: Re: PAM passwdqc, strict aliasing, and WARNS X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Jul 2012 13:12:54 -0000 On Fri, Jul 13, 2012 at 04:14:17PM -0600, Justin T. Gibbs wrote: > Someone who has yet to confess added -Werror to the global CFLAGS > (via /etc/make.conf) for one of our systems at work. Before I > figured out that this was the cause of builds failing, I hacked up > pam_passwdc to resolve the problem. This gets the module to > WARNS=2, but to go farther, the "logically const" issues with this > code will need to be sorted out. > Is this change worth committing? Is this the best way to resolve > the strict aliasing issues in this code? The prototype of pam_get_item() is int pam_get_item(const pam_handle_t *pamh, int item_type, const void **item); Therefore, you should pass a pointer to a const void pointer as the last argument. You can then convert the const void pointer to the desired type. For example: const void *item; const struct pam_conv *conv; result = pam_get_item(pamh, PAM_CONV, &item); conv = item; Passing something like a pointer to a 'const struct pam_conv *' to pam_get_item() will cause a strict-aliasing violation because pam_get_item() will attempt to store a value into an object of declared type 'const struct pam_conv *' using an lvalue of type 'const void *'. In both C99 and C11, these rules are in 6.5 Expressions. In the case of const struct pam_conv *, the union approach violates the C standard because the C standard does not guarantee that all object pointers have the same representation. The conversion might be non-trivial and a "type-pun" may not work properly. However, in almost all real machines the conversion is trivial. Some compilers may still consider the union approach a strict-aliasing violation. In any case, I think it is a bit ugly and should be avoided when possible (like here). -- Jilles Tjoelker