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