C++ PATCH: PR23840

Mark Mitchell mark@codesourcery.com
Mon Oct 3 14:19:00 GMT 2005


This patch fixes a C++ regression introduced when VA_ARG_EXPR was
added to the compiler.  In particular, in C++, va_arg (ap, T).f() is
valid, just as is f().g(), if the expression before the "." is a class
type.  These left-hand-side expressions aren't quite lvalues (in that
you can't take their addresses directly), but you can use them in ways
that require an address.

Tested on x86_64-unknown-linux-gnu, applied on the mainline and on the
4.0 branch.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2005-10-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/23840
	* tree.c (lvalue_p1): A VA_ARG_EXPR with class type is an lvalue,
	when class rvalues are lvalues.

2005-10-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/23840
	* g++.dg/expr/stdarg1.C: New test.

Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.442
diff -c -5 -p -r1.442 tree.c
*** gcc/cp/tree.c	6 Sep 2005 14:55:05 -0000	1.442
--- gcc/cp/tree.c	2 Oct 2005 21:21:56 -0000
*************** lvalue_p_1 (tree ref,
*** 156,167 ****
  			 treat_class_rvalues_as_lvalues);
  
      case TARGET_EXPR:
        return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
  
-     case CALL_EXPR:
      case VA_ARG_EXPR:
        /* Any class-valued call would be wrapped in a TARGET_EXPR.  */
        return clk_none;
  
      case FUNCTION_DECL:
        /* All functions (except non-static-member functions) are
--- 156,171 ----
  			 treat_class_rvalues_as_lvalues);
  
      case TARGET_EXPR:
        return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
  
      case VA_ARG_EXPR:
+       return (treat_class_rvalues_as_lvalues
+ 	      && CLASS_TYPE_P (TREE_TYPE (ref))
+ 	      ? clk_class : clk_none);
+ 
+     case CALL_EXPR:
        /* Any class-valued call would be wrapped in a TARGET_EXPR.  */
        return clk_none;
  
      case FUNCTION_DECL:
        /* All functions (except non-static-member functions) are
Index: gcc/testsuite/g++.dg/expr/stdarg1.C
===================================================================
RCS file: gcc/testsuite/g++.dg/expr/stdarg1.C
diff -N gcc/testsuite/g++.dg/expr/stdarg1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/expr/stdarg1.C	2 Oct 2005 21:21:56 -0000
***************
*** 0 ****
--- 1,13 ----
+ // PR c++/23840
+ 
+ #include <stdarg.h>
+ struct S 
+ {
+   int f(int);
+ };
+ void f(int i, ...) 
+ {
+   va_list ap;
+   va_start (ap, i);
+   va_arg (ap, S).f(0);
+ }



More information about the Gcc-patches mailing list