re PR c++/65209 (Broken code with global static variables, invalid pointer when freeing global variables)

PR c++/65209
	* decl2.c (constrain_visibility) [VISIBILITY_ANON]: Clear
	DECL_COMDAT.
	(constrain_visibility_for_template): Handle reference arguments.

From-SVN: r220991
This commit is contained in:
Jason Merrill 2015-02-25 16:46:29 -05:00 committed by Jason Merrill
parent 76fabbf42d
commit 2b8f9c8f36
3 changed files with 52 additions and 2 deletions

View File

@ -1,5 +1,10 @@
2015-02-25 Jason Merrill <jason@redhat.com>
PR c++/65209
* decl2.c (constrain_visibility) [VISIBILITY_ANON]: Clear
DECL_COMDAT.
(constrain_visibility_for_template): Handle reference arguments.
PR debug/58315
* decl.c (start_preparsed_function): Use create_artificial_label
for cdtor_label.

View File

@ -2175,6 +2175,7 @@ constrain_visibility (tree decl, int visibility, bool tmpl)
TREE_PUBLIC (decl) = 0;
DECL_WEAK (decl) = 0;
DECL_COMMON (decl) = 0;
DECL_COMDAT (decl) = false;
if (TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
{
@ -2215,9 +2216,12 @@ constrain_visibility_for_template (tree decl, tree targs)
tree arg = TREE_VEC_ELT (args, i-1);
if (TYPE_P (arg))
vis = type_visibility (arg);
else if (TREE_TYPE (arg) && POINTER_TYPE_P (TREE_TYPE (arg)))
else
{
STRIP_NOPS (arg);
if (REFERENCE_REF_P (arg))
arg = TREE_OPERAND (arg, 0);
if (TREE_TYPE (arg))
STRIP_NOPS (arg);
if (TREE_CODE (arg) == ADDR_EXPR)
arg = TREE_OPERAND (arg, 0);
if (VAR_OR_FUNCTION_DECL_P (arg))

View File

@ -0,0 +1,41 @@
// PR c++/65209
// { dg-final { scan-assembler-not "comdat" } }
// Everything involving the anonymous namespace bits should be private, not
// COMDAT.
struct Bar
{
static Bar *self();
char pad[24];
};
template <Bar *(&holderFunction)()>
struct BarGlobalStatic
{
Bar *operator()() { return holderFunction(); }
};
namespace {
namespace Q_QGS_s_self {
inline Bar *innerFunction() {
static struct Holder {
Bar value;
~Holder() {}
} holder;
return &holder.value;
}
}
}
static BarGlobalStatic<Q_QGS_s_self::innerFunction> s_self;
Bar *Bar::self()
{
return s_self();
}
int main(int argc, char *argv[])
{
Bar* bar = Bar::self();
return 0;
}