Bug 32643 - [12/13/14/15 Regression] Wrong error message with unsigned char a = uchar&512
Summary: [12/13/14/15 Regression] Wrong error message with unsigned char a = uchar&512
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.3.0
: P2 normal
Target Milestone: 12.5
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid, diagnostic
Depends on:
Blocks: 19976 29116 32628
  Show dependency treegraph
 
Reported: 2007-07-06 09:03 UTC by Andrew Pinski
Modified: 2024-07-19 12:54 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.0.1, 4.1.3
Known to fail: 10.1.0, 11.0, 4.2.3, 4.3.0
Last reconfirmed: 2024-02-29 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Pinski 2007-07-06 09:03:29 UTC
testcase, compile with -pedantic-errors (we don't reject it overwise in 4.3):
unsigned char p;
unsigned char p1 = p & 512;
------------- cut -------
We get:
overflow-warn-5.c:7: warning: overflow in implicit constant conversion
overflow-warn-5.c:7: error: overflow in constant expression

Now there is an overflow but only because we optimize the IR (unsigned char)(((int)p)& 512) into:
p & (unsigned char)512 and (unsigned char)512 is converted into 0 (with overflow) so we have p & 0 which is then optimized into 0(with overflow).  So we are only rejecting this because of the overflow due to the conversion (which was due to fold).


We don't reject as invalid code either:
unsigned char p;
unsigned char p1 = p & 0;
Comment 1 Andrew Pinski 2007-07-06 09:07:18 UTC
Note this was found while trying to fix PR 32628.

The diagnostic issue is at least a regression from 4.0.1.  Well and the accepts invalid (without -pedantic-errors for the first testcase).

The second testcase was  accepted wrongly in 4.0.1 also.
Comment 2 Andrew Pinski 2007-07-06 09:43:23 UTC
This quick hack fixes the problem for both testcases (the fold-const part is the only part required to fix the second testcase);
Index: fold-const.c
===================================================================
--- fold-const.c        (revision 126396)
+++ fold-const.c        (working copy)
@@ -3278,7 +3278,7 @@
 {
   tree t = fold_convert (type, result);
 
-  if (TREE_SIDE_EFFECTS (omitted))
+  if (folding_initializer || TREE_SIDE_EFFECTS (omitted))
     return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
 
   return non_lvalue (t);
@@ -3291,7 +3291,7 @@
 {
   tree t = fold_convert (type, result);
 
-  if (TREE_SIDE_EFFECTS (omitted))
+  if (folding_initializer || TREE_SIDE_EFFECTS (omitted))
     return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
 
   return pedantic_non_lvalue (t);
@@ -14438,6 +14438,10 @@
 tree
 fold_ignored_result (tree t)
 {
+  /* Just for now, if this is an initializer.   */
+  if (folding_initializer)
+    return t;
+
   if (!TREE_SIDE_EFFECTS (t))
     return integer_zero_node;
 
Index: c-typeck.c
===================================================================
--- c-typeck.c  (revision 126396)
+++ c-typeck.c  (working copy)
@@ -3783,7 +3783,8 @@
   enum tree_code coder;
   tree rname = NULL_TREE;
   bool objc_ok = false;
-
+  int old_folding_initializer;
+  
   if (errtype == ic_argpass || errtype == ic_argpass_nonproto)
     {
       tree selector;
@@ -3918,13 +3919,29 @@
           && (coder == INTEGER_TYPE || coder == REAL_TYPE
               || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE
               || coder == BOOLEAN_TYPE))
-    return convert_and_check (type, rhs);
+    {
+      tree new;
+      old_folding_initializer = folding_initializer;
+      if (errtype == ic_init)
+       folding_initializer = 1;
+      new = convert_and_check (type, rhs);
+      folding_initializer = old_folding_initializer;
+      return new;
+    }
 
   /* Aggregates in different TUs might need conversion.  */
   if ((codel == RECORD_TYPE || codel == UNION_TYPE)
       && codel == coder
       && comptypes (type, rhstype))
-    return convert_and_check (type, rhs);
+    {
+      tree new;
+      old_folding_initializer = folding_initializer;
+      if (errtype == ic_init)
+       folding_initializer = 1;
+      new = convert_and_check (type, rhs);
+      folding_initializer = old_folding_initializer;
+      return new;
+    }
 
   /* Conversion to a transparent union from its member types.
      This applies only to function arguments.  */
Comment 3 Manuel López-Ibáñez 2007-07-08 10:12:41 UTC
(In reply to comment #0)
> testcase, compile with -pedantic-errors (we don't reject it overwise in 4.3):
> unsigned char p;
> unsigned char p1 = p & 512;
> 
> Now there is an overflow but only because we optimize the IR (unsigned
> char)(((int)p)& 512) into:
> p & (unsigned char)512 and (unsigned char)512 is converted into 0 (with
> overflow) so we have p & 0 which is then optimized into 0(with overflow).  So
> we are only rejecting this because of the overflow due to the conversion (which
> was due to fold).

There should not be any overflow? So the result is wrong independently whether this is an initialization or not? The operation should be done with int, isn't it?  

BTW, you should get two warnings when using -pedantic.

> We don't reject as invalid code either:
> unsigned char p;
> unsigned char p1 = p & 0;

Why should we? There is no overflow here, you mean that p is not constant? I think we have two issues in the first testcase, one is folding (X op 0), the other is converting 512 to uchar before performing the operation. Am I wrong?

Comment 4 Andrew Pinski 2007-07-08 10:19:52 UTC
(In reply to comment #3)
> > We don't reject as invalid code either:
> > unsigned char p;
> > unsigned char p1 = p & 0;
> 
> Why should we? There is no overflow here, you mean that p is not constant? I
> think we have two issues in the first testcase, one is folding (X op 0), the
> other is converting 512 to uchar before performing the operation. Am I wrong?

Yes, the converting 512 to uchar is a valid optimization.  That is:
(char)(((int) a) & b)
is the same as:
a & ((char)b)
if a is of type char.
as there are no overflow concerns with AND.

The folding gets us to the case where we have "a & 0" which is not a valid constant initializer at all.

Note I found this while working on fixing PR 32628, where the patch which fixes that caues us to no longer emit a warning/error for the first testcase.
Comment 5 Richard Biener 2007-12-07 20:19:26 UTC
Confirmed.
Comment 6 Richard Biener 2008-03-14 16:52:15 UTC
Adjusting target milestone.
Comment 7 Richard Biener 2008-06-06 14:57:39 UTC
4.3.1 is being released, adjusting target milestone.
Comment 8 Joseph S. Myers 2008-08-27 22:02:24 UTC
4.3.2 is released, changing milestones to 4.3.3.
Comment 9 Manuel López-Ibáñez 2008-11-03 10:40:35 UTC
Andrew,

what is the status of this? 

Joseph, 

Will this be fixed by your new code for 4.5?
Comment 10 jsm-csl@polyomino.org.uk 2008-11-03 12:58:38 UTC
Subject: Re:  [4.2/4.3/4.4 Regression] Wrong error message with
 unsigned char a = uchar&512

On Mon, 3 Nov 2008, manu at gcc dot gnu dot org wrote:

> Joseph, 
> 
> Will this be fixed by your new code for 4.5?

As I said in <http://gcc.gnu.org/ml/gcc-patches/2008-10/msg01061.html>, 
that patch does not fix this bug.

Comment 11 Richard Biener 2009-01-24 10:19:51 UTC
GCC 4.3.3 is being released, adjusting target milestone.
Comment 12 Richard Biener 2009-08-04 12:28:18 UTC
GCC 4.3.4 is being released, adjusting target milestone.
Comment 13 Richard Biener 2010-05-22 18:11:39 UTC
GCC 4.3.5 is being released, adjusting target milestone.
Comment 14 Richard Biener 2011-03-04 12:41:30 UTC
Not fixed by the constant expression work either.
Comment 15 Richard Biener 2011-06-27 12:12:59 UTC
4.3 branch is being closed, moving to 4.4.7 target.
Comment 16 Jakub Jelinek 2012-03-13 12:45:43 UTC
4.4 branch is being closed, moving to 4.5.4 target.
Comment 17 Richard Biener 2012-07-02 11:43:48 UTC
The 4.5 branch is being closed, adjusting target milestone.
Comment 18 Jakub Jelinek 2013-04-12 15:16:07 UTC
GCC 4.6.4 has been released and the branch has been closed.
Comment 19 Richard Biener 2014-06-12 13:42:44 UTC
The 4.7 branch is being closed, moving target milestone to 4.8.4.
Comment 20 Jakub Jelinek 2014-12-19 13:32:40 UTC
GCC 4.8.4 has been released.
Comment 21 Manuel López-Ibáñez 2015-12-09 16:45:14 UTC
Not to sound pedantic, but https://gcc.gnu.org/bugs/management.html says:

The target milestone should be set to the next release of the newest active release branch that needs fixing (the rationale is that a patch will have to go to the newest release branch before any other release branch).

Thus, I think it should still be 6.0 until 6.1 is released.
Comment 22 Bernd Schmidt 2016-12-19 14:28:36 UTC
Ok, so I have a patch that makes the original testcase pass, by allowing folding in get_unwidened depening on a new arg. That was:

unsigned char p;
unsigned char p1 = p & 512;

But, how about

char p2 = p & 512;

Are we supposed to still warn about this (we do, with the patch I have)? Probably not, right?
Comment 23 Martin Sebor 2017-01-13 18:19:15 UTC
Bernd, intuitively, I would not expect a warning in the case you ask about.

-Woverflow is documented to "warn about compile-time overflow in constant expressions."  A strict reading of this single sentence would suggest that since none of the initialization expressions in the original test case is a constant expression no warning should be issued (and the initialization expressions should perhaps be diagnosed as not constant).

Alternatively, the documentation for the warning should explain what GCC considers a constant expression (if more than what's required by the C standard) and in what contexts and under what circumstances (e.g., per Josephs's description in the post referenced in comment #10).  Otherwise, what should or shouldn't be expected to be diagnosed is open to debate.

FWIW, to illustrate, GCC rejects some expressions with an error and not others based on what it considers a constant expression (i.e., what it folds).  In my view, that's more of a problem than the warning.

$ cat t.c && gcc t.c
unsigned char p;

char p2 = p & 512;
char p3 = p & 2;
t.c:3:11: warning: overflow in implicit constant conversion [-Woverflow]
 char p2 = p & 512;
           ^
t.c:4:11: error: initializer element is not constant
 char p3 = p & 2;
           ^

With -Wpedantic there is also a redundant warning:

t.c:3:11: warning: overflow in implicit constant conversion [-Woverflow]
 char p2 = p & 512;
           ^
t.c:3:1: warning: overflow in constant expression [-Woverflow]
 char p2 = p & 512;
 ^~~~
t.c:4:11: error: initializer element is not constant
 char p3 = p & 2;
           ^
Comment 24 Jakub Jelinek 2017-05-02 15:57:25 UTC
GCC 7.1 has been released.
Comment 25 Richard Biener 2018-01-25 08:22:11 UTC
GCC 7.3 is being released, adjusting target milestone.
Comment 26 Richard Biener 2019-11-14 07:55:29 UTC
The GCC 7 branch is being closed, re-targeting to GCC 8.4.
Comment 27 Jakub Jelinek 2020-03-04 09:49:38 UTC
GCC 8.4.0 has been released, adjusting target milestone.
Comment 28 Richard Biener 2020-05-20 07:41:22 UTC
Fixed on trunk sofar.
Comment 29 Richard Biener 2020-05-20 07:41:44 UTC
Sorry, wrong bug...
Comment 30 Martin Sebor 2021-01-29 22:26:37 UTC
No change in GCC 11:

$ cat pr32643.c && gcc -S -Wall -Wpedantic pr32643.c
unsigned char p;
unsigned char p1 = p & 512;
pr32643.c:2:20: warning: overflow in conversion from ‘int’ to ‘unsigned char’ changes value from ‘(int)p & 512’ to ‘0’ [-Woverflow]
    2 | unsigned char p1 = p & 512;
      |                    ^
pr32643.c:2:1: warning: overflow in constant expression [-Woverflow]
    2 | unsigned char p1 = p & 512;
      | ^~~~~~~~
Comment 31 Jakub Jelinek 2021-05-14 09:45:49 UTC
GCC 8 branch is being closed.
Comment 32 Richard Biener 2021-06-01 08:04:31 UTC
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
Comment 33 Richard Biener 2022-05-27 09:33:47 UTC
GCC 9 branch is being closed
Comment 34 Jakub Jelinek 2022-06-28 10:29:27 UTC
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
Comment 35 Richard Biener 2023-07-07 10:28:53 UTC
GCC 10 branch is being closed.
Comment 36 Richard Biener 2024-07-19 12:54:18 UTC
GCC 11 branch is being closed.