g++-2.95 rejects cast to void

Nathan Sidwell nathan@acm.org
Thu Jun 17 09:14:00 GMT 1999


Ok,
here's a patch which corrects g++'s erroneous processing of expressions in void
context. require_complete_type_in_void was incorrect in looking for a complete
type -- there is no such requirement in the standard. Test case
g++.bugs/900428_01.C was incorrect in this assertion. It was my fault for
providing such a patch (1999-02-26).

What actually happens in such cases is that no lvalue->rvalue transformation
happens and no indirection occurs. This also means that, should the expression
refer to a volatile object, no read occurs of the object, i.e.

volatile int *pvi;

*pvi;

whatever pvi points to is NOT read. This might surprise the user, so I've
replaced
require_complete_type_in_void with check_expr_in_void which concerns itself
with checking volatileness. In the above example the diagnostic,
	warning: volatile object in void context will not be accessed
will be issued.

Most of check_expr_in_void is what was in require_complete_type_in_void.

This bug manifests itself in the 2.95 branch, and it is critical that we fix
it. There are two choices,
1) apply this fix to both branches
2) apply this fix to the mainline and turn require_complete_type_in_void into a
no-op for the release branch.

2) is the safer option.

Attached is the patch and a replacement 900428_01.C.

Some processing from cplus_expand_expr_stmt should migrate to
check_expr_in_void, but lets take this one step at a time.

I said,
>> forthcoming. This line of reasoning implies that
>> g++.bugs/900428_01.C is wrong, even for volatile objects in
>> statement expressions (6.2/1), because lvalue->rvalue never happens.

Mike Stump said,
>I question this.  I don't think we should implement a gross
>incompatibility with C, I have no faith that the decision that ANSI
>C++ took was the right one.  I favor postponing this one.

I don't think we can duck at least turning off the error for the 2.95 release.
At the moment we're rejecting code which is valid according to the standard.

Ok to install?

nathan
-- 
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
        I have seen the death of PhotoShop -- it is called GIMP
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk
// g++ 1.37.1 bug 900428_01

// If an expression is used in a void context, it is evaluated and its result
// discarded. BUT lvalue to rvalue and other such `normal' conversions are not
// applied. This means indirecting an incomplete type is NOT an error. However,
// the naive programmer might expect indirecting to a volatile object to
// actually read the object. This doesn't happen and we warn when the
// expression has volatile type.

// This test case was originally incorrect in its assertion that such
// expressions caused things to be read.

// keywords: incomplete types, evaluation, volatile qualifier
// Build don't link: 

int i;

void *pv;
volatile void *pvv;
struct s;
extern struct s es, *ps;
extern volatile struct s evs, *pvs;

void pv_test (s &rs, volatile s &vrs)
{
  *pv;			// ok
  (i ? *pv : *pv);	// ok
  *pv, *pv;		// ok

  *pvv;			// WARNING - not deref'd
  (i ? *pvv : *pvv);	// WARNING - not deref'd
  *pvv, *pvv;		// WARNING - not deref'd

  es;			// ok
  (i ? es : es);	// ok
  es, es;		// ok

  evs;			// WARNING - not deref'd
  (i ? evs : evs);	// WARNING - not deref'd
  evs, evs;		// WARNING - not deref'd

  *ps;			// ok
  (i ? *ps : *ps);	// ok
  *ps, *ps;		// ok

  *pvs;			// WARNING - not deref'd
  (i ? *pvs : *pvs);	// WARNING - not deref'd
  *pvs, *pvs;		// WARNING - not deref'd
  
  rs; // ok
  vrs; // WARNING - not deref'd
}

int main () { return 0; }


More information about the Gcc-patches mailing list