mirror of git://gcc.gnu.org/git/gcc.git
decl.c (record_key_method_defined): New, broken out of ...
cp/ * decl.c (record_key_method_defined): New, broken out of ... (finish_function): ... here. Call it. (start_decl): Treat aliases as definitions. testsuite/ * g++.dg/ext/attr-alias-1.C: New. * g++.dg/ext/attr-alias-2.C: New. From-SVN: r160431
This commit is contained in:
parent
4b9c045f7e
commit
3bb1ed661a
|
@ -1,3 +1,9 @@
|
||||||
|
2010-06-08 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
* decl.c (record_key_method_defined): New, broken out of ...
|
||||||
|
(finish_function): ... here. Call it.
|
||||||
|
(start_decl): Treat aliases as definitions.
|
||||||
|
|
||||||
2010-06-08 Laurynas Biveinis <laurynas.biveinis@gmail.com>
|
2010-06-08 Laurynas Biveinis <laurynas.biveinis@gmail.com>
|
||||||
|
|
||||||
* typeck2.c (abstract_virtuals_error): Use typed GC allocation.
|
* typeck2.c (abstract_virtuals_error): Use typed GC allocation.
|
||||||
|
|
|
@ -90,6 +90,7 @@ static void check_function_type (tree, tree);
|
||||||
static void finish_constructor_body (void);
|
static void finish_constructor_body (void);
|
||||||
static void begin_destructor_body (void);
|
static void begin_destructor_body (void);
|
||||||
static void finish_destructor_body (void);
|
static void finish_destructor_body (void);
|
||||||
|
static void record_key_method_defined (tree);
|
||||||
static tree create_array_type_for_decl (tree, tree, tree);
|
static tree create_array_type_for_decl (tree, tree, tree);
|
||||||
static tree get_atexit_node (void);
|
static tree get_atexit_node (void);
|
||||||
static tree get_dso_handle_node (void);
|
static tree get_dso_handle_node (void);
|
||||||
|
@ -4129,6 +4130,7 @@ start_decl (const cp_declarator *declarator,
|
||||||
tree context;
|
tree context;
|
||||||
bool was_public;
|
bool was_public;
|
||||||
int flags;
|
int flags;
|
||||||
|
bool alias;
|
||||||
|
|
||||||
*pushed_scope_p = NULL_TREE;
|
*pushed_scope_p = NULL_TREE;
|
||||||
|
|
||||||
|
@ -4190,6 +4192,10 @@ start_decl (const cp_declarator *declarator,
|
||||||
if (toplevel_bindings_p ())
|
if (toplevel_bindings_p ())
|
||||||
TREE_STATIC (decl) = 1;
|
TREE_STATIC (decl) = 1;
|
||||||
}
|
}
|
||||||
|
alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) != 0;
|
||||||
|
|
||||||
|
if (alias && TREE_CODE (decl) == FUNCTION_DECL)
|
||||||
|
record_key_method_defined (decl);
|
||||||
|
|
||||||
/* If this is a typedef that names the class for linkage purposes
|
/* If this is a typedef that names the class for linkage purposes
|
||||||
(7.1.3p8), apply any attributes directly to the type. */
|
(7.1.3p8), apply any attributes directly to the type. */
|
||||||
|
@ -4292,7 +4298,9 @@ start_decl (const cp_declarator *declarator,
|
||||||
DECL_EXTERNAL (decl) = 1;
|
DECL_EXTERNAL (decl) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
|
if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)
|
||||||
|
/* Aliases are definitions. */
|
||||||
|
&& !alias)
|
||||||
permerror (input_location, "declaration of %q#D outside of class is not definition",
|
permerror (input_location, "declaration of %q#D outside of class is not definition",
|
||||||
decl);
|
decl);
|
||||||
|
|
||||||
|
@ -12502,6 +12510,22 @@ outer_curly_brace_block (tree fndecl)
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If FNDECL is a class's key method, add the class to the list of
|
||||||
|
keyed classes that should be emitted. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
record_key_method_defined (tree fndecl)
|
||||||
|
{
|
||||||
|
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
|
||||||
|
&& DECL_VIRTUAL_P (fndecl)
|
||||||
|
&& !processing_template_decl)
|
||||||
|
{
|
||||||
|
tree fnclass = DECL_CONTEXT (fndecl);
|
||||||
|
if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
|
||||||
|
keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Finish up a function declaration and compile that function
|
/* Finish up a function declaration and compile that function
|
||||||
all the way to assembler language output. The free the storage
|
all the way to assembler language output. The free the storage
|
||||||
for the function definition.
|
for the function definition.
|
||||||
|
@ -12528,14 +12552,7 @@ finish_function (int flags)
|
||||||
gcc_assert (!defer_mark_used_calls);
|
gcc_assert (!defer_mark_used_calls);
|
||||||
defer_mark_used_calls = true;
|
defer_mark_used_calls = true;
|
||||||
|
|
||||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
|
record_key_method_defined (fndecl);
|
||||||
&& DECL_VIRTUAL_P (fndecl)
|
|
||||||
&& !processing_template_decl)
|
|
||||||
{
|
|
||||||
tree fnclass = DECL_CONTEXT (fndecl);
|
|
||||||
if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
|
|
||||||
keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
|
|
||||||
}
|
|
||||||
|
|
||||||
nested = function_depth > 1;
|
nested = function_depth > 1;
|
||||||
fntype = TREE_TYPE (fndecl);
|
fntype = TREE_TYPE (fndecl);
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2010-06-08 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
* g++.dg/ext/attr-alias-1.C: New.
|
||||||
|
* g++.dg/ext/attr-alias-2.C: New.
|
||||||
|
|
||||||
2010-06-07 Tobias Burnus <burnus@net-b.de>
|
2010-06-07 Tobias Burnus <burnus@net-b.de>
|
||||||
|
|
||||||
PR fortran/44446
|
PR fortran/44446
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-require-alias "" } */
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
struct Klass
|
||||||
|
{
|
||||||
|
int implementation () const;
|
||||||
|
int magic () const;
|
||||||
|
};
|
||||||
|
|
||||||
|
int Klass::implementation (void) const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Klass::magic () const
|
||||||
|
__attribute__ ((alias ("_ZNK5Klass14implementationEv")));
|
||||||
|
|
||||||
|
int __attribute__ ((noinline))
|
||||||
|
Foo (Klass const *ptr)
|
||||||
|
{
|
||||||
|
if (ptr->magic () != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (typeid (*ptr) != typeid (Klass))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
Klass obj;
|
||||||
|
|
||||||
|
return Foo (&obj);
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-require-alias "" } */
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
struct Klass
|
||||||
|
{
|
||||||
|
int implementation () const;
|
||||||
|
virtual int magic () const;
|
||||||
|
};
|
||||||
|
|
||||||
|
int Klass::implementation (void) const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Klass::magic () const
|
||||||
|
__attribute__ ((alias ("_ZNK5Klass14implementationEv")));
|
||||||
|
|
||||||
|
int __attribute__ ((noinline))
|
||||||
|
Foo (Klass const *ptr)
|
||||||
|
{
|
||||||
|
if (ptr->magic () != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (typeid (*ptr) != typeid (Klass))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
Klass obj;
|
||||||
|
|
||||||
|
return Foo (&obj);
|
||||||
|
}
|
Loading…
Reference in New Issue