summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog2
-rw-r--r--debian/patches/go-escape-analysis6.diff209
-rw-r--r--debian/rules.patch2
3 files changed, 213 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index 17e96d0..efac9c4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,8 @@ gcc-5 (5.2.1-1) UNRELEASED; urgency=medium
* Update to SVN 20150716 (r225880, 5.2.1) from the gcc-5-branch.
* Require version 5.2 for the libstdc++6 cxx symbols.
* Ignore missing libstdc++ symbols on sparc64 (work around #792204).
+ * Go escape analysis: analyze multiple result type assertions (taken
+ from the trunk).
-- Matthias Klose <doko@debian.org> Thu, 16 Jul 2015 15:35:44 +0200
diff --git a/debian/patches/go-escape-analysis6.diff b/debian/patches/go-escape-analysis6.diff
new file mode 100644
index 0000000..675e62e
--- /dev/null
+++ b/debian/patches/go-escape-analysis6.diff
@@ -0,0 +1,209 @@
+# DP: escape: Analyze multiple result type assertions.
+
+ For multi-result type assertions, the object being converted is hidden
+ behind unsafe conversions and calls to runtime methods. This change
+ allows the analysis to make edges between the result of the assertion
+ and the object being asserted.
+
+Index: gcc/go/gofrontend/expressions.h
+===================================================================
+--- a/src/gcc/go/gofrontend/expressions.h (revision 225750)
++++ b/src/gcc/go/gofrontend/expressions.h (revision 225751)
+@@ -32,6 +32,7 @@
+ class Set_and_use_temporary_expression;
+ class String_expression;
+ class Type_conversion_expression;
++class Unsafe_type_conversion_expression;
+ class Unary_expression;
+ class Binary_expression;
+ class Call_expression;
+@@ -571,6 +572,15 @@
+ conversion_expression()
+ { return this->convert<Type_conversion_expression, EXPRESSION_CONVERSION>(); }
+
++ // If this is an unsafe conversion expression, return the
++ // Unsafe_type_conversion_expression structure. Otherwise, return NULL.
++ Unsafe_type_conversion_expression*
++ unsafe_conversion_expression()
++ {
++ return this->convert<Unsafe_type_conversion_expression,
++ EXPRESSION_UNSAFE_CONVERSION>();
++ }
++
+ // Return whether this is the expression nil.
+ bool
+ is_nil_expression() const
+@@ -1505,6 +1515,57 @@
+ bool may_convert_function_types_;
+ };
+
++// An unsafe type conversion, used to pass values to builtin functions.
++
++class Unsafe_type_conversion_expression : public Expression
++{
++ public:
++ Unsafe_type_conversion_expression(Type* type, Expression* expr,
++ Location location)
++ : Expression(EXPRESSION_UNSAFE_CONVERSION, location),
++ type_(type), expr_(expr)
++ { }
++
++ Expression*
++ expr() const
++ { return this->expr_; }
++
++ protected:
++ int
++ do_traverse(Traverse* traverse);
++
++ bool
++ do_is_immutable() const;
++
++ Type*
++ do_type()
++ { return this->type_; }
++
++ void
++ do_determine_type(const Type_context*)
++ { this->expr_->determine_type_no_context(); }
++
++ Expression*
++ do_copy()
++ {
++ return new Unsafe_type_conversion_expression(this->type_,
++ this->expr_->copy(),
++ this->location());
++ }
++
++ Bexpression*
++ do_get_backend(Translate_context*);
++
++ void
++ do_dump_expression(Ast_dump_context*) const;
++
++ private:
++ // The type to convert to.
++ Type* type_;
++ // The expression to convert.
++ Expression* expr_;
++};
++
+ // A Unary expression.
+
+ class Unary_expression : public Expression
+@@ -2024,6 +2085,10 @@
+ call() const
+ { return this->call_; }
+
++ unsigned int
++ index() const
++ { return this->index_; }
++
+ protected:
+ int
+ do_traverse(Traverse*);
+Index: gcc/go/gofrontend/escape.cc
+===================================================================
+--- a/src/gcc/go/gofrontend/escape.cc (revision 225750)
++++ b/src/gcc/go/gofrontend/escape.cc (revision 225751)
+@@ -547,6 +547,41 @@
+ expr = expr->type_guard_expression()->expr();
+ break;
+
++ case Expression::EXPRESSION_UNSAFE_CONVERSION:
++ {
++ Expression* e = expr->unsafe_conversion_expression()->expr();
++ if (e->call_result_expression() != NULL
++ && e->call_result_expression()->index() == 0)
++ {
++ // a, ok := p.(T) gets lowered into a call to one of the interface
++ // to type conversion functions instead of a type guard expression.
++ // We only want to make a connection between a and p, the bool
++ // result should not escape because p escapes.
++ e = e->call_result_expression()->call();
++
++ Named_object* fn =
++ e->call_expression()->fn()->func_expression()->named_object();
++ std::string fn_name = fn->name();
++ if (fn->package() == NULL
++ && fn->is_function_declaration()
++ && !fn->func_declaration_value()->asm_name().empty())
++ {
++ if (fn_name == "ifaceI2E2"
++ || fn_name == "ifaceI2I2")
++ e = e->call_expression()->args()->at(0);
++ else if (fn_name == "ifaceE2I2"
++ || fn_name == "ifaceI2I2"
++ || fn_name == "ifaceE2T2P"
++ || fn_name == "ifaceI2T2P"
++ || fn_name == "ifaceE2T2"
++ || fn_name == "ifaceI2T2")
++ e = e->call_expression()->args()->at(1);
++ }
++ }
++ expr = e;
++ }
++ break;
++
+ default:
+ done = true;
+ break;
+Index: gcc/go/gofrontend/expressions.cc
+===================================================================
+--- a/src/gcc/go/gofrontend/expressions.cc (revision 225750)
++++ b/src/gcc/go/gofrontend/expressions.cc (revision 225751)
+@@ -3391,53 +3391,8 @@
+ return new Type_conversion_expression(type, val, location);
+ }
+
+-// An unsafe type conversion, used to pass values to builtin functions.
++// Class Unsafe_type_conversion_expression.
+
+-class Unsafe_type_conversion_expression : public Expression
+-{
+- public:
+- Unsafe_type_conversion_expression(Type* type, Expression* expr,
+- Location location)
+- : Expression(EXPRESSION_UNSAFE_CONVERSION, location),
+- type_(type), expr_(expr)
+- { }
+-
+- protected:
+- int
+- do_traverse(Traverse* traverse);
+-
+- bool
+- do_is_immutable() const;
+-
+- Type*
+- do_type()
+- { return this->type_; }
+-
+- void
+- do_determine_type(const Type_context*)
+- { this->expr_->determine_type_no_context(); }
+-
+- Expression*
+- do_copy()
+- {
+- return new Unsafe_type_conversion_expression(this->type_,
+- this->expr_->copy(),
+- this->location());
+- }
+-
+- Bexpression*
+- do_get_backend(Translate_context*);
+-
+- void
+- do_dump_expression(Ast_dump_context*) const;
+-
+- private:
+- // The type to convert to.
+- Type* type_;
+- // The expression to convert.
+- Expression* expr_;
+-};
+-
+ // Traversal.
+
+ int
diff --git a/debian/rules.patch b/debian/rules.patch
index 2c8635e..9a3e78e 100644
--- a/debian/rules.patch
+++ b/debian/rules.patch
@@ -85,6 +85,7 @@ debian_patches += \
go-escape-analysis3 \
go-escape-analysis4 \
go-escape-analysis5 \
+ go-escape-analysis6 \
gccgo-sendfile-fix \
pr66368 \
@@ -94,6 +95,7 @@ debian_patches += \
# go-escape-analysis3 \
# go-escape-analysis4 \
# go-escape-analysis5 \
+# go-escape-analysis6 \
# $(if $(filter yes, $(DEB_CROSS)),,gcc-print-file-name) \
# libstdc++-nothumb-check \