Bug 70772 - Wrong warning about unspecified behavior for comparison with string literal
Summary: Wrong warning about unspecified behavior for comparison with string literal
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2016-04-23 18:39 UTC by Alexander Cherepanov
Modified: 2016-04-26 17:50 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.9.3, 5.3.0, 6.0
Last reconfirmed: 2016-04-25 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Cherepanov 2016-04-23 18:39:52 UTC
While compiling such program:

int main()
{
  "abc" == "def";
}

I get this warning:

$ gcc -Wall -Wno-unused-value example.c 
example.c: In function ‘main’:
example.c:3:9: warning: comparison with string literal results in unspecified behavior [-Waddress]
   "abc" == "def";
         ^~

The warning is wrong, this equality cannot be true.

I understand that the warning is intended to catch comparisons like "abc" == "abc" which indeed have an unspecified result. But the current warning is too promiscuous.
The easy fix is to reformulate closer to "comparison with string literal is always false or has an unspecified result".
The more thorough fix is to separately catch cases that could be proved to be false at compile time.
Comment 1 Alexander Cherepanov 2016-04-23 18:45:52 UTC
clang bug -- https://llvm.org/bugs/show_bug.cgi?id=27495 .
Comment 2 Richard Biener 2016-04-25 07:50:09 UTC
Confirmed.
Comment 3 Martin Sebor 2016-04-26 17:50:53 UTC
This bug affects both the C and the C++ front ends.  I mention it because when developing a patch, it would be worth fixing both, and handle other equality and relational operators, as well as the substraction expression.  Since the C rules are different than C++, the handling needs to be different for each language.

The test case below shows the problems in C and documents the expected output in C++.  Note that even in cases where a diagnostic is expected and issued, the text of the diagnostic should change to reflect what the relevant standard says (undefined behavior in C rather than unspecified).  Unlike in C, in C++, the behavior of relational expressions is well defined even for pointers pointing to different objects provided one compares either less that or equal to the other (it is unspecified otherwise), so the text of the diagnostic should be adjusted to reflect that.

$ cat v.c && gcc -S -Wall -Wextra -Wpedantic -xc v.c
void f (void)
{
  const __PTRDIFF_TYPE__ a[] = {
    "a" == "b",   // no warning expected (behavior well defined)
    "a" != "b",   // no warning expected (behavior well defined)
    "a" <  "b",   // warning expected in C only (undefined behavior)
    "a" <= "b",   // warning expected in C only (undefined behavior)
    "a" >  "b",   // warning expected in C only (undefined behavior)
    "a" >= "b",   // warning expected in C only (undefined behavior)
    "a" -  "b"    // warning expected (undefined behavior)
  };
  (void)a;
}
v.c: In function ‘f’:
v.c:4:9: warning: comparison with string literal results in unspecified behavior [-Waddress]
     "a" == "b",   // no warning expected (behavior well defined)
         ^~
v.c:5:9: warning: comparison with string literal results in unspecified behavior [-Waddress]
     "a" != "b",   // no warning expected (behavior well defined)
         ^~
v.c:6:9: warning: comparison with string literal results in unspecified behavior [-Waddress]
     "a" <  "b",   // warning expected in C only (undefined behavior)
         ^
v.c:7:9: warning: comparison with string literal results in unspecified behavior [-Waddress]
     "a" <= "b",   // warning expected in C only (undefined behavior)
         ^~
v.c:8:9: warning: comparison with string literal results in unspecified behavior [-Waddress]
     "a" >  "b",   // warning expected in C only (undefined behavior)
         ^
v.c:9:9: warning: comparison with string literal results in unspecified behavior [-Waddress]
     "a" >= "b",   // warning expected in C only (undefined behavior)
         ^~