diff options
author | Jason Merrill <jason@redhat.com> | 2013-03-16 22:41:22 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2013-03-16 22:41:22 -0400 |
commit | bab5167fe640ee7596bb644035cad57f6c9160c0 (patch) | |
tree | 4260d93a9ab8a461ec2d417499b6687d36124630 /gcc | |
parent | d14d53ad6501853b2471ad90ead6eace803226a7 (diff) | |
download | gcc-bab5167fe640ee7596bb644035cad57f6c9160c0.zip gcc-bab5167fe640ee7596bb644035cad57f6c9160c0.tar.gz gcc-bab5167fe640ee7596bb644035cad57f6c9160c0.tar.bz2 |
re PR c++/54277 (Template class member referred to with implicit this inside lambda is incorrectly const-qualified)
PR c++/54277
* cp-tree.h (WILDCARD_TYPE_P): Split out from...
(MAYBE_CLASS_TYPE_P): ...here.
* semantics.c (lambda_capture_field_type): Only build a
magic decltype for wildcard types.
(lambda_proxy_type): Likewise.
(finish_non_static_data_member): Get the quals from
the object.
From-SVN: r196747
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 17 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this9.C | 19 |
4 files changed, 41 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f6f1521..ec7cd0f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2013-03-16 Jason Merrill <jason@redhat.com> + PR c++/54277 + * cp-tree.h (WILDCARD_TYPE_P): Split out from... + (MAYBE_CLASS_TYPE_P): ...here. + * semantics.c (lambda_capture_field_type): Only build a + magic decltype for wildcard types. + (lambda_proxy_type): Likewise. + (finish_non_static_data_member): Get the quals from + the object. + PR c++/55931 * parser.c (cp_parser_template_argument): Don't fold_non_dependent_expr. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 39fb3df..7ce1acb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1220,17 +1220,20 @@ enum languages { lang_c, lang_cplusplus, lang_java }; /* The _DECL for this _TYPE. */ #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE))) -/* Nonzero if T is a class (or struct or union) type. Also nonzero - for template type parameters, typename types, and instantiated - template template parameters. Keep these checks in ascending code - order. */ -#define MAYBE_CLASS_TYPE_P(T) \ +/* Nonzero if T is a type that could resolve to any kind of concrete type + at instantiation time. */ +#define WILDCARD_TYPE_P(T) \ (TREE_CODE (T) == TEMPLATE_TYPE_PARM \ || TREE_CODE (T) == TYPENAME_TYPE \ || TREE_CODE (T) == TYPEOF_TYPE \ || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM \ - || TREE_CODE (T) == DECLTYPE_TYPE \ - || CLASS_TYPE_P (T)) + || TREE_CODE (T) == DECLTYPE_TYPE) + +/* Nonzero if T is a class (or struct or union) type. Also nonzero + for template type parameters, typename types, and instantiated + template template parameters. Keep these checks in ascending code + order. */ +#define MAYBE_CLASS_TYPE_P(T) (WILDCARD_TYPE_P (T) || CLASS_TYPE_P (T)) /* Set CLASS_TYPE_P for T to VAL. T must be a class, struct, or union type. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9a2b728..5143e4b 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1574,9 +1574,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) else { /* Set the cv qualifiers. */ - int quals = (current_class_ref - ? cp_type_quals (TREE_TYPE (current_class_ref)) - : TYPE_UNQUALIFIED); + int quals = cp_type_quals (TREE_TYPE (object)); if (DECL_MUTABLE_P (decl)) quals &= ~TYPE_QUAL_CONST; @@ -9056,7 +9054,7 @@ tree lambda_capture_field_type (tree expr) { tree type; - if (type_dependent_expression_p (expr)) + if (!TREE_TYPE (expr) || WILDCARD_TYPE_P (TREE_TYPE (expr))) { type = cxx_make_type (DECLTYPE_TYPE); DECLTYPE_TYPE_EXPR (type) = expr; @@ -9265,7 +9263,7 @@ lambda_proxy_type (tree ref) if (REFERENCE_REF_P (ref)) ref = TREE_OPERAND (ref, 0); type = TREE_TYPE (ref); - if (!dependent_type_p (type)) + if (type && !WILDCARD_TYPE_P (type)) return type; type = cxx_make_type (DECLTYPE_TYPE); DECLTYPE_TYPE_EXPR (type) = ref; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this9.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this9.C new file mode 100644 index 0000000..07ddd08 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this9.C @@ -0,0 +1,19 @@ +// PR c++/54277 +// { dg-do compile { target c++11 } } + +struct Used +{ + void foo() { } +}; + +template <typename> +struct S +{ + Used x; + + void bar() + { + auto f = [this] { x.foo(); }; + f(); + } +}; |