Message ID | 20170525100700.GU12306@redhat.com |
---|---|
State | New |
Headers | show |
On 25/05/17 11:07 +0100, Jonathan Wakely wrote: >On 25/05/17 10:05 +0200, Andreas Schwab wrote: >>../../gcc/ada/gcc-interface/utils2.c: In function 'int compare_elmt_bitpos(const void*, const void*)': >>../../gcc/ada/gcc-interface/utils2.c:1937:73: error: type qualifiers ignored on cast result type [-Werror=ignored-qualifiers] >> const constructor_elt * const elmt1 = (const constructor_elt * const) rt1; >> ^~~ >>../../gcc/ada/gcc-interface/utils2.c:1938:73: error: type qualifiers ignored on cast result type [-Werror=ignored-qualifiers] >> const constructor_elt * const elmt2 = (const constructor_elt * const) rt2; > >I'm testing this obvious fix. Committed as r248458 because it gets bootstrap past the error above, although now Ada fails for me with: /home/jwakely/src/gcc/bootstrap/./gcc/xgcc -B/home/jwakely/src/gcc/bootstrap/./gcc/ -B/usr/local/x86_64-pc-linux-gnu/bin/ -B/usr/local/x86_64-pc-linux-gnu/lib/ -isystem /usr/local/x86_64-pc-linux-gnu/include -isystem /usr/local/x86_64-pc-linux-gnu/sys-include -c -g -O2 -m32 -fpic -W -Wall -gnatpg -nostdinc -m32 s-regpat.adb -o s-regpat.o raised STORAGE_ERROR : stack overflow or erroneous memory access ../gcc-interface/Makefile:296: recipe for target 's-regpat.o' failed >diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c >index fc6f1b8..cd37791 100644 >--- a/gcc/ada/gcc-interface/utils2.c >+++ b/gcc/ada/gcc-interface/utils2.c >@@ -1934,8 +1934,8 @@ build_call_raise_range (int msg, Node_Id gnat_node, char kind, > static int > compare_elmt_bitpos (const PTR rt1, const PTR rt2) > { >- const constructor_elt * const elmt1 = (const constructor_elt * const) rt1; >- const constructor_elt * const elmt2 = (const constructor_elt * const) rt2; >+ const constructor_elt * const elmt1 = (const constructor_elt *) rt1; >+ const constructor_elt * const elmt2 = (const constructor_elt *) rt2; > const_tree const field1 = elmt1->index; > const_tree const field2 = elmt2->index; > const int ret
On Thu, May 25, 2017 at 03:02:42PM +0100, Jonathan Wakely wrote: > On 25/05/17 11:07 +0100, Jonathan Wakely wrote: > > On 25/05/17 10:05 +0200, Andreas Schwab wrote: > > > ../../gcc/ada/gcc-interface/utils2.c: In function 'int compare_elmt_bitpos(const void*, const void*)': > > > ../../gcc/ada/gcc-interface/utils2.c:1937:73: error: type qualifiers ignored on cast result type [-Werror=ignored-qualifiers] > > > const constructor_elt * const elmt1 = (const constructor_elt * const) rt1; > > > ^~~ > > > ../../gcc/ada/gcc-interface/utils2.c:1938:73: error: type qualifiers ignored on cast result type [-Werror=ignored-qualifiers] > > > const constructor_elt * const elmt2 = (const constructor_elt * const) rt2; > > > > I'm testing this obvious fix. > > Committed as r248458 because it gets bootstrap past the error above, > although now Ada fails for me with: > > /home/jwakely/src/gcc/bootstrap/./gcc/xgcc -B/home/jwakely/src/gcc/bootstrap/./gcc/ -B/usr/local/x86_64-pc-linux-gnu/bin/ -B/usr/local/x86_64-pc-linux-gnu/lib/ -isystem /usr/local/x86_64-pc-linux-gnu/include -isystem /usr/local/x86_64-pc-linux-gnu/sys-include -c -g -O2 -m32 -fpic -W -Wall -gnatpg -nostdinc -m32 s-regpat.adb -o s-regpat.o > > raised STORAGE_ERROR : stack overflow or erroneous memory access > ../gcc-interface/Makefile:296: recipe for target 's-regpat.o' failed > > > > diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c > > index fc6f1b8..cd37791 100644 > > --- a/gcc/ada/gcc-interface/utils2.c > > +++ b/gcc/ada/gcc-interface/utils2.c > > @@ -1934,8 +1934,8 @@ build_call_raise_range (int msg, Node_Id gnat_node, char kind, > > static int > > compare_elmt_bitpos (const PTR rt1, const PTR rt2) > > { > > - const constructor_elt * const elmt1 = (const constructor_elt * const) rt1; > > - const constructor_elt * const elmt2 = (const constructor_elt * const) rt2; > > + const constructor_elt * const elmt1 = (const constructor_elt *) rt1; > > + const constructor_elt * const elmt2 = (const constructor_elt *) rt2; > > const_tree const field1 = elmt1->index; > > const_tree const field2 = elmt2->index; > > const int ret So, what can one do with typeof or similar to avoid the warning? void foo (const void *p) { const int *const q = (const int *const) p; typeof (q) r = (typeof (q)) p; (void) q; (void) r; } AFAIK typeof doesn't strip the toplevel qualifiers and I see current trunk warns even about the cast in r initialization. Similarly to what has been noted recently in another (C) PR, it would be nice if we had toplevel cv stripping variant of typeof or some special builtin that could wrap typeof or some type and could be used in places where typeof can, __strip_cv (typeof (q)) = (__strip_cv (typeof (q))) p; or typeof (q) = (__strip_cv (typeof (q))) p; or __strip_cv (const int *const) z; where the last one would be effectively const int *z; Jakub
On Thu, May 25, 2017 at 04:11:19PM +0200, Jakub Jelinek wrote: > So, what can one do with typeof or similar to avoid the warning? > > void > foo (const void *p) > { > const int *const q = (const int *const) p; > typeof (q) r = (typeof (q)) p; > (void) q; > (void) r; > } > > AFAIK typeof doesn't strip the toplevel qualifiers and I see current trunk > warns even about the cast in r initialization. Similarly to what has been > noted recently in another (C) PR, it would be nice if we had toplevel cv > stripping variant of typeof or some special builtin that could wrap > typeof or some type and could be used in places where typeof can, > __strip_cv (typeof (q)) = (__strip_cv (typeof (q))) p; > or > typeof (q) = (__strip_cv (typeof (q))) p; > or > __strip_cv (const int *const) z; > where the last one would be effectively > const int *z; I guess in C++ one can use typeof (q) r = (remove_cv <typeof (q)>::type) p; or something similar, but in C there is nothing like that. Jakub
On Thu, May 25, 2017 at 04:11:19PM +0200, Jakub Jelinek wrote: > On Thu, May 25, 2017 at 03:02:42PM +0100, Jonathan Wakely wrote: > > On 25/05/17 11:07 +0100, Jonathan Wakely wrote: > > > On 25/05/17 10:05 +0200, Andreas Schwab wrote: > > > > ../../gcc/ada/gcc-interface/utils2.c: In function 'int compare_elmt_bitpos(const void*, const void*)': > > > > ../../gcc/ada/gcc-interface/utils2.c:1937:73: error: type qualifiers ignored on cast result type [-Werror=ignored-qualifiers] > > > > const constructor_elt * const elmt1 = (const constructor_elt * const) rt1; > > > > ^~~ > > > > ../../gcc/ada/gcc-interface/utils2.c:1938:73: error: type qualifiers ignored on cast result type [-Werror=ignored-qualifiers] > > > > const constructor_elt * const elmt2 = (const constructor_elt * const) rt2; > > > > > > I'm testing this obvious fix. > > > > Committed as r248458 because it gets bootstrap past the error above, > > although now Ada fails for me with: > > > > /home/jwakely/src/gcc/bootstrap/./gcc/xgcc -B/home/jwakely/src/gcc/bootstrap/./gcc/ -B/usr/local/x86_64-pc-linux-gnu/bin/ -B/usr/local/x86_64-pc-linux-gnu/lib/ -isystem /usr/local/x86_64-pc-linux-gnu/include -isystem /usr/local/x86_64-pc-linux-gnu/sys-include -c -g -O2 -m32 -fpic -W -Wall -gnatpg -nostdinc -m32 s-regpat.adb -o s-regpat.o > > > > raised STORAGE_ERROR : stack overflow or erroneous memory access > > ../gcc-interface/Makefile:296: recipe for target 's-regpat.o' failed > > > > > > > diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c > > > index fc6f1b8..cd37791 100644 > > > --- a/gcc/ada/gcc-interface/utils2.c > > > +++ b/gcc/ada/gcc-interface/utils2.c > > > @@ -1934,8 +1934,8 @@ build_call_raise_range (int msg, Node_Id gnat_node, char kind, > > > static int > > > compare_elmt_bitpos (const PTR rt1, const PTR rt2) > > > { > > > - const constructor_elt * const elmt1 = (const constructor_elt * const) rt1; > > > - const constructor_elt * const elmt2 = (const constructor_elt * const) rt2; > > > + const constructor_elt * const elmt1 = (const constructor_elt *) rt1; > > > + const constructor_elt * const elmt2 = (const constructor_elt *) rt2; > > > const_tree const field1 = elmt1->index; > > > const_tree const field2 = elmt2->index; > > > const int ret > > So, what can one do with typeof or similar to avoid the warning? > > void > foo (const void *p) > { > const int *const q = (const int *const) p; > typeof (q) r = (typeof (q)) p; > (void) q; > (void) r; > } > > AFAIK typeof doesn't strip the toplevel qualifiers and I see current trunk > warns even about the cast in r initialization. Similarly to what has been > noted recently in another (C) PR, it would be nice if we had toplevel cv > stripping variant of typeof or some special builtin that could wrap > typeof or some type and could be used in places where typeof can, > __strip_cv (typeof (q)) = (__strip_cv (typeof (q))) p; > or > typeof (q) = (__strip_cv (typeof (q))) p; > or > __strip_cv (const int *const) z; > where the last one would be effectively > const int *z; I remember trying to implement the stripping version of __typeof; I even had a prototype patch that I'm of course not finding right now, but I'd be happy to work on this again. Ok, I at least found the PR: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65455 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39985 Also there's https://gcc.gnu.org/ml/gcc-patches/2016-02/msg00268.html Let me know if I should get back to it. Marek
On 25/05/17 16:11 +0200, Jakub Jelinek wrote: >On Thu, May 25, 2017 at 03:02:42PM +0100, Jonathan Wakely wrote: >> On 25/05/17 11:07 +0100, Jonathan Wakely wrote: >> > On 25/05/17 10:05 +0200, Andreas Schwab wrote: >> > > ../../gcc/ada/gcc-interface/utils2.c: In function 'int compare_elmt_bitpos(const void*, const void*)': >> > > ../../gcc/ada/gcc-interface/utils2.c:1937:73: error: type qualifiers ignored on cast result type [-Werror=ignored-qualifiers] >> > > const constructor_elt * const elmt1 = (const constructor_elt * const) rt1; >> > > ^~~ >> > > ../../gcc/ada/gcc-interface/utils2.c:1938:73: error: type qualifiers ignored on cast result type [-Werror=ignored-qualifiers] >> > > const constructor_elt * const elmt2 = (const constructor_elt * const) rt2; >> > >> > I'm testing this obvious fix. >> >> Committed as r248458 because it gets bootstrap past the error above, >> although now Ada fails for me with: >> >> /home/jwakely/src/gcc/bootstrap/./gcc/xgcc -B/home/jwakely/src/gcc/bootstrap/./gcc/ -B/usr/local/x86_64-pc-linux-gnu/bin/ -B/usr/local/x86_64-pc-linux-gnu/lib/ -isystem /usr/local/x86_64-pc-linux-gnu/include -isystem /usr/local/x86_64-pc-linux-gnu/sys-include -c -g -O2 -m32 -fpic -W -Wall -gnatpg -nostdinc -m32 s-regpat.adb -o s-regpat.o >> >> raised STORAGE_ERROR : stack overflow or erroneous memory access >> ../gcc-interface/Makefile:296: recipe for target 's-regpat.o' failed >> >> >> > diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c >> > index fc6f1b8..cd37791 100644 >> > --- a/gcc/ada/gcc-interface/utils2.c >> > +++ b/gcc/ada/gcc-interface/utils2.c >> > @@ -1934,8 +1934,8 @@ build_call_raise_range (int msg, Node_Id gnat_node, char kind, >> > static int >> > compare_elmt_bitpos (const PTR rt1, const PTR rt2) >> > { >> > - const constructor_elt * const elmt1 = (const constructor_elt * const) rt1; >> > - const constructor_elt * const elmt2 = (const constructor_elt * const) rt2; >> > + const constructor_elt * const elmt1 = (const constructor_elt *) rt1; >> > + const constructor_elt * const elmt2 = (const constructor_elt *) rt2; >> > const_tree const field1 = elmt1->index; >> > const_tree const field2 = elmt2->index; >> > const int ret > >So, what can one do with typeof or similar to avoid the warning? > >void >foo (const void *p) >{ > const int *const q = (const int *const) p; > typeof (q) r = (typeof (q)) p; > (void) q; > (void) r; >} I'd probably write that like this instead: void foo (const void *p) { typedef const int* ptr_type; ptr_type const q = (ptr_type) p; ptr_type const r = (ptr_type) p; (void) q; (void) r; } It names the type only once, not twice as in your example, and doesn't need to use typeof to refer to that type again. The variables p and q are defined const, which is what's wanted. The cast is to ptr_type, not ptr_type const.
On Thu, May 25, 2017 at 03:52:47PM +0100, Jonathan Wakely wrote: > I'd probably write that like this instead: > > void > foo (const void *p) > { > typedef const int* ptr_type; > ptr_type const q = (ptr_type) p; > ptr_type const r = (ptr_type) p; > (void) q; > (void) r; > } > > It names the type only once, not twice as in your example, and doesn't > need to use typeof to refer to that type again. That was over-simplified, I meant cases where you actually don't know the exact type, just use typeof to create a variable of such a type and then want to cast something to that type. Jakub
On 25/05/17 16:56 +0200, Jakub Jelinek wrote: >On Thu, May 25, 2017 at 03:52:47PM +0100, Jonathan Wakely wrote: >> I'd probably write that like this instead: >> >> void >> foo (const void *p) >> { >> typedef const int* ptr_type; >> ptr_type const q = (ptr_type) p; >> ptr_type const r = (ptr_type) p; >> (void) q; >> (void) r; >> } >> >> It names the type only once, not twice as in your example, and doesn't >> need to use typeof to refer to that type again. > >That was over-simplified, I meant cases where you actually don't know the >exact type, just use typeof to create a variable of such a type and >then want to cast something to that type. The most obvious case I can think of where you don't know the type would be the result of some expression (maybe involving overloaded operators, or a call to an overloaded function). In that case: typeof (expr) const q = (typeof (expr)) p; Again, add the const to the variable definition, but not the cast. or using a typedef again for clarity and to avoid the repetition: typedef typeof (expr) the_type; the_type const q = (the_type) p; If the result of the expression is a scalar type then it won't be const-qualified, so the_type isn't either, and the cast won't warn. If the result of the expression is a class-type then it can be const-qualified, and so the_type is also const-qualified, but the warning isn't issued in such case. All the realistic case I can think of expr won't be simply a variable (because if you have a variable then it was already declared with some type and you can refer to that type directly) so the original problem where typeof(q) deduces a const-qualified type won't happen. template<typename T> void f (const T& t, const void* p) { // no need for typeof(t) because we can just use T T* const q = (T*)p; T* const r = (T*)p; } There's this case, which will warn if the type is a pointer or other scalar: auto const q = some_function (p); typeof (q) r = (typeof (q)) p But what you really care about is typeof (some_function (p)) not typeof (q), which is just the 'expr' case above: typedef typeof (some_function(p)) ptr_type; ptr_type const q = some_function (p); ptr_type const r = (ptr_type)p; The warning is avoidable by using typeof on the expression that determines the type, not on a variable that has a const-qualified version of the type.
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index fc6f1b8..cd37791 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -1934,8 +1934,8 @@ build_call_raise_range (int msg, Node_Id gnat_node, char kind, static int compare_elmt_bitpos (const PTR rt1, const PTR rt2) { - const constructor_elt * const elmt1 = (const constructor_elt * const) rt1; - const constructor_elt * const elmt2 = (const constructor_elt * const) rt2; + const constructor_elt * const elmt1 = (const constructor_elt *) rt1; + const constructor_elt * const elmt2 = (const constructor_elt *) rt2; const_tree const field1 = elmt1->index; const_tree const field2 = elmt2->index; const int ret