Summary: | va_list is automatically taken address-of when passed as argument | ||
---|---|---|---|
Product: | gcc | Reporter: | Olof Lindholm <olof.lindholm> |
Component: | target | Assignee: | Andreas Jaeger <aj> |
Status: | RESOLVED INVALID | ||
Severity: | normal | CC: | gcc-bugs, gcc, ian-gccbug, jh, jkain, msebor |
Priority: | P2 | Keywords: | diagnostic, rejects-valid |
Version: | 3.3.3 | ||
Target Milestone: | --- | ||
Host: | x86_64-suse-linux | Target: | x86_64-suse-linux |
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | ||
Attachments: |
output of -show-temps
source file |
Description
Olof Lindholm
2004-03-12 16:17:19 UTC
Created attachment 5908 [details]
output of -show-temps
Created attachment 5909 [details]
source file
Can you provide the output of "gcc -v" as it works for me on powerpc-apple-darwin7.2.0 and i686-pc- linux-gnu? gcc -v Reading specs from /localhome/mygcc/bin/../lib/gcc-lib/x86_64-unknown-linux-gnu/3.3.3/specs Configured with: ./configure Thread model: posix gcc version 3.3.3 I have not seen to problem on any other platform than x86_64. Have tried the specific microprogram on ia32-redhat-linux and it worked, but I only have an older version of gcc there (2.95.3) Andreas said he would take care of it next week. AFAIK it is incorrect to use "va_list *" so the code is wrong. va_list is allowed to be something different that a pointer, for example on ppc64 and x86-64 it is an one element array (builtin type). Arrays are always passed as a pointer to the first element so there is no performance penalty. AFAIK using "&marker" where marker is va_list is wrong too. See the discussion when we were fixing vasprintf.c from libiberty http://gcc.gnu.org/ml/gcc-patches/2003-10/msg00219.html Subject: Re: va_list is automatically taken address-of when passed as argument "zlomek at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: > ------- Additional Comments From zlomek at gcc dot gnu dot org 2004-03-13 06:10 ------- > AFAIK it is incorrect to use "va_list *" so the code is wrong. I don't see anything wrong with using "va_list *". The standard even says: It is permitted to create a pointer to a va_list and pass that pointer to another function, in which case the original function may make further use of the original list after the other function returns. About passing by value it says: The object ap may be passed as an argument to another function; if that function invokes the va_arg macro with parameter ap, the value of ap in the calling function is indeterminate and shall be passed to the va_end macro prior to any further reference to ap. Well, it doesn't invoke va_arg, so that should be fine, too. Subject: Re: va_list is automatically taken address-of when passed as argument > > ------- Additional Comments From falk dot hueffner at student dot uni-tuebingen dot de 2004-03-13 12:15 ------- > Subject: Re: va_list is automatically taken address-of > when passed as argument > > "zlomek at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: > > > ------- Additional Comments From zlomek at gcc dot gnu dot org 2004-03-13 06:10 ------- > > AFAIK it is incorrect to use "va_list *" so the code is wrong. > > I don't see anything wrong with using "va_list *". The standard even says: > > It is permitted to create a pointer to a va_list and pass that > pointer to another function, in which case the original function > may make further use of the original list after the other > function returns. > > About passing by value it says: My recollection from last time we were discussing this is that text above is an footnote that is not normative and in conflict with rest of the standard, so it needs to be ignored. While I agree that this behaviour is very unfortuante side effect of va-arg implementation, there are some other ABIS around (PPC SysV) doing the same so the only choice now is probably to avoid this construct. Honza > > The object ap may be passed as an argument to another function; > if that function invokes the va_arg macro with parameter ap, the > value of ap in the calling function is indeterminate and shall be > passed to the va_end macro prior to any further reference to ap. > > Well, it doesn't invoke va_arg, so that should be fine, too. > > > > -- > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14557 > > ------- You are receiving this mail because: ------- > You are on the CC list for the bug, or are watching someone who is. Subject: Re: va_list is automatically taken address-of when passed as argument "jh at suse dot cz" <gcc-bugzilla@gcc.gnu.org> writes: > My recollection from last time we were discussing this is that text > above is an footnote that is not normative and in conflict with rest of > the standard, so it needs to be ignored. Okay, let's say we ignore it. Which part of the standard is violated then? Subject: Re: va_list is automatically taken address-of
when passed as argument
On Sat, 13 Mar 2004, falk dot hueffner at student dot uni-tuebingen dot de wrote:
> I don't see anything wrong with using "va_list *". The standard even says:
There's nothing wrong with using va_list *, the only problem is when
taking the address of a parameter to do so.
With a variable
va_list ap;
you use &ap to take the address.
With a parameter (subject to array-to-pointer adjustment)
va_list ap
you use &ap if va_list is not an array type, but ap if it is an array
type.
Subject: Re: va_list is automatically taken address-of when passed as argument "jsm at polyomino dot org dot uk" <gcc-bugzilla@gcc.gnu.org> writes: > ------- Additional Comments From jsm at polyomino dot org dot uk 2004-03-13 13:22 ------- > There's nothing wrong with using va_list *, the only problem is when > taking the address of a parameter to do so. > > With a variable > > va_list ap; > > you use &ap to take the address. > > With a parameter (subject to array-to-pointer adjustment) > > va_list ap > > you use &ap if va_list is not an array type, but ap if it is an > array type. Ah, I see. Thanks. Subject: Re: va_list is automatically taken address-of when passed as argument &ap should always work; taking the address of an array produces a pointer to the array, which has a different type but the same value as the pointer to the first element that you get if you don't take the address. You have to write *ap in the callee, is all. As far as I can see the original example is strictly conforming and the warning should not be issued. zw Subject: Re: va_list is automatically taken address-of
when passed as argument
On Sat, 13 Mar 2004, zack at codesourcery dot com wrote:
> &ap should always work; taking the address of an array produces a
> pointer to the array, which has a different type but the same value as
> the pointer to the first element that you get if you don't take the
> address. You have to write *ap in the callee, is all.
The trouble is that in this example you're taking the address of a pointer
to the first element of the array (namely, the parameter declared with the
array type va_list which has pointer type because of the adjustment of
parameter types).
Subject: Re: va_list is automatically taken address-of when passed as argument "jsm at polyomino dot org dot uk" <gcc-bugzilla@gcc.gnu.org> writes: > The trouble is that in this example you're taking the address of a > pointer to the first element of the array (namely, the parameter > declared with the array type va_list which has pointer type because > of the adjustment of parameter types). Ah, so what's unportable is taking the address of a va_list which has been passed to you as a value parameter? This I can see. zw *** Bug 20951 has been marked as a duplicate of this bug. *** *** Bug 8262 has been marked as a duplicate of this bug. *** *** Bug 26294 has been marked as a duplicate of this bug. *** *** Bug 27534 has been marked as a duplicate of this bug. *** The number of duplicates of this report isn't terribly high, but doesn't this at least deserve a mention in the 'Disappointments' section of the manual? In any case, the following macro could be used as a workaround, under some rather reasonable assumptions: #if __STDC_VERSION__ >= 201112L #define va_ptr(ap) _Generic(&(ap), va_list *: &(ap), default: (va_list *)(ap)) #elif __GNUC__ >= 4 #define va_ptr(ap) __builtin_choose_expr(__builtin_types_compatible_p(__typeof__(&(ap)), va_list *), &(ap), (va_list *)(ap)) #else #define va_ptr(ap) (sizeof(ap) == sizeof(va_list) ? (va_list *)&(ap) : (va_list *)(ap)) #endif The main assumption is that a pointer to an array is the same as a pointer to its zeroth element, i.e. when we have a variable T array[N]; then (&array == (T (*)[N])array); or at least that this holds for the array type that va_list is. I don't see anything in the C standard that would explicitly guarantee this, but this should be a safe assumption to make, because breaking it would presumably make the following memcpy calls non-equivalent: T array0[N], array1[N]; memcpy(array1, array0, sizeof(array0)); memcpy(&array1, array0, sizeof(array0)); memcpy(array1, &array0, sizeof(array0)); memcpy(&array1, &array0, sizeof(array0)); which would be strange. Furthermore, the last version will break in the presence of va_list defined like typedef void *va_list[1]; typedef char va_list[sizeof(char *)]; but I think it's reasonable to assume that no ABI standard is going to prescribe something like this. None of the targets currently supported by GCC do. (In reply to felix from comment #19) > The number of duplicates of this report isn't terribly high, but doesn't > this at least deserve a mention in the 'Disappointments' section of the > manual? > > In any case, the following macro could be used as a workaround, under some > rather reasonable assumptions: > > #if __STDC_VERSION__ >= 201112L > #define va_ptr(ap) _Generic(&(ap), va_list *: &(ap), default: (va_list > *)(ap)) ... the standard conform way to deal with this issue is to va_list ap2; va_copy(ap2, ap); and then use &ap2, this always works. the proposed macros are both broken and unnecessary. > va_list ap2; > va_copy(ap2, ap); > and then use &ap2, this always works. > the proposed macros are both broken and unnecessary. That's not equivalent. Using va_arg(ap2, T) does not propagate state changes back to ap, which is the main motivation to form a pointer to ap in the first place. The macros do that just fine. You mean they are unportable? That part is true, I admitted as much. Pick your poison. As for being unnecessary, I vaguely remember gnulib trying to use internal helper functions with va_list * parameter in their vfprintf implementation. I cannot find the link now, unfortunately. But there are also duplicates to this very report, so clearly the need is there. Your email was bounced... ------------------------- ... because something went wrong between you and your recipient. Oh no! What to do next? ---------------- Well, your specific problem was a *5.1.2 * error. Which means you should: Check the "flash-gordon.me.uk" part of "gcc@flash-gordon.me.uk" for misspellings or missing letters. If you find an error, correct it in your contacts list or address book for next time. Or further: It is possible that the domain is temporarily inactive. If the spelling looks correct, contact your mail provider and if necessary, contact your recipient another way (e.g., phone or text message). Get more help on 5.1.2 errors here![1] Thanks, have a lovely day. Yours truly, betterbounces.net[2] Rate this email: Helpful[3] :) or... Not Helpful[4] :( Advertisement | Prefer no ads?[5] Learn more about RevenueStripe... [6] [7] --------------------------------------------------------------------- © 2017 betterbounces.net, All rights reserved. Privacy[8] [IMAGE] [IMAGE] [IMAGE] [IMAGE] [IMAGE] 1. https://a.b-io.me/c/Y1lM9w9S1Kcyhmff9PUym3lzb4DFXoKjbQxPz_NW_WrQaWlkIsfqBNRgrwhzFkMcrwIXvcetvsZyskw3ba6cO13ry35GacumgC9FOm4QkNXaAORBfGNI9XaxlUM1jCpXwWSsHd4hBnlo3Ep2ClCJZR4F_2_Z944RQ_Ff1Hlr7qC5AubVwp4npLVx_SJUN89AI6R8sJU6BcnDevdyvtmr3XLv1zMnoJcUo9jOL4SdRznpTxVFk4gP6m8fUQOpJB.mCOXnPq7M.5.wEjbngsCiw9exDqQLI9eWwPLzORZhDw9W5V3M6SSy9ACeUE20ncsQuzenNfjXo4dd68t_RmnLpoAvRTpuEJDV4Lmq8o6zs9Abcgz_kivUcOhyaVuawoG6M11eQELWLpH0Vs8NmgE3MY0TiDO3KU_V7w0eHjri9.twOAjjam3qwa1jLaAvk31Y5x2e.65D9k7fK9V0PT4wI5Vx5wMoLgN7BUrvnfnF3YZJzSk9BM9xI3Ke3BiT6f4z 2. https://a.b-io.me/c/Y1lM9w9S1Kcyhmff9PUym3lzb4DFXoKjbQxPz_NW_WrQaWlkIsfqBNRgrwhzFkMcrwIXvcetvsZyskw3ba6cO13ry35GacumgC9FOm4QkNXaAORBfGNI9XaxlUM1jCpXwWSsHd4hBnlo3Ep2ClCJZR4F_2_Z944RQ_Ff1Hlr7qC5AubVwp4npLVx_SJUN89AI6R8sJU6BcnOFzLscYDd_muBr0cqfVNXlAl73cWA7IEKNcxgbpC49DF.K_iHE4RwTSVvdmLIBNY7YexqWgPQgytJT9.x.rSqRNsT01JDgKk5i3vc0Jo.GX7ip_SABKQbP2D9EwQZROeSf8LgvA6Bm6.smm7wWn96mtx_vbla9ds- 3. https://a.b-io.me/c/Y1lM9w9S1Kcyhmff9PUym3lzb4DFXoKjbQxPz_NW_WrQaWlkIsfqBNRgrwhzFkMcrwIXvcetvsZyskw3ba6cO13ry35GacumgC9FOm4QkNXaAORBfGNI9XaxlUM1jCpXwWSsHd4hBnlo3Ep2ClCJZR4F_2_Z944RQ_Ff1Hlr7qC5AubVwp4npLVx_SJUN89AI6R8sJU6BcnDevdyvtmr3SQCfDh9Nllm1xxkirU9iGeJRMIJCeh4_rhv8rSXZms8yV1cHIIO.DQHsbSiSXFFFwiIXVDY97IzEM2xKAcTY43fK9V0PT4wI5Vx5wMoLgN7BUrvnfnF3YZJzSk9BM9xIw1m1d7bBy4hf1IHxzL2mRzWLv9AFWPezwk_1D5f8BNpdyC560RQkF51r0i2tp95k0dMw9RD4ed6GYKls.oEbv9uyjjLmKbT9Z.wWV1osAHxEegkm0owPMW9YCxKQu84jWuwZdR7HRXoK76JsqyBH4bNNv1dlOjg3cVUlP4jpqDVLkHb3Deos.A- 4. https://a.b-io.me/c/Y1lM9w9S1Kcyhmff9PUym3lzb4DFXoKjbQxPz_NW_WrQaWlkIsfqBNRgrwhzFkMcrwIXvcetvsZyskw3ba6cO13ry35GacumgC9FOm4QkNXaAORBfGNI9XaxlUM1jCpXwWSsHd4hBnlo3Ep2ClCJZR4F_2_Z944RQ_Ff1Hlr7qC5AubVwp4npLVx_SJUN89AI6R8sJU6BcnDevdyvtmr3SQCfDh9Nllm1xxkirU9iGeJRMIJCeh4_rhv8rSXZms8yV1cHIIO.DQHsbSiSXFFFwiIXVDY97IzEM2xKAcTY43fK9V0PT4wI5Vx5wMoLgN7BUrvnfnF3YZJzSk9BM9xIw1m1d7bBy4hb3qihMYau.6R3JspOZZpeDDWIM2ZwsZ7twKFN2dpifDGPOdSRj1EW1sVg4IarW8oQgLry3CN1jdwmv86NTcKo2UsMKSQNmn82g9GaB.Aab_hFWGduKelhd_zkhoBta3xbetkl8tJBjdEecbdRMWk0eR.hPW394lfunbII79SX7y0zhgaUCFBhw-- 5. https://a.b-io.me/c/Y1lM9w9S1Kcyhmff9PUym3lzb4DFXoKjbQxPz_NW_WrQaWlkIsfqBNRgrwhzFkMcrwIXvcetvsZyskw3ba6cO13ry35GacumgC9FOm4QkNXaAORBfGNI9XaxlUM1jCpXwWSsHd4hBnlo3Ep2ClCJZR4F_2_Z944RQ_Ff1Hlr7qC5AubVwp4npLVx_SJUN89AI6R8sJU6BcnDevdyvtmr3XQSZ5q7Uj4AUiZ.VwRVR0uATpJf4wwi2VBn2uyg_TniJvFx9Ykk4tGemAGZEpURvQmxJqhFX9kmefyRbN3anZT9Psy7Qwp1WuVTAYoDkjUpMkJpEhGzSVxLxWi8A5ZosYQm_CP1pW5QZqRpWSOTdGnJOZ61Se8VxvmwfXh4AY9ZrCMU63YPBX6ZA78PdxvP7lEgrAZUzHfGczjz_39.lBKQyr_yKuIpcw0m7EMQCkaZbNaX8qEZceMGLyBYMb6g.rs7WCkhrE5ikz5PafL2GJQOU1vvVOy7NrL198gM8C_0GyRdSM2zDileyARIlxoX8ALjoCwa9JXkiP05sPdmZlwzQLq1fShUUsp9g0aXOz_70iG9nz4Wv68V5vR7aSs.xbCQtqhEsq8Opq2EUc4yTtsKuku9TC1tIkVG7Z9qPDn.MIqQ0vOJX8C6YenpnQz7iAvXX62x1Bw1m.SoyXmrjN4QkYwd_7HhsLcChTdnaYnwxjznUkY9RFtbFYOCGq1vKEIC68twjdY3cJr.OjU3CqNCmkqgAAsbqycQQoH55CiX_9YQ48RbRVB7f19k7IEXcOg3DCBOR.7WCtl3OoIThpaH6PFz4jRZ4A-- 6. https://a.b-io.me/c/Y1lM9w9S1Kcyhmff9PUym3lzb4DFXoKjbQxPz_NW_WrQaWlkIsfqBNRgrwhzFkMcrwIXvcetvsZyskw3ba6cO13ry35GacumgC9FOm4QkNXaAORBfGNI9XaxlUM1jCpXwWSsHd4hBnlo3Ep2ClCJZR4F_2_Z944RQ_Ff1Hlr7qC5AubVwp4npLVx_SJUN89AI6R8sJU6BcnOFzLscYDd_vqRDj0SoJx6X2cUYMUBoBnyYh259jgZLmu.gJrc5PREAHsseYstd5eqVluqQ1VKEsgcWQVaFzMA41D4N7g_a.VK0zKni9IiUiMz1vh9HNUt1H5z5sniDd6InEr4aMXaSQmRFYCWbTvSR_ac7UAeZLRbmJtFzgH07TcucLjIcQBxz0iGtaebo9OPe_CcwUVyeIDpoLkMXVoov_BsjwMPeOW2qB12AEKQkr1gLEpC7ziNa7Bl1HsdFegrvomyrIEfhs02.V2U6ODdxVSU.iOmoNUuQdvcN6iz8A-- 7. https://a.b-io.me/c/Y1lM9w9S1Kcyhmff9PUym3lzb4DFXoKjbQxPz_NW_WrQaWlkIsfqBNRgrwhzFkMcrwIXvcetvsZyskw3ba6cO13ry35GacumgC9FOm4QkNXaAORBfGNI9XaxlUM1jCpXwWSsHd4hBnlo3Ep2ClCJZR4F_2_Z944RQ_Ff1Hlr7qC5AubVwp4npLVx_SJUN89AI6R8sJU6BcnOFzLscYDd_nvhsHDpeErFT9ujPR.S.S.OTuCQ1AcE58yCnaaGRjo0AFRhpX6WYHsgxI2PLfTUqvyoHTevVH4KjWhfxulCynmhq13SFHUO0jB2muQSPg_3SJ0IQqs0_Ueh5G7FUEOOOEKdML5h84VlSYbjsz_N1HGHQOs5n.1E7s1DI3iSpGDB_N3yMYqvuBcr6XwBibKM4P3LdsZfK.Q2M11eQELWLpH0Vs8NmgE3MY0TiDO3KU_V7w0eHjri9.twOAjjam3qwa1jLaAvk31Y5x2e.65D9k7fK9V0PT4wI5Vx5wMoLgN7BUrvnfnF3YZJzSk9BM9xI3Ke3BiT6f4z 8. https://a.b-io.me/c/Y1lM9w9S1Kcyhmff9PUym3lzb4DFXoKjbQxPz_NW_WrQaWlkIsfqBNRgrwhzFkMcrwIXvcetvsZyskw3ba6cO13ry35GacumgC9FOm4QkNXaAORBfGNI9XaxlUM1jCpXwWSsHd4hBnlo3Ep2ClCJZR4F_2_Z944RQ_Ff1Hlr7qC5AubVwp4npLVx_SJUN89AI6R8sJU6BcnDevdyvtmr3XLv1zMnoJcUo9jOL4SdRzmgYGya.Yip6kk9.QLUBM15GQzYjJN.vEkzXV5AQtYukfRWzw2aATcxjROIM7cpT5XvDR4eOuL3_3A4CONqberBrWMtoC_TfVjnHZ7.rkP2Tt8r1XQ9PjAjlXHnAyguA3sFSu_d_cXdhknNKT0Ez3Ejcp7cGJPp.jM- (In reply to felix from comment #21) > > va_list ap2; > > va_copy(ap2, ap); > > > and then use &ap2, this always works. > > > the proposed macros are both broken and unnecessary. > > That's not equivalent. Using va_arg(ap2, T) does not propagate state changes > back to ap, which is the main motivation to form a pointer to ap in the > first place. The macros do that just fine. You mean they are unportable? > That part is true, I admitted as much. Pick your poison. > state changes are propagated to ap2, which is what you should use after you made the copy, it does exactly what you want. |