Bug 39985 - Type qualifiers not actually ignored on function return type
Summary: Type qualifiers not actually ignored on function return type
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: ---
Assignee: Marek Polacek
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2009-04-30 23:44 UTC by Anders Kaseorg
Modified: 2018-01-31 15:30 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-07-25 00:00:00


Attachments
Test case - g++ -Wignored-qualifiers test.C gives confusing results (188 bytes, text/plain)
2009-11-21 12:24 UTC, Magnus Fromreide
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Anders Kaseorg 2009-04-30 23:44:55 UTC
The warning printed with -Wignored-qualifiers (“warning: type qualifiers ignored on function return type”) seems to be lying.  The const on a function’s return type is not actually ignored, as can be demonstrated using typeof().  I think that the warning should be right and the typeof() behavior is wrong, but I’m not actually sure.

int f(void);
const int g(void);  /* warning: type qualifiers ignored on function return type */
typeof(f()) a;
a = 5;
typeof(g()) b;
b = 5;  /* error: assignment of read-only variable ‘b’ */

Another thing that seems similarly strange is that a statement expression can return a const type, even though it is not an lvalue:

const int x = 5;
typeof( ({ x; }) ) y;
y = 5;  /* error: assignment of read-only variable ‘y’ */
Comment 1 Magnus Fromreide 2009-11-21 12:24:35 UTC
Created attachment 19074 [details]
Test case - g++ -Wignored-qualifiers test.C gives confusing results

In C++ it becomes even worse since the types are used more.

As it stands right now it becomes ridiculous:

$ g++ -Wignored-qualifiers test.C
test.C:12: warning: type qualifiers ignored on function return type
test.C:12: error: conflicting return type specified for ‘virtual const int D1::F()’
test.C:5: error:   overriding ‘virtual int B1::F()’
test.C:20: warning: type qualifiers ignored on function return type
test.C:27: error: conflicting return type specified for ‘virtual int D2::F()’
test.C:20: error:   overriding ‘virtual const int B2::F()’

Are the type qualifiers ignored or are they not?
Comment 2 Joseph S. Myers 2009-11-22 20:24:02 UTC
If you wish to report a C++ bug, it needs to have component "c++" and be
a separate bug from any bug report for C front-end issues; comments
about possible C++ front-end issues in "c" bugs are irrelevant except insofar
as they illuminate questions of what the C front end should do.

For C, the qualifiers are ignored as far as standard terms are concerned.
Whether typeof applied to an rvalue in GNU C has a qualified types is
fundamentally confused at present; my inclination is that we should
eliminate the inconsistent attempts to give rvalues qualified types in
some cases, and say that if the operand of typeof is not an lvalue it
never has a qualified type.
Comment 3 Anders Kaseorg 2009-11-27 07:33:11 UTC
> my inclination is that we should eliminate the inconsistent attempts to give
> rvalues qualified types in some cases, and say that if the operand of typeof
> is not an lvalue it never has a qualified type.

Should typeof ever return a qualified type?  It is easy to add qualifiers to a type if they are desired (const typeof(foo)), but seems difficult to remove them.

For example, seemingly reasonable macros like
  #define MAX(__x, __y) ({           \
      typeof(__x) __ret = __x;       \
      if (__y > __ret) __ret = __y;  \
      __ret;                         \
  })
currently fail when given a qualified argument:
  const int c = 42;
  MAX(c, 17);  /* error: assignment of read-only variable ‘__ret’ */

This bug report was motivated by my attempts to fix a macro like this, by replacing typeof(__x) with something that strips qualifiers.  These all fail to strip qualifiers:
  typeof( ({ __x; }) )
  typeof( ((typeof(__x)(*)(void)) 0)() )
  typeof( (typeof(__x)) (__x) )
This seems to work, but only for numeric and pointer types:
  typeof( (typeof(__x)) 0 )
This succeeds at stripping qualifiers for numeric types, but for some reason it promotes char and short to int, and it fails to strip qualifiers for non-numeric types:
  typeof( 1 ? (__x) : (__x) )

Much confusion would be avoided if typeof(__x) just stripped qualifiers to begin with.
Comment 4 Eric Gallager 2017-07-25 18:21:11 UTC
(In reply to Anders Kaseorg from comment #3)
> > my inclination is that we should eliminate the inconsistent attempts to give
> > rvalues qualified types in some cases, and say that if the operand of typeof
> > is not an lvalue it never has a qualified type.
> 
> Should typeof ever return a qualified type?  It is easy to add qualifiers to
> a type if they are desired (const typeof(foo)), but seems difficult to
> remove them.
> 
> For example, seemingly reasonable macros like
>   #define MAX(__x, __y) ({           \
>       typeof(__x) __ret = __x;       \
>       if (__y > __ret) __ret = __y;  \
>       __ret;                         \
>   })
> currently fail when given a qualified argument:
>   const int c = 42;
>   MAX(c, 17);  /* error: assignment of read-only variable ‘__ret’ */
> 
> This bug report was motivated by my attempts to fix a macro like this, by
> replacing typeof(__x) with something that strips qualifiers.  These all fail
> to strip qualifiers:
>   typeof( ({ __x; }) )
>   typeof( ((typeof(__x)(*)(void)) 0)() )
>   typeof( (typeof(__x)) (__x) )
> This seems to work, but only for numeric and pointer types:
>   typeof( (typeof(__x)) 0 )
> This succeeds at stripping qualifiers for numeric types, but for some reason
> it promotes char and short to int, and it fails to strip qualifiers for
> non-numeric types:
>   typeof( 1 ? (__x) : (__x) )
> 
> Much confusion would be avoided if typeof(__x) just stripped qualifiers to
> begin with.

Related: bug 65455. Marek Polacek has been posting patches to the gcc-patches mailing list towards solving this; latest message in the chain was:
https://gcc.gnu.org/ml/gcc-patches/2017-07/msg01146.html
Assigning this to him since he's already been working on it anyways.
Comment 5 joseph@codesourcery.com 2017-07-31 21:47:10 UTC
In C, in C11 mode, type qualifiers are completely ignored on function 
return types, including not affecting type compatibility, after my commit:

r236231 | jsm28 | 2016-05-13 21:35:39 +0000 (Fri, 13 May 2016) | 46 lines

Implement C11 DR#423 resolution (ignore function return type qualifiers).