re PR debug/65549 (crash in htab_hash_string with -flto -g)
2015-06-02 Richard Biener <rguenther@suse.de> PR debug/65549 * dwarf2out.c (lookup_context_die): New function. (resolve_addr): Avoid forcing a full DIE for the target of a DW_TAG_GNU_call_site during late compilation. Instead create a stub DIE without a type if we have a context DIE present. * g++.dg/lto/pr65549_0.C: New testcase. From-SVN: r224029
This commit is contained in:
parent
1817fe58f2
commit
71fa02e0d8
4 changed files with 193 additions and 3 deletions
|
@ -1,3 +1,12 @@
|
|||
2015-06-02 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR debug/65549
|
||||
* dwarf2out.c (lookup_context_die): New function.
|
||||
(resolve_addr): Avoid forcing a full DIE for the
|
||||
target of a DW_TAG_GNU_call_site during late compilation.
|
||||
Instead create a stub DIE without a type if we have a
|
||||
context DIE present.
|
||||
|
||||
2015-06-02 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* df-scan.c (df_scan_start_dump): Add space between regno and regname.
|
||||
|
|
|
@ -20621,6 +20621,28 @@ is_naming_typedef_decl (const_tree decl)
|
|||
!= TYPE_NAME (TREE_TYPE (decl))));
|
||||
}
|
||||
|
||||
/* Looks up the DIE for a context. */
|
||||
|
||||
static inline dw_die_ref
|
||||
lookup_context_die (tree context)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
/* Find die that represents this context. */
|
||||
if (TYPE_P (context))
|
||||
{
|
||||
context = TYPE_MAIN_VARIANT (context);
|
||||
dw_die_ref ctx = lookup_type_die (context);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
return strip_naming_typedef (context, ctx);
|
||||
}
|
||||
else
|
||||
return lookup_decl_die (context);
|
||||
}
|
||||
return comp_unit_die ();
|
||||
}
|
||||
|
||||
/* Returns the DIE for a context. */
|
||||
|
||||
static inline dw_die_ref
|
||||
|
@ -23949,12 +23971,22 @@ resolve_addr (dw_die_ref die)
|
|||
{
|
||||
tree tdecl = SYMBOL_REF_DECL (a->dw_attr_val.v.val_addr);
|
||||
dw_die_ref tdie = lookup_decl_die (tdecl);
|
||||
dw_die_ref cdie;
|
||||
if (tdie == NULL
|
||||
&& DECL_EXTERNAL (tdecl)
|
||||
&& DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE)
|
||||
&& DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE
|
||||
&& (cdie = lookup_context_die (DECL_CONTEXT (tdecl))))
|
||||
{
|
||||
force_decl_die (tdecl);
|
||||
tdie = lookup_decl_die (tdecl);
|
||||
/* Creating a full DIE for tdecl is overly expensive and
|
||||
at this point even wrong when in the LTO phase
|
||||
as it can end up generating new type DIEs we didn't
|
||||
output and thus optimize_external_refs will crash. */
|
||||
tdie = new_die (DW_TAG_subprogram, cdie, NULL_TREE);
|
||||
add_AT_flag (tdie, DW_AT_external, 1);
|
||||
add_AT_flag (tdie, DW_AT_declaration, 1);
|
||||
add_linkage_attr (tdie, tdecl);
|
||||
add_name_and_src_coords_attributes (tdie, tdecl);
|
||||
equate_decl_number_to_die (tdecl, tdie);
|
||||
}
|
||||
if (tdie)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2015-06-02 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR debug/65549
|
||||
* g++.dg/lto/pr65549_0.C: New testcase.
|
||||
|
||||
2015-06-02 Thomas Schwinge <thomas@codesourcery.com>
|
||||
|
||||
PR libgomp/65742
|
||||
|
|
144
gcc/testsuite/g++.dg/lto/pr65549_0.C
Normal file
144
gcc/testsuite/g++.dg/lto/pr65549_0.C
Normal file
|
@ -0,0 +1,144 @@
|
|||
// { dg-lto-do link }
|
||||
// { dg-lto-options { { -std=gnu++14 -flto -g } { -std=gnu++14 -flto -g -O2 -fno-inline -flto-partition=max } } }
|
||||
// { dg-extra-ld-options "-r -nostdlib" }
|
||||
|
||||
namespace std {
|
||||
inline namespace __cxx11 {}
|
||||
template <typename _Tp, _Tp> struct integral_constant {
|
||||
static constexpr _Tp value = 0;
|
||||
};
|
||||
template <typename> struct __and_;
|
||||
struct is_member_object_pointer : integral_constant<bool, false> {};
|
||||
template <typename>
|
||||
struct is_member_function_pointer : integral_constant<bool, false> {};
|
||||
template <typename> struct remove_reference { typedef int type; };
|
||||
template <typename> class C;
|
||||
template <bool, int, typename...> struct __result_of_impl;
|
||||
template <typename _Functor, typename... _ArgTypes>
|
||||
struct __result_of_impl<false, 0, _Functor, _ArgTypes...> {
|
||||
typedef decltype(0) type;
|
||||
};
|
||||
template <typename _Functor, typename... _ArgTypes>
|
||||
struct C<_Functor(_ArgTypes...)>
|
||||
: __result_of_impl<is_member_object_pointer::value,
|
||||
is_member_function_pointer<
|
||||
typename remove_reference<_Functor>::type>::value,
|
||||
_Functor> {};
|
||||
template <typename _Tp> using result_of_t = typename C<_Tp>::type;
|
||||
template <typename> void forward();
|
||||
template <typename _Tp> _Tp move(_Tp) {}
|
||||
namespace __cxx11 {
|
||||
class basic_string typedef string;
|
||||
}
|
||||
template <typename> struct allocator_traits { typedef decltype(0) pointer; };
|
||||
}
|
||||
struct F : std::allocator_traits<int> {};
|
||||
namespace std {
|
||||
namespace __cxx11 {
|
||||
class basic_string {
|
||||
public:
|
||||
struct _Alloc_hider : F {
|
||||
_Alloc_hider(pointer);
|
||||
} _M_dataplus;
|
||||
basic_string(int) : _M_dataplus(0) {}
|
||||
~basic_string();
|
||||
};
|
||||
}
|
||||
template <typename> class function;
|
||||
template <typename _Functor> class _Base_manager {
|
||||
protected:
|
||||
static _Functor *_M_get_pointer(int) {}
|
||||
};
|
||||
template <typename, typename> class _Function_handler;
|
||||
template <typename _Res, typename _Functor, typename... _ArgTypes>
|
||||
class _Function_handler<_Res(_ArgTypes...), _Functor>
|
||||
: _Base_manager<_Functor> {
|
||||
public:
|
||||
static _Res _M_invoke(const int &) {
|
||||
(*_Base_manager<_Functor>::_M_get_pointer(0))();
|
||||
}
|
||||
};
|
||||
template <typename, typename> using __check_func_return_type = int;
|
||||
template <typename _Res, typename... _ArgTypes>
|
||||
class function<_Res(_ArgTypes...)> {
|
||||
template <typename> using _Invoke = decltype(0);
|
||||
template <typename _Functor>
|
||||
using _Callable = __and_<__check_func_return_type<_Invoke<_Functor>, _Res>>;
|
||||
template <typename, typename> using _Requires = int;
|
||||
|
||||
public:
|
||||
template <typename _Functor, typename = _Requires<_Callable<_Functor>, void>>
|
||||
function(_Functor);
|
||||
using _Invoker_type = _Res (*)(const int &);
|
||||
_Invoker_type _M_invoker;
|
||||
};
|
||||
template <typename _Res, typename... _ArgTypes>
|
||||
template <typename _Functor, typename>
|
||||
function<_Res(_ArgTypes...)>::function(_Functor) {
|
||||
_M_invoker = _Function_handler<_Res(), _Functor>::_M_invoke;
|
||||
}
|
||||
class unique_ptr {
|
||||
public:
|
||||
~unique_ptr();
|
||||
};
|
||||
template <typename _Tp, typename... _Args> _Tp make_unique(_Args... __args) {
|
||||
_Tp(__args...);
|
||||
}
|
||||
}
|
||||
class A {
|
||||
public:
|
||||
template <class T> T as();
|
||||
};
|
||||
class variables_map {
|
||||
public:
|
||||
A operator[](std::basic_string);
|
||||
};
|
||||
class B {
|
||||
public:
|
||||
variables_map configuration();
|
||||
void run(int, int, std::function<void()>);
|
||||
};
|
||||
class H;
|
||||
struct G {
|
||||
enum {} _state;
|
||||
};
|
||||
class D {
|
||||
G _local_state;
|
||||
std::unique_ptr _task;
|
||||
template <typename Func> void schedule(Func func) {
|
||||
struct task_with_state {
|
||||
task_with_state(Func func) : _func(func) {}
|
||||
Func _func;
|
||||
} tws = std::make_unique<task_with_state>(std::move(func));
|
||||
}
|
||||
friend H;
|
||||
};
|
||||
template <typename> using futurize_t = H;
|
||||
class H {
|
||||
D *_promise;
|
||||
template <typename Func> void schedule(Func func) {
|
||||
G __trans_tmp_1;
|
||||
struct task_with_ready_state {
|
||||
task_with_ready_state(Func, G);
|
||||
};
|
||||
std::make_unique<task_with_ready_state>(std::move(func), __trans_tmp_1);
|
||||
_promise->schedule(std::move(func));
|
||||
}
|
||||
template <typename Func, typename Param> void then(Func func, Param) {
|
||||
using P = D;
|
||||
P pr;
|
||||
schedule([ pr = std::move(pr), func, param = std::forward<Param> ]{});
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename Func> futurize_t<std::result_of_t<Func()>> then(Func) {
|
||||
then(0, [] {});
|
||||
}
|
||||
} clients;
|
||||
main() {
|
||||
B app;
|
||||
app.run(0, 0, [&] {
|
||||
auto config = app.configuration()[0].as<std::string>();
|
||||
clients.then([] {});
|
||||
});
|
||||
}
|
Loading…
Add table
Reference in a new issue