Bug 170403 - wrong ntohs expression type tickling clang
Summary: wrong ntohs expression type tickling clang
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: 9.0-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: Tijl Coosemans
Keywords: standards
Depends on:
Reported: 2012-08-06 06:50 UTC by William Ahern
Modified: 2018-09-22 16:25 UTC (History)
2 users (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description William Ahern 2012-08-06 06:50:01 UTC
I reported this bug to Apple a couple of years ago. Maybe it was inherited from FreeBSD.

The source of the problem is ntohs/htons optimization. ntohs expands to

(__builtin_constant_p(_x) ?  __bswap16_const((__uint16_t)(_x)) : __bswap16_var(_x))

in /usr/include/machine/endian.h.

The problem is that the promoted type of that ternary expression is int. But ntohs and htons are defined to have a return type of uint16_t.

Normally, this is a case of no harm no foul because basically every value gets promoted to int eventually, when used as an operand or argument. Nonetheless, the clang printf analyzer complains when using the %hu format specifier. GCC keeps silent, which is probably why this issue never came to anybody's attention.

$ make CC=clang foo
clang -O2 -pipe   foo.c  -o foo
foo.c:8:12: warning: conversion specifies type 'unsigned short' but the argument
      has type 'int' [-Wformat]
        printf("%hu\n", ntohs(i));
                ~~^     ~~~~~~~~
1 warning generated.


Cast the result of the __bswap16  expression to __uint16_t, either in the __ntohs/__htons macros, or in the __bswap16 macro directly like with __bswap16_const.
How-To-Repeat: // make CC=clang foo
#include <stdio.h>
#include <arpa/inet.h>

int main(void) {
	uint16_t i = 1234;

	printf("%hu\n", ntohs(i));

	return 0;
Comment 1 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 07:59:11 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped
Comment 2 Yuri Pankov 2017-12-31 15:44:33 UTC
fixed in base r232730
Comment 3 Kubilay Kocak freebsd_committer freebsd_triage 2018-09-22 09:20:41 UTC
Assign to committer that resolved