https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89107
Bug ID: 89107 Summary: -Wconversion warning is not appropriate since conversion doesn't alter value, because of mask entered before. Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: mareksz1958 at wp dot pl Target Milestone: --- Such code is failing to compile on 2): union U { unsigned int a:20; }; int main() { union U u; unsigned int val = 0xaabbc000; u.a = val & 0xfffff; // 1) works u.a = (val >> 12) & 0xfffff; // 2) doesn't } Because of the shift the compiler refuses to accept the conversion. And complains in the following way: $ gcc wconv.c -Wconversion -Werror wconv.c: In function ‘main’: wconv.c:10:11: error: conversion to ‘unsigned int:20’ from ‘unsigned int’ may alter its value [-Werror=conversion] u.a = (val >> 12) & 0xfffff; /* 2) doesn't */ ^ cc1: all warnings being treated as errors Clang is compiling following code successfully. Seems like there is some off-by-one bug; Mask 0x7ffff works without warnings/errors.