aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-03-16 22:41:22 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-03-16 22:41:22 -0400
commitbab5167fe640ee7596bb644035cad57f6c9160c0 (patch)
tree4260d93a9ab8a461ec2d417499b6687d36124630
parentd14d53ad6501853b2471ad90ead6eace803226a7 (diff)
downloadgcc-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
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h17
-rw-r--r--gcc/cp/semantics.c8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this9.C19
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();
+ }
+};