aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-07-03 01:03:34 -0400
committerJason Merrill <jason@gcc.gnu.org>2012-07-03 01:03:34 -0400
commite0e1b357435272f8906e8fd70d92c7862e1bc07b (patch)
treeb32f464c8a8a5c7cfc0c717a1c38fee7740263bf
parent39fa0adb69ef147f872fefe2ef44aed9c6155b9c (diff)
downloadgcc-e0e1b357435272f8906e8fd70d92c7862e1bc07b.zip
gcc-e0e1b357435272f8906e8fd70d92c7862e1bc07b.tar.gz
gcc-e0e1b357435272f8906e8fd70d92c7862e1bc07b.tar.bz2
re PR c++/53619 ([C++11] wrong capture of "this" in lambda in case of multiple inheritance)
PR c++/53619 * pt.c (in_template_function): New. * cp-tree.h: Declare it. * class.c (build_base_path, resolves_to_fixed_type_p): Use it. From-SVN: r189191
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/class.c6
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.c17
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C22
6 files changed, 50 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 580f8cd..2c52423 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2012-07-02 Jason Merrill <jason@redhat.com>
+ PR c++/53619
+ * pt.c (in_template_function): New.
+ * cp-tree.h: Declare it.
+ * class.c (build_base_path, resolves_to_fixed_type_p): Use it.
+
PR c++/53783
* pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Use tsubst
for LAMBDA_EXPR_EXTRA_SCOPE.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index e70e674..0d4a40d 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -325,8 +325,7 @@ build_base_path (enum tree_code code,
up properly yet, and the value doesn't matter there either; we're just
interested in the result of overload resolution. */
if (cp_unevaluated_operand != 0
- || (current_function_decl
- && uses_template_parms (current_function_decl)))
+ || in_template_function ())
{
expr = build_nop (ptr_target_type, expr);
if (!want_pointer)
@@ -6523,8 +6522,7 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
/* processing_template_decl can be false in a template if we're in
fold_non_dependent_expr, but we still want to suppress this check. */
- if (current_function_decl
- && uses_template_parms (current_function_decl))
+ if (in_template_function ())
{
/* In a template we only care about the type of the result. */
if (nonnull)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a4b7ae3..41ca83c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5330,6 +5330,7 @@ extern tree lookup_template_class (tree, tree, tree, tree,
extern tree lookup_template_function (tree, tree);
extern int uses_template_parms (tree);
extern int uses_template_parms_level (tree, int);
+extern bool in_template_function (void);
extern tree instantiate_class_template (tree);
extern tree instantiate_template (tree, tree, tsubst_flags_t);
extern int fn_type_unification (tree, tree, tree,
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d385ea7..f618fa5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8027,6 +8027,23 @@ uses_template_parms (tree t)
return dependent_p;
}
+/* Returns true iff current_function_decl is an incompletely instantiated
+ template. Useful instead of processing_template_decl because the latter
+ is set to 0 during fold_non_dependent_expr. */
+
+bool
+in_template_function (void)
+{
+ tree fn = current_function_decl;
+ bool ret;
+ ++processing_template_decl;
+ ret = (fn && DECL_LANG_SPECIFIC (fn)
+ && DECL_TEMPLATE_INFO (fn)
+ && any_dependent_template_arguments_p (DECL_TI_ARGS (fn)));
+ --processing_template_decl;
+ return ret;
+}
+
/* Returns true if T depends on any template parameter with level LEVEL. */
int
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cb62b11..7ce574a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2012-07-02 Jason Merrill <jason@redhat.com>
+ PR c++/53619
+ * g++.dg/cpp0x/lambda/lambda-this5.C: New.
+
PR c++/53783
* g++.dg/cpp0x/lambda/lambda-template7.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C
new file mode 100644
index 0000000..8974641
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C
@@ -0,0 +1,22 @@
+// PR c++/53619
+// { dg-do run { target c++11 } }
+
+struct C {
+ int x;
+};
+struct B {
+ int q;
+};
+struct A : public B , C {
+ void foo();
+};
+
+void A::foo() {
+ auto k = [this]() {return (void *)(&x);};
+ if (k() != (void*)&x)
+ __builtin_abort();
+}
+
+int main(int l, char **) {
+ A a; a.foo();
+}