Bug 68193

Summary: _Generic -Woverflow false alarm
Product: gcc Reporter: Paul Eggert <eggert>
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: egallager, muecker, rguenth, uecker
Priority: P3 Keywords: diagnostic, patch
Version: 5.2.0   
Target Milestone: 14.0   
URL: https://gcc.gnu.org/pipermail/gcc-patches/2023-August/626319.html
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89425
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110703
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97100
Host: Target:
Build: Known to work:
Known to fail: 4.9.0 Last reconfirmed: 2015-11-03 00:00:00
Attachments: Ternary if

Description Paul Eggert 2015-11-02 23:46:31 UTC
I ran into this problem when developing Gnulib code.  This is with GCC 5.2.0 on x86-64.  Compile the following program t.c with 'gcc -Wall t.c':

int
main (void)
{
  int i = 0;
  int j = _Generic (i,
		    int: 0,
		    long int: (i = (long int) 9223372036854775808UL));
  return i + j;
}

GCC generates the bogus warning:

t.c: In function 'main':
t.c:7:22: warning: overflow in implicit constant conversion [-Woverflow]
       long int: (i = (long int) 9223372036854775808UL));
                      ^

The warning is bogus because the corresponding expression is not evaluated, as per the semantics of _Generic.

Add 1 to that big constant, changing it to 9223372036854775809UL, and the bogus warning goes away.  So it's possible that there are two bugs here, one having to do with bogus warnings in unevaluated _Generic subexpressions, the other having to do with (unsigned long) LONG_MIN.
Comment 1 Richard Biener 2015-11-03 10:30:40 UTC
Confirmed.
Comment 2 Marek Polacek 2015-12-02 12:04:30 UTC
The problem here is that after we've parsed the selector (with warnings inhibited), we go over all the associations: process the type-name, then parse assignment-expression of the association also using c_parser_expr_no_commas, but this time without the warnings inhibited.  We should probably disable warnings when processing the associations and only warn for matched_assoc.  But I can't readily conceive how to do that.
Comment 3 Marek Polacek 2015-12-02 16:36:24 UTC
I think some kind of delayed warning could help (so parse expressions and print possible warnings to some "printer" and then print warnings from this "printer" only for the association that matched).  Because of "default:" selectors we can't parse just the one that matches.
Comment 4 jsm-csl@polyomino.org.uk 2015-12-02 16:47:15 UTC
I agree delaying warnings would help, but you'd need to distinguish 
warnings relating to execution of the code that should be disabled in 
unevaluated code from warnings that should always be present (which 
include but aren't limited to pedwarns).  For example, you shouldn't lose 
a diagnostic for an implicit function declaration just because it's in an 
unevaluated _Generic selection.
Comment 5 Marek Polacek 2015-12-02 17:10:49 UTC
Yes, so this would be somehow tied to c_inhibit_evaluation_warnings as in we warn for
  0 ? foo () : 2;
if foo() wasn't declared but not for the div-by-zero here:
  0 ? 1 / 0 : 2;
Comment 6 Ladislav Michl 2019-05-21 21:53:47 UTC
Created attachment 46391 [details]
Ternary if

That ternary operator makes warning disappear. In the testcase 'gcc -Woverflow -o x x.c' gives:
x.c:14:9: warning: unsigned conversion from ‘int’ to ‘unsigned char’ changes value from ‘1000’ to ‘232’ [-Woverflow]
   baz = 1000;
         ^~~~
x.c:16:9: warning: unsigned conversion from ‘int’ to ‘unsigned char’ changes value from ‘2000’ to ‘208’ [-Woverflow]
   baz = 2000;
         ^~~~
while 'gcc -DNO -Woverflow -o x x.c' silently ignores overflow.
I would welcome any advice, how o properly categorize this bug, so eventually new bugreport will be created.

Thank you.
Comment 8 GCC Commits 2023-08-05 08:40:14 UTC
The master branch has been updated by Martin Uecker <uecker@gcc.gnu.org>:

https://gcc.gnu.org/g:54be338589ea93ad4ff53d22adde476a0582537b

commit r14-3004-g54be338589ea93ad4ff53d22adde476a0582537b
Author: Martin Uecker <uecker@tugraz.at>
Date:   Fri Aug 4 07:48:21 2023 +0200

    c: _Generic should not warn in non-active branches [PR68193,PR97100,PR110703]
    
    To avoid false diagnostics, use c_inhibit_evaluation_warnings when
    a generic association is known to not match during parsing.  We may
    still generate false positives if the default branch comes earler than
    a specific association that matches.
    
    PR c/68193
    PR c/97100
    PR c/110703
    
    gcc/c/:
            * c-parser.cc (c_parser_generic_selection): Inhibit evaluation
            warnings branches that are known not be taken during parsing.
    
    gcc/testsuite/ChangeLog:
            * gcc.dg/pr68193.c: New test.
Comment 9 uecker 2023-11-03 19:26:50 UTC
Fixed on trunk.