| // { dg-do assemble } |
| // g++ 1.37.1 bug 900428_01 |
| |
| // g++ fails to issue error messages for cases where an incomplete type |
| // object must be evaluated if the value of such an evaluation is not |
| // actually used in the given context. |
| |
| // In the case where such an object is volatile, it is obvious that this |
| // could be a problem, however I believe that errors should be issued |
| // for such cases regardless of whether or not such values are volatile |
| // because the abstract semantics seem to require the evaluation of such |
| // values whether they are volatile or not. |
| |
| // [expr.static.cast/4, stmt.expr/1, expr.comma/1] show that expressions do |
| // not under go lvalue to rvalue decay, unless the value is actually used. |
| // This can be surprising when the object is volatile. We interpret a |
| // dereference of pointer to volatile to be a read. |
| |
| // keywords: incomplete types, evaluation, volatile qualifier |
| |
| int *ip_fn (); |
| int &ir_fn (); |
| volatile int *vip_fn (); |
| volatile int &vir_fn (); |
| |
| void int_test (int i, int *p, volatile int *vp, int &r, volatile int &vr) |
| { |
| int j; |
| volatile int vj; |
| |
| *p; // ok, no warning |
| (void)*p; // ok, no warning |
| (void)(i ? j : *p); // ok, no warning |
| (void)(i ? *p : j); // ok, no warning |
| (void)((void)1, *p); // ok, no warning |
| |
| *vp; // ok, no warning |
| (void)*vp; // ok, no warning |
| (void)(i ? vj : *vp); // ok, no warning |
| (void)(i ? *vp : vj); // ok, no warning |
| (void)((void)1, *vp); // ok, no warning |
| |
| r; // ok, no warning |
| (void)r; // ok, no warning |
| (void)(i ? j : r); // ok, no warning |
| (void)(i ? r : j); // ok, no warning |
| (void)((void)1, r); // ok, no warning |
| |
| vr; // { dg-warning "" } reference not accessed |
| (void)vr; // { dg-warning "" } reference not accessed |
| (void)(i ? vj : vr); // { dg-warning "" } reference not accessed |
| (void)(i ? vr : vj); // { dg-warning "" } reference not accessed |
| (void)((void)1, vr); // { dg-warning "" } reference not accessed |
| |
| *ip_fn (); // ok, no warning |
| *vip_fn (); // ok, no warning |
| ir_fn (); // ok, no warning |
| vir_fn (); // { dg-warning "" } reference not accessed |
| } |
| |
| struct S; |
| S *sp_fn (); |
| S &sr_fn (); |
| volatile S *vsp_fn (); |
| volatile S &vsr_fn (); |
| |
| void incomplete_test (int i, S *p, volatile S *vp, S &r, volatile S &vr) |
| { |
| extern S j; |
| extern volatile S vj; |
| |
| *p; // ok, no warning |
| (void)*p; // ok, no warning |
| (void)(i ? j : *p); // ok, no warning |
| (void)(i ? *p : j); // ok, no warning |
| (void)((void)1, *p); // ok, no warning |
| |
| *vp; // { dg-warning "" } incomplete not accessed |
| (void)*vp; // { dg-warning "" } incomplete not accessed |
| (void)(i ? vj : *vp); // { dg-warning "" } incomplete not accessed |
| (void)(i ? *vp : vj); // { dg-warning "" } incomplete not accessed |
| (void)((void)1, *vp); // { dg-warning "" } incomplete not accessed |
| |
| r; // ok, no warning |
| (void)r; // ok, no warning |
| (void)(i ? j : r); // ok, no warning |
| (void)(i ? r : j); // ok, no warning |
| (void)((void)1, r); // ok, no warning |
| |
| vr; // { dg-warning "" } reference not accessed |
| (void)vr; // { dg-warning "" } reference not accessed |
| (void)(i ? vj : vr); // { dg-warning "" } reference not accessed |
| (void)(i ? vr : vj); // { dg-warning "" } reference not accessed |
| (void)((void)1, vr); // { dg-warning "" } reference not accessed |
| |
| *sp_fn (); // ok, no warning |
| *vsp_fn (); // { dg-warning "" } incomplete not accessed |
| sr_fn (); // ok, no warning |
| vsr_fn (); // { dg-warning "" } reference not accessed |
| } |
| |
| struct T {int m;}; |
| T *tp_fn (); |
| T &tr_fn (); |
| volatile T *vtp_fn (); |
| volatile T &vtr_fn (); |
| |
| void complete_test (int i, T *p, volatile T *vp, T &r, volatile T &vr) |
| { |
| T j; |
| volatile T vj; |
| |
| *p; // ok, no warning |
| (void)*p; // ok, no warning |
| (void)(i ? j : *p); // ok, no warning |
| (void)(i ? *p : j); // ok, no warning |
| (void)((void)1, *p); // ok, no warning |
| |
| *vp; // ok, no warning |
| (void)*vp; // ok, no warning |
| (void)(i ? vj : *vp); // ok, no warning |
| (void)(i ? *vp : vj); // ok, no warning |
| (void)((void)1, *vp); // ok, no warning |
| |
| r; // ok, no warning |
| (void)r; // ok, no warning |
| (void)(i ? j : r); // ok, no warning |
| (void)(i ? r : j); // ok, no warning |
| (void)((void)1, r); // ok, no warning |
| |
| vr; // { dg-warning "" } reference not accessed |
| (void)vr; // { dg-warning "" } reference not accessed |
| (void)(i ? vj : vr); // { dg-warning "" } reference not accessed |
| (void)(i ? vr : vj); // { dg-warning "" } reference not accessed |
| (void)((void)1, vr); // { dg-warning "" } reference not accessed |
| |
| *tp_fn (); // ok, no warning |
| *vtp_fn (); // ok, no warning |
| tr_fn (); // ok, no warning |
| vtr_fn (); // ok, no warning{ dg-warning "" } reference not accessed |
| } |
| |
| void extern_test () |
| { |
| extern S es; |
| extern volatile S ves; |
| extern T et; |
| extern volatile T vet; |
| |
| extern S &esr; |
| extern volatile S &vesr; |
| extern T &etr; |
| extern volatile T &vetr; |
| |
| es; // ok, no warning |
| ves; // { dg-warning "" } incomplete not accessed |
| et; // ok, no warning |
| vet; // ok, no warning |
| |
| esr; // ok, no warning |
| vesr; // { dg-warning "" } incomplete not accessed |
| etr; // ok, no warning |
| vetr; // { dg-warning "" } reference not accessed |
| } |