re PR ipa/63587 (ICE : tree check: expected var_decl, have result_decl in add_local_variables, at tree-inline.c:4112)
PR ipa/63587 * g++.dg/ipa/pr63587-1.C: New test * g++.dg/ipa/pr63587-2.C: New test. * cgraphunit.c (cgraph_node::expand_thunk): Only VAR_DECLs are put to local declarations. * function.c (add_local_decl): Implementation moved from header file, assert introduced for tree type. * function.h: Likewise. From-SVN: r216841
This commit is contained in:
parent
7b310e901c
commit
5cf18d250f
@ -1,3 +1,12 @@
|
||||
2014-10-29 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR ipa/63587
|
||||
* cgraphunit.c (cgraph_node::expand_thunk): Only VAR_DECLs are put
|
||||
to local declarations.
|
||||
* function.c (add_local_decl): Implementation moved from header
|
||||
file, assert introduced for tree type.
|
||||
* function.h: Likewise.
|
||||
|
||||
2014-10-29 Dominik Vogt <vogt@linux.vnet.ibm.com>
|
||||
|
||||
* godump.c (go_format_type): Represent "float _Complex" and
|
||||
|
@ -1550,7 +1550,9 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
|
||||
else if (!is_gimple_reg_type (restype))
|
||||
{
|
||||
restmp = resdecl;
|
||||
add_local_decl (cfun, restmp);
|
||||
|
||||
if (TREE_CODE (restmp) == VAR_DECL)
|
||||
add_local_decl (cfun, restmp);
|
||||
BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
|
||||
}
|
||||
else
|
||||
|
@ -6441,6 +6441,15 @@ match_asm_constraints_1 (rtx_insn *insn, rtx *p_sets, int noutputs)
|
||||
df_insn_rescan (insn);
|
||||
}
|
||||
|
||||
/* Add the decl D to the local_decls list of FUN. */
|
||||
|
||||
void
|
||||
add_local_decl (struct function *fun, tree d)
|
||||
{
|
||||
gcc_assert (TREE_CODE (d) == VAR_DECL);
|
||||
vec_safe_push (fun->local_decls, d);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_match_asm_constraints =
|
||||
|
@ -668,11 +668,7 @@ struct GTY(()) function {
|
||||
|
||||
/* Add the decl D to the local_decls list of FUN. */
|
||||
|
||||
static inline void
|
||||
add_local_decl (struct function *fun, tree d)
|
||||
{
|
||||
vec_safe_push (fun->local_decls, d);
|
||||
}
|
||||
void add_local_decl (struct function *fun, tree d);
|
||||
|
||||
#define FOR_EACH_LOCAL_DECL(FUN, I, D) \
|
||||
FOR_EACH_VEC_SAFE_ELT_REVERSE ((FUN)->local_decls, I, D)
|
||||
|
@ -1,3 +1,9 @@
|
||||
2014-10-29 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR ipa/63587
|
||||
* g++.dg/ipa/pr63587-1.C: New test.
|
||||
* g++.dg/ipa/pr63587-2.C: New test.
|
||||
|
||||
2014-10-29 Dominik Vogt <vogt@linux.vnet.ibm.com>
|
||||
|
||||
* gcc.misc-tests/godump-1.c: Add tests for complex types.
|
||||
|
92
gcc/testsuite/g++.dg/ipa/pr63587-1.C
Normal file
92
gcc/testsuite/g++.dg/ipa/pr63587-1.C
Normal file
@ -0,0 +1,92 @@
|
||||
// PR ipa/63587
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "-O2 -fno-strict-aliasing" }
|
||||
|
||||
template <class> struct A
|
||||
{
|
||||
};
|
||||
template <typename> struct B
|
||||
{
|
||||
template <typename> struct C;
|
||||
};
|
||||
class D;
|
||||
template <typename> class F;
|
||||
struct G
|
||||
{
|
||||
void operator()(const D &, D);
|
||||
};
|
||||
class D
|
||||
{
|
||||
public:
|
||||
D (int);
|
||||
};
|
||||
struct H
|
||||
{
|
||||
H (int);
|
||||
};
|
||||
template <typename _Key, typename, typename, typename _Compare, typename>
|
||||
class I
|
||||
{
|
||||
typedef _Key key_type;
|
||||
template <typename _Key_compare> struct J
|
||||
{
|
||||
_Key_compare _M_key_compare;
|
||||
};
|
||||
J<_Compare> _M_impl;
|
||||
|
||||
public:
|
||||
A<int> _M_get_insert_unique_pos (const key_type &);
|
||||
A<int> _M_get_insert_hint_unique_pos (H &);
|
||||
template <typename... _Args> int _M_emplace_hint_unique (H, _Args &&...);
|
||||
};
|
||||
template <typename _Key, typename _Tp, typename _Compare = G,
|
||||
typename _Alloc = F<A<_Tp> > >
|
||||
class K
|
||||
{
|
||||
typedef _Key key_type;
|
||||
typedef _Key value_type;
|
||||
typedef typename B<_Alloc>::template C<value_type> _Pair_alloc_type;
|
||||
I<key_type, value_type, int, _Compare, _Pair_alloc_type> _M_t;
|
||||
|
||||
public:
|
||||
void operator[](key_type)
|
||||
{
|
||||
_M_t._M_emplace_hint_unique (0);
|
||||
}
|
||||
};
|
||||
template <typename _Key, typename _Val, typename _KeyOfValue,
|
||||
typename _Compare, typename _Alloc>
|
||||
A<int>
|
||||
I<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos (
|
||||
const key_type &p1)
|
||||
{
|
||||
_M_impl._M_key_compare (p1, 0);
|
||||
}
|
||||
template <typename _Key, typename _Val, typename _KeyOfValue,
|
||||
typename _Compare, typename _Alloc>
|
||||
A<int>
|
||||
I<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_hint_unique_pos (
|
||||
H &)
|
||||
{
|
||||
_M_get_insert_unique_pos (0);
|
||||
}
|
||||
template <typename _Key, typename _Val, typename _KeyOfValue,
|
||||
typename _Compare, typename _Alloc>
|
||||
template <typename... _Args>
|
||||
int
|
||||
I<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique (
|
||||
H p1, _Args &&...)
|
||||
{
|
||||
_M_get_insert_hint_unique_pos (p1);
|
||||
}
|
||||
namespace {
|
||||
struct L;
|
||||
}
|
||||
void
|
||||
fn1 ()
|
||||
{
|
||||
K<D, L> a;
|
||||
a[0];
|
||||
K<D, int> b;
|
||||
b[0];
|
||||
}
|
250
gcc/testsuite/g++.dg/ipa/pr63587-2.C
Normal file
250
gcc/testsuite/g++.dg/ipa/pr63587-2.C
Normal file
@ -0,0 +1,250 @@
|
||||
// PR ipa/63587
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "-O2" }
|
||||
|
||||
namespace boost {
|
||||
class basic_cstring
|
||||
{
|
||||
public:
|
||||
basic_cstring (char *);
|
||||
};
|
||||
template <typename> struct identity
|
||||
{
|
||||
};
|
||||
struct make_identity;
|
||||
struct function_buffer
|
||||
{
|
||||
};
|
||||
template <typename FunctionObj> struct function_obj_invoker0
|
||||
{
|
||||
static int
|
||||
invoke (function_buffer &)
|
||||
{
|
||||
FunctionObj f;
|
||||
f ();
|
||||
}
|
||||
};
|
||||
template <typename FunctionObj> struct get_function_obj_invoker0
|
||||
{
|
||||
typedef function_obj_invoker0<FunctionObj> type;
|
||||
};
|
||||
template <typename FunctionObj> struct apply
|
||||
{
|
||||
typedef typename get_function_obj_invoker0<FunctionObj>::type invoker_type;
|
||||
};
|
||||
struct basic_vtable0
|
||||
{
|
||||
typedef int (*invoker_type)(function_buffer &);
|
||||
template <typename F> void assign_to (F, function_buffer);
|
||||
invoker_type invoker;
|
||||
};
|
||||
class function0
|
||||
{
|
||||
public:
|
||||
template <typename Functor> function0 (Functor)
|
||||
{
|
||||
typedef typename apply<Functor>::invoker_type invoker_type;
|
||||
basic_vtable0 stored_vtable { invoker_type::invoke };
|
||||
stored_vtable.assign_to (0, functor);
|
||||
}
|
||||
function_buffer functor;
|
||||
};
|
||||
class function : function0
|
||||
{
|
||||
public:
|
||||
template <typename Functor> function (Functor f) : function0 (f) {}
|
||||
};
|
||||
class test_unit_generator
|
||||
{
|
||||
};
|
||||
class test_case
|
||||
{
|
||||
public:
|
||||
test_case (basic_cstring, basic_cstring, int, function);
|
||||
};
|
||||
struct auto_test_unit_registrar
|
||||
{
|
||||
auto_test_unit_registrar (test_unit_generator);
|
||||
};
|
||||
template <typename F> F unwrap (F, int);
|
||||
struct for_each_impl
|
||||
{
|
||||
template <typename Iterator, typename LastIterator, typename TransformFunc,
|
||||
typename F>
|
||||
static void
|
||||
execute (Iterator, LastIterator, TransformFunc, F f)
|
||||
{
|
||||
identity<char> __trans_tmp_1;
|
||||
unwrap (f, 0)(__trans_tmp_1);
|
||||
}
|
||||
};
|
||||
template <typename, typename, typename F>
|
||||
void
|
||||
for_each (F f)
|
||||
{
|
||||
for_each_impl::execute (0, 0, 0, f);
|
||||
}
|
||||
template <typename TestCaseTemplate> class test_case_template_invoker
|
||||
{
|
||||
public:
|
||||
void operator()()
|
||||
{
|
||||
TestCaseTemplate::run (0);
|
||||
}
|
||||
};
|
||||
template <typename Generator, typename TestCaseTemplate>
|
||||
struct generate_test_case_4_type
|
||||
{
|
||||
generate_test_case_4_type (basic_cstring, basic_cstring, int, Generator G)
|
||||
: m_test_case_name (0), m_test_case_file (0), m_holder (G)
|
||||
{
|
||||
}
|
||||
template <typename TestType> void operator()(identity<TestType>)
|
||||
{
|
||||
test_case (0, 0, 0, test_case_template_invoker<TestCaseTemplate> ());
|
||||
}
|
||||
basic_cstring m_test_case_name;
|
||||
basic_cstring m_test_case_file;
|
||||
Generator m_holder;
|
||||
};
|
||||
template <typename TestCaseTemplate>
|
||||
class template_test_case_gen : public test_unit_generator
|
||||
{
|
||||
public:
|
||||
template_test_case_gen (basic_cstring, basic_cstring, int)
|
||||
{
|
||||
for_each<int, make_identity> (
|
||||
generate_test_case_4_type<template_test_case_gen, TestCaseTemplate> (
|
||||
0, 0, 0, *this));
|
||||
}
|
||||
};
|
||||
class attribute_name
|
||||
{
|
||||
int m_id;
|
||||
|
||||
public:
|
||||
attribute_name (char);
|
||||
};
|
||||
template <typename> struct term;
|
||||
namespace exprns_ {
|
||||
template <typename> struct expr;
|
||||
}
|
||||
using exprns_::expr;
|
||||
template <typename T> struct Trans_NS_proto_terminal
|
||||
{
|
||||
typedef expr<term<T> > type;
|
||||
};
|
||||
namespace exprns_ {
|
||||
template <typename Arg0> struct expr<term<Arg0> >
|
||||
{
|
||||
Arg0 child0;
|
||||
};
|
||||
}
|
||||
template <typename Expr> struct actor
|
||||
{
|
||||
typename Trans_NS_proto_terminal<Expr>::type proto_expr_;
|
||||
};
|
||||
template <template <typename> class Actor = actor> struct terminal
|
||||
{
|
||||
typedef Actor<int> type;
|
||||
};
|
||||
namespace log {
|
||||
struct to_log_fun
|
||||
{
|
||||
};
|
||||
class value_extractor;
|
||||
template <typename, typename = value_extractor, typename = void,
|
||||
template <typename> class = actor>
|
||||
class attribute_actor;
|
||||
class attribute_terminal
|
||||
{
|
||||
public:
|
||||
attribute_name m_name;
|
||||
attribute_name
|
||||
get_name ()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
};
|
||||
template <typename, typename, typename, template <typename> class ActorT>
|
||||
class attribute_actor : ActorT<attribute_terminal>
|
||||
{
|
||||
public:
|
||||
typedef int value_type;
|
||||
attribute_name
|
||||
get_name ()
|
||||
{
|
||||
return this->proto_expr_.child0.get_name ();
|
||||
}
|
||||
};
|
||||
template <typename AttributeValueT>
|
||||
attribute_actor<AttributeValueT> attr (attribute_name);
|
||||
terminal<>::type stream;
|
||||
template <typename LeftT, typename ImplT> class attribute_output_terminal
|
||||
{
|
||||
public:
|
||||
template <typename U>
|
||||
attribute_output_terminal (LeftT, attribute_name, ImplT, U);
|
||||
};
|
||||
template <typename LeftT> struct make_output_expression
|
||||
{
|
||||
typedef attribute_output_terminal<LeftT, to_log_fun> type;
|
||||
template <typename RightT>
|
||||
static type
|
||||
make (LeftT left, RightT &right)
|
||||
{
|
||||
type (left, right.get_name (), to_log_fun (), 0);
|
||||
}
|
||||
};
|
||||
template <typename, typename RightT, typename = typename RightT::value_type>
|
||||
struct make_output_actor;
|
||||
template <template <typename> class ActorT, typename LeftExprT,
|
||||
typename RightT, typename ValueT>
|
||||
struct make_output_actor<ActorT<LeftExprT>, RightT, ValueT>
|
||||
{
|
||||
typedef make_output_expression<ActorT<LeftExprT> > make_expression;
|
||||
typedef ActorT<typename make_expression::type> type;
|
||||
static type
|
||||
make (ActorT<LeftExprT> left, RightT &right)
|
||||
{
|
||||
type { make_expression::make (left, right) };
|
||||
}
|
||||
};
|
||||
template <typename LeftExprT, typename T, typename FallbackPolicyT,
|
||||
typename TagT>
|
||||
typename make_output_actor<actor<LeftExprT>, attribute_actor<TagT> >::type
|
||||
operator<<(actor<LeftExprT> left,
|
||||
attribute_actor<T, FallbackPolicyT, TagT> right)
|
||||
{
|
||||
make_output_actor<actor<LeftExprT>, attribute_actor<T> >::make (left, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace logging = boost::log;
|
||||
namespace expr = logging;
|
||||
namespace {
|
||||
class my_class;
|
||||
}
|
||||
template <typename> struct default_formatting
|
||||
{
|
||||
void test_method ();
|
||||
};
|
||||
struct default_formatting_invoker
|
||||
{
|
||||
static void
|
||||
run (void *)
|
||||
{
|
||||
default_formatting<int> t;
|
||||
t.test_method ();
|
||||
}
|
||||
};
|
||||
boost::auto_test_unit_registrar default_formatting_registrar56 (
|
||||
boost::template_test_case_gen<default_formatting_invoker> (0, 0, 0));
|
||||
template <typename CharT>
|
||||
void
|
||||
default_formatting<CharT>::test_method ()
|
||||
{
|
||||
expr::stream << expr::attr<my_class> (0);
|
||||
expr::stream << expr::attr<int> (0) << expr::attr<int> (0)
|
||||
<< expr::attr<int> (0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user