Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
e8abc66f
Commit
e8abc66f
authored
Apr 24, 1995
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
67th Cygnus<->FSF merge
From-SVN: r9433
parent
87c73618
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
349 additions
and
472 deletions
+349
-472
gcc/cp/ChangeLog
+95
-0
gcc/cp/call.c
+17
-2
gcc/cp/class.c
+12
-17
gcc/cp/cp-tree.h
+10
-0
gcc/cp/decl.c
+1
-0
gcc/cp/decl2.c
+24
-3
gcc/cp/expr.c
+2
-2
gcc/cp/gxxint.texi
+75
-22
gcc/cp/init.c
+2
-2
gcc/cp/lex.c
+2
-348
gcc/cp/method.c
+2
-2
gcc/cp/parse.y
+1
-0
gcc/cp/pt.c
+19
-5
gcc/cp/repo.c
+36
-34
gcc/cp/search.c
+3
-0
gcc/cp/tree.c
+7
-3
gcc/cp/typeck.c
+36
-28
gcc/cp/typeck2.c
+5
-4
No files found.
gcc/cp/ChangeLog
View file @
e8abc66f
Sun Apr 23 12:32:38 1995 Mike Stump <mrs@cygnus.com>
* decl2.c (finish_file): Fix broken linked list handling.
Fri Apr 21 18:08:43 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* class.c (finish_base_struct): Don't set TYPE_HAS_COMPLEX_*_REF
as often.
(finish_struct): Ditto.
* various: Use TYPE_HAS_TRIVIAL_* instead of TYPE_HAS_COMPLEX_*.
* cp-tree.h (TYPE_HAS_TRIVIAL_INIT_REF): New macro.
(TYPE_HAS_TRIVIAL_ASSIGN_REF): New macro.
Fri Apr 21 15:52:22 1995 Jason Merrill <jason@python.cygnus.com>
* typeck.c (c_expand_return): Only expand a returned TARGET_EXPR if
it is of the same type as the return value.
Fri Apr 21 03:01:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl2.c (finish_file): Reconsider if synthesizing a method wrote
out its assembly.
* typeck.c (convert_for_initialization): Don't call a trivial copy
constructor.
* typeck2.c (store_init_value): Only abort if the type has a
non-trivial copy constructor.
* typeck.c (c_expand_return): If we're returning in a register and
the return value is a TARGET_EXPR, expand it. Only do
expand_aggr_init if we're returning in memory.
(expand_target_expr): Function to expand a TARGET_EXPR.
(build_modify_expr): Use it.
* tree.c (build_cplus_new): Layout the slot.
* expr.c (cplus_expand_expr): Use expand_call to expand the call
under a NEW_EXPR, so the target is not discarded.
Thu Apr 20 14:59:31 1995 Mike Stump <mrs@cygnus.com>
* gc.c (build_dynamic_cast): Tighten error checking.
Thu Apr 20 11:23:54 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* expr.c (cplus_expand_expr): Only abort if the returned target is
different from what we expected if the type has a non-trivial copy
constructor.
* decl2.c (cplus_decl_attributes): Attributes applied to a template
really apply to the template's result.
* tree.c (lvalue_p): Check IS_AGGR_TYPE instead of TREE_ADDRESSABLE
to decide whether to consider a CALL_EXPR an lvalue.
* class.c (finish_struct_bits): Only set TREE_ADDRESSABLE if the
type has a non-trivial copy constructor.
* decl.c (start_function): If interface_known, unset
DECL_NOT_REALLY_EXTERN on the function.
Wed Apr 19 16:53:13 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* pt.c (do_function_instantiation): Handle explicit instantiation of
member functions.
(do_type_instantiation): Handle 'inline template class foo<int>',
meaning just spit out the vtable.
* lex.c (cons_up_default_function): Set DECL_NOT_REALLY_EXTERN on
the consed functions.
* decl2.c (import_export_inline): Set DECL_INTERFACE_KNOWN.
Wed Apr 19 16:28:17 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
* call.c, class.c, decl2.c, gc.c, init.c, parse.y, pt.c, search.c,
typeck.c: Include output.h.
Wed Apr 19 14:57:21 1995 Gerald Baumgartner (gb@alexander.cs.purdue.edu)
* call.c (build_method_call): Allow a signature member functions to
be called from a default implementation.
Wed Apr 19 10:21:17 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* repo.c (finish_repo): Remember what directory we are in.
* search.c (expand_upcast_fixups): Don't mess with abort_fndecl.
* repo.c: Use obstacks instead of fixed-size buffers. Don't spit
out the second copy of the symbol name. Don't remember COLLECT_GCC.
Wed Apr 19 02:32:40 1995 Mike Stump <mrs@cygnus.com>
Wed Apr 19 02:32:40 1995 Mike Stump <mrs@cygnus.com>
* search.c (virtual_context): New function to get the virtual
* search.c (virtual_context): New function to get the virtual
...
...
gcc/cp/call.c
View file @
e8abc66f
...
@@ -27,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -27,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <stdio.h>
#include "cp-tree.h"
#include "cp-tree.h"
#include "class.h"
#include "class.h"
#include "output.h"
#include "flags.h"
#include "flags.h"
#include "obstack.h"
#include "obstack.h"
...
@@ -1683,10 +1684,24 @@ build_method_call (instance, name, parms, basetype_path, flags)
...
@@ -1683,10 +1684,24 @@ build_method_call (instance, name, parms, basetype_path, flags)
need_vtbl
=
(
dtor_label
||
ctor_label
)
need_vtbl
=
(
dtor_label
||
ctor_label
)
?
unneeded
:
maybe_needed
;
?
unneeded
:
maybe_needed
;
/* If `this' is a signature pointer and `name' is not a constructor,
we are calling a signature member function. In that case, set the
`basetype' to the signature type and dereference the `optr' field. */
if
(
IS_SIGNATURE_POINTER
(
basetype
)
&&
TYPE_IDENTIFIER
(
basetype
)
!=
name
)
{
basetype
=
SIGNATURE_TYPE
(
basetype
);
instance_ptr
=
build_optr_ref
(
instance
);
instance_ptr
=
convert
(
TYPE_POINTER_TO
(
basetype
),
instance_ptr
);
basetype_path
=
TYPE_BINFO
(
basetype
);
}
else
{
instance
=
C_C_D
;
instance
=
C_C_D
;
instance_ptr
=
current_class_decl
;
instance_ptr
=
current_class_decl
;
result
=
build_field_call
(
TYPE_BINFO
(
current_class_type
),
basetype_path
=
TYPE_BINFO
(
current_class_type
);
instance_ptr
,
name
,
parms
);
}
result
=
build_field_call
(
basetype_path
,
instance_ptr
,
name
,
parms
);
if
(
result
)
if
(
result
)
return
result
;
return
result
;
...
...
gcc/cp/class.c
View file @
e8abc66f
...
@@ -27,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -27,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "cp-tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "flags.h"
#include "rtl.h"
#include "rtl.h"
#include "output.h"
#include "obstack.h"
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_alloc xmalloc
...
@@ -1412,8 +1413,7 @@ finish_base_struct (t, b, t_binfo)
...
@@ -1412,8 +1413,7 @@ finish_base_struct (t, b, t_binfo)
TYPE_NEEDS_CONSTRUCTING
(
t
)
|=
TYPE_NEEDS_CONSTRUCTING
(
basetype
);
TYPE_NEEDS_CONSTRUCTING
(
t
)
|=
TYPE_NEEDS_CONSTRUCTING
(
basetype
);
TYPE_NEEDS_DESTRUCTOR
(
t
)
|=
TYPE_NEEDS_DESTRUCTOR
(
basetype
);
TYPE_NEEDS_DESTRUCTOR
(
t
)
|=
TYPE_NEEDS_DESTRUCTOR
(
basetype
);
TYPE_HAS_COMPLEX_ASSIGN_REF
(
t
)
|=
TYPE_HAS_COMPLEX_ASSIGN_REF
(
basetype
);
TYPE_HAS_COMPLEX_ASSIGN_REF
(
t
)
|=
TYPE_HAS_COMPLEX_ASSIGN_REF
(
basetype
);
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
|=
(
TYPE_HAS_COMPLEX_INIT_REF
(
basetype
)
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
|=
TYPE_HAS_COMPLEX_INIT_REF
(
basetype
);
||
TYPE_NEEDS_CONSTRUCTING
(
basetype
));
TYPE_OVERLOADS_CALL_EXPR
(
t
)
|=
TYPE_OVERLOADS_CALL_EXPR
(
basetype
);
TYPE_OVERLOADS_CALL_EXPR
(
t
)
|=
TYPE_OVERLOADS_CALL_EXPR
(
basetype
);
TYPE_OVERLOADS_ARRAY_REF
(
t
)
|=
TYPE_OVERLOADS_ARRAY_REF
(
basetype
);
TYPE_OVERLOADS_ARRAY_REF
(
t
)
|=
TYPE_OVERLOADS_ARRAY_REF
(
basetype
);
...
@@ -1688,19 +1688,19 @@ finish_struct_bits (t, max_has_virtual)
...
@@ -1688,19 +1688,19 @@ finish_struct_bits (t, max_has_virtual)
}
}
}
}
/* If this type has constructors, force its mode to be BLKmode,
/* If this type has a copy constructor, force its mode to be BLKmode, and
and force its TREE_ADDRESSABLE bit to be nonzero. */
force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to
if
(
TYPE_NEEDS_CONSTRUCTING
(
t
)
||
TYPE_NEEDS_DESTRUCTOR
(
t
))
be passed by invisible reference and prevent it from being returned in
a register. */
if
(
!
TYPE_HAS_TRIVIAL_INIT_REF
(
t
))
{
{
tree
variants
=
t
;
tree
variants
;
if
(
TREE_CODE
(
TYPE_NAME
(
t
))
==
TYPE_DECL
)
if
(
TREE_CODE
(
TYPE_NAME
(
t
))
==
TYPE_DECL
)
DECL_MODE
(
TYPE_NAME
(
t
))
=
BLKmode
;
DECL_MODE
(
TYPE_NAME
(
t
))
=
BLKmode
;
while
(
variants
)
for
(
variants
=
t
;
variants
;
variants
=
TYPE_NEXT_VARIANT
(
variants
)
)
{
{
TYPE_MODE
(
variants
)
=
BLKmode
;
TYPE_MODE
(
variants
)
=
BLKmode
;
TREE_ADDRESSABLE
(
variants
)
=
1
;
TREE_ADDRESSABLE
(
variants
)
=
1
;
variants
=
TYPE_NEXT_VARIANT
(
variants
);
}
}
}
}
}
}
...
@@ -3085,7 +3085,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
...
@@ -3085,7 +3085,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
members. */
members. */
cant_synth_asn_ref
=
1
;
cant_synth_asn_ref
=
1
;
cant_have_default_ctor
=
1
;
cant_have_default_ctor
=
1
;
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
=
1
;
if
(
!
TYPE_HAS_CONSTRUCTOR
(
t
)
&&
extra_warnings
)
if
(
!
TYPE_HAS_CONSTRUCTOR
(
t
)
&&
extra_warnings
)
{
{
...
@@ -3109,7 +3108,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
...
@@ -3109,7 +3108,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
members. */
members. */
cant_synth_asn_ref
=
1
;
cant_synth_asn_ref
=
1
;
cant_have_default_ctor
=
1
;
cant_have_default_ctor
=
1
;
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
=
1
;
if
(
!
TYPE_HAS_CONSTRUCTOR
(
t
)
&&
!
IS_SIGNATURE
(
t
)
if
(
!
TYPE_HAS_CONSTRUCTOR
(
t
)
&&
!
IS_SIGNATURE
(
t
)
&&
extra_warnings
)
&&
extra_warnings
)
...
@@ -3266,9 +3264,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
...
@@ -3266,9 +3264,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_NEEDS_CONSTRUCTING
(
t
)
|=
TYPE_NEEDS_CONSTRUCTING
(
type
);
TYPE_NEEDS_CONSTRUCTING
(
t
)
|=
TYPE_NEEDS_CONSTRUCTING
(
type
);
TYPE_NEEDS_DESTRUCTOR
(
t
)
|=
TYPE_NEEDS_DESTRUCTOR
(
type
);
TYPE_NEEDS_DESTRUCTOR
(
t
)
|=
TYPE_NEEDS_DESTRUCTOR
(
type
);
TYPE_HAS_COMPLEX_ASSIGN_REF
(
t
)
|=
TYPE_HAS_COMPLEX_ASSIGN_REF
(
type
);
TYPE_HAS_COMPLEX_ASSIGN_REF
(
t
)
|=
TYPE_HAS_COMPLEX_ASSIGN_REF
(
type
);
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
|=
TYPE_HAS_COMPLEX_INIT_REF
(
type
);
|=
(
TYPE_HAS_COMPLEX_INIT_REF
(
type
)
||
TYPE_NEEDS_CONSTRUCTING
(
type
));
}
}
if
(
!
TYPE_HAS_INIT_REF
(
type
)
if
(
!
TYPE_HAS_INIT_REF
(
type
)
...
@@ -3374,7 +3370,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
...
@@ -3374,7 +3370,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
TYPE_HAS_COMPLEX_INIT_REF
(
t
)
|=
(
TYPE_HAS_INIT_REF
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
)
|=
(
TYPE_HAS_INIT_REF
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
)
||
has_virtual
||
any_default_members
||
first_vfn_base_index
>=
0
);
||
any_default_members
);
TYPE_NEEDS_CONSTRUCTING
(
t
)
TYPE_NEEDS_CONSTRUCTING
(
t
)
|=
(
TYPE_HAS_CONSTRUCTOR
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
)
|=
(
TYPE_HAS_CONSTRUCTOR
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
)
||
has_virtual
||
any_default_members
||
first_vfn_base_index
>=
0
);
||
has_virtual
||
any_default_members
||
first_vfn_base_index
>=
0
);
...
@@ -3406,8 +3402,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
...
@@ -3406,8 +3402,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_HAS_REAL_ASSIGNMENT
(
t
)
|=
TYPE_HAS_ASSIGNMENT
(
t
);
TYPE_HAS_REAL_ASSIGNMENT
(
t
)
|=
TYPE_HAS_ASSIGNMENT
(
t
);
TYPE_HAS_REAL_ASSIGN_REF
(
t
)
|=
TYPE_HAS_ASSIGN_REF
(
t
);
TYPE_HAS_REAL_ASSIGN_REF
(
t
)
|=
TYPE_HAS_ASSIGN_REF
(
t
);
TYPE_HAS_COMPLEX_ASSIGN_REF
(
t
)
TYPE_HAS_COMPLEX_ASSIGN_REF
(
t
)
|=
(
TYPE_HAS_ASSIGN_REF
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
)
|=
TYPE_HAS_ASSIGN_REF
(
t
)
||
TYPE_USES_VIRTUAL_BASECLASSES
(
t
);
||
has_virtual
||
first_vfn_base_index
>=
0
);
if
(
!
TYPE_HAS_ASSIGN_REF
(
t
)
&&
!
cant_synth_asn_ref
if
(
!
TYPE_HAS_ASSIGN_REF
(
t
)
&&
!
cant_synth_asn_ref
&&
!
IS_SIGNATURE
(
t
))
&&
!
IS_SIGNATURE
(
t
))
...
...
gcc/cp/cp-tree.h
View file @
e8abc66f
...
@@ -1220,6 +1220,16 @@ struct lang_decl
...
@@ -1220,6 +1220,16 @@ struct lang_decl
of ARRAY_TYPE is the type of the elements needs a destructor. */
of ARRAY_TYPE is the type of the elements needs a destructor. */
#define TYPE_NEEDS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_4(NODE))
#define TYPE_NEEDS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_4(NODE))
/* Nonzero for class type means that initialization of this type can use
a bitwise copy. */
#define TYPE_HAS_TRIVIAL_INIT_REF(NODE) \
(TYPE_HAS_INIT_REF (NODE) && ! TYPE_HAS_COMPLEX_INIT_REF (NODE))
/* Nonzero for class type means that assignment of this type can use
a bitwise copy. */
#define TYPE_HAS_TRIVIAL_ASSIGN_REF(NODE) \
(TYPE_HAS_ASSIGN_REF (NODE) && ! TYPE_HAS_COMPLEX_ASSIGN_REF (NODE))
/* Nonzero for _TYPE node means that this type is a pointer to member
/* Nonzero for _TYPE node means that this type is a pointer to member
function type. */
function type. */
#define TYPE_PTRMEMFUNC_P(NODE) (TREE_CODE(NODE) == RECORD_TYPE && TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag)
#define TYPE_PTRMEMFUNC_P(NODE) (TREE_CODE(NODE) == RECORD_TYPE && TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag)
...
...
gcc/cp/decl.c
View file @
e8abc66f
...
@@ -10827,6 +10827,7 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
...
@@ -10827,6 +10827,7 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
||
(
DECL_THIS_INLINE
(
decl1
)
&&
!
flag_implement_inlines
));
||
(
DECL_THIS_INLINE
(
decl1
)
&&
!
flag_implement_inlines
));
else
else
DECL_EXTERNAL
(
decl1
)
=
0
;
DECL_EXTERNAL
(
decl1
)
=
0
;
DECL_NOT_REALLY_EXTERN
(
decl1
)
=
0
;
DECL_INTERFACE_KNOWN
(
decl1
)
=
1
;
DECL_INTERFACE_KNOWN
(
decl1
)
=
1
;
}
}
else
else
...
...
gcc/cp/decl2.c
View file @
e8abc66f
...
@@ -34,6 +34,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -34,6 +34,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "cp-tree.h"
#include "cp-tree.h"
#include "decl.h"
#include "decl.h"
#include "lex.h"
#include "lex.h"
#include "output.h"
extern
tree
grokdeclarator
();
extern
tree
grokdeclarator
();
extern
tree
get_file_function_name
();
extern
tree
get_file_function_name
();
...
@@ -1948,7 +1949,12 @@ void
...
@@ -1948,7 +1949,12 @@ void
cplus_decl_attributes
(
decl
,
attributes
,
prefix_attributes
)
cplus_decl_attributes
(
decl
,
attributes
,
prefix_attributes
)
tree
decl
,
attributes
,
prefix_attributes
;
tree
decl
,
attributes
,
prefix_attributes
;
{
{
if
(
decl
&&
decl
!=
void_type_node
)
if
(
decl
==
NULL_TREE
||
decl
==
void_type_node
)
return
;
if
(
TREE_CODE
(
decl
)
==
TEMPLATE_DECL
)
decl
=
DECL_TEMPLATE_RESULT
(
decl
);
decl_attributes
(
decl
,
attributes
,
prefix_attributes
);
decl_attributes
(
decl
,
attributes
,
prefix_attributes
);
}
}
...
@@ -2775,6 +2781,8 @@ import_export_inline (decl)
...
@@ -2775,6 +2781,8 @@ import_export_inline (decl)
}
}
else
else
TREE_PUBLIC
(
decl
)
=
0
;
TREE_PUBLIC
(
decl
)
=
0
;
DECL_INTERFACE_KNOWN
(
decl
)
=
1
;
}
}
extern
int
parse_time
,
varconst_time
;
extern
int
parse_time
,
varconst_time
;
...
@@ -3086,11 +3094,12 @@ finish_file ()
...
@@ -3086,11 +3094,12 @@ finish_file ()
inline'. */
inline'. */
{
{
int
reconsider
=
1
;
/* More may be referenced; check again */
int
reconsider
=
1
;
/* More may be referenced; check again */
saved_inlines
=
tree_cons
(
NULL_TREE
,
NULL_TREE
,
saved_inlines
);
while
(
reconsider
)
while
(
reconsider
)
{
{
tree
last
=
saved_inlines
;
tree
last
=
saved_inlines
=
tree_cons
(
NULL_TREE
,
NULL_TREE
,
saved_inlines
);
tree
last_head
=
last
;
tree
place
=
TREE_CHAIN
(
saved_inlines
);
tree
place
=
TREE_CHAIN
(
saved_inlines
);
reconsider
=
0
;
reconsider
=
0
;
...
@@ -3100,11 +3109,23 @@ finish_file ()
...
@@ -3100,11 +3109,23 @@ finish_file ()
{
{
tree
decl
=
TREE_VALUE
(
place
);
tree
decl
=
TREE_VALUE
(
place
);
/* Slice out the empty elements put in just above in the
previous reconsidering. */
if
(
decl
==
NULL_TREE
)
{
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
continue
;
}
if
(
DECL_ARTIFICIAL
(
decl
)
&&
!
DECL_INITIAL
(
decl
))
if
(
DECL_ARTIFICIAL
(
decl
)
&&
!
DECL_INITIAL
(
decl
))
{
{
if
(
TREE_USED
(
decl
)
if
(
TREE_USED
(
decl
)
||
(
TREE_PUBLIC
(
decl
)
&&
DECL_NOT_REALLY_EXTERN
(
decl
)))
||
(
TREE_PUBLIC
(
decl
)
&&
DECL_NOT_REALLY_EXTERN
(
decl
)))
{
synthesize_method
(
decl
);
synthesize_method
(
decl
);
if
(
TREE_ASM_WRITTEN
(
decl
))
reconsider
=
1
;
}
else
else
{
{
last
=
place
;
last
=
place
;
...
...
gcc/cp/expr.c
View file @
e8abc66f
...
@@ -142,7 +142,7 @@ cplus_expand_expr (exp, target, tmode, modifier)
...
@@ -142,7 +142,7 @@ cplus_expand_expr (exp, target, tmode, modifier)
preserve_temp_slots
(
DECL_RTL
(
slot
));
preserve_temp_slots
(
DECL_RTL
(
slot
));
call_exp
=
build
(
CALL_EXPR
,
type
,
func
,
args
,
0
);
call_exp
=
build
(
CALL_EXPR
,
type
,
func
,
args
,
0
);
TREE_SIDE_EFFECTS
(
call_exp
)
=
1
;
TREE_SIDE_EFFECTS
(
call_exp
)
=
1
;
return_target
=
expand_
expr
(
call_exp
,
call_target
,
mode
,
0
);
return_target
=
expand_
call
(
call_exp
,
call_target
,
ignore
);
free_temp_slots
();
free_temp_slots
();
if
(
call_target
==
0
)
if
(
call_target
==
0
)
{
{
...
@@ -174,7 +174,7 @@ cplus_expand_expr (exp, target, tmode, modifier)
...
@@ -174,7 +174,7 @@ cplus_expand_expr (exp, target, tmode, modifier)
if
(
call_target
!=
return_target
)
if
(
call_target
!=
return_target
)
{
{
my_friendly_assert
(
!
TYPE_NEEDS_CONSTRUCTING
(
type
),
317
);
my_friendly_assert
(
TYPE_HAS_TRIVIAL_INIT_REF
(
type
),
317
);
if
(
GET_MODE
(
return_target
)
==
BLKmode
)
if
(
GET_MODE
(
return_target
)
==
BLKmode
)
emit_block_move
(
call_target
,
return_target
,
expr_size
(
exp
),
emit_block_move
(
call_target
,
return_target
,
expr_size
(
exp
),
TYPE_ALIGN
(
type
)
/
BITS_PER_UNIT
);
TYPE_ALIGN
(
type
)
/
BITS_PER_UNIT
);
...
...
gcc/cp/gxxint.texi
View file @
e8abc66f
...
@@ -1145,16 +1145,21 @@ independent representation for exceptions.
...
@@ -1145,16 +1145,21 @@ independent representation for exceptions.
The
C
++
front
-
end
exceptions
are
mapping
into
the
unwind
-
protect
The
C
++
front
-
end
exceptions
are
mapping
into
the
unwind
-
protect
semantics
by
the
C
++
front
-
end
.
The
mapping
is
describe
below
.
semantics
by
the
C
++
front
-
end
.
The
mapping
is
describe
below
.
Objects
with
RTTI
support
should
use
the
RTTI
information
to
do
mapping
When
-
frtti
is
used
,
rtti
is
used
to
do
exception
object
type
checking
,
and
checking
.
Objects
without
RTTI
,
like
int
and
const
char
*
,
have
to
when
it
isn
'
t
used
,
the
encoded
name
for
the
type
of
the
object
being
use
another
means
of
matching
.
Currently
we
use
the
normal
mangling
used
in
thrown
is
used
instead
.
All
code
that
originates
exceptions
,
even
code
building
functions
names
.
Int
'
s
are
"i"
,
const
char
*
is
PCc
,
etc
...
that
throws
exceptions
as
a
side
effect
,
like
dynamic
casting
,
and
all
code
that
catches
exceptions
must
be
compiled
with
either
-
frtti
,
or
Unfortunately
,
the
standard
allows
standard
type
conversions
on
throw
-
fno
-
rtti
.
It
is
not
possible
to
mix
rtti
base
exception
handling
parameters
so
they
can
match
catch
handlers
.
This
means
we
need
a
objects
with
code
that
doesn
'
t
use
rtti
.
The
exceptions
to
this
,
are
mechanism
to
handle
type
conversion
at
run
time
,
ICK
.
I
read
this
part
code
that
doesn
'
t
catch
or
throw
exceptions
,
catch
(...),
and
code
that
again
,
and
it
appears
that
we
only
have
to
be
able
to
do
a
few
of
the
just
rethrows
an
exception
.
conversions
at
run
time
,
so
we
should
be
ok
.
Currently
we
use
the
normal
mangling
used
in
building
functions
names
(
int
'
s
are
"i"
,
const
char
*
is
PCc
)
to
build
the
non
-
rtti
base
type
descriptors
for
exception
handling
.
These
descriptors
are
just
plain
NULL
terminated
strings
,
and
internally
they
are
passed
around
as
char
*
.
In
C
++
,
all
cleanups
should
be
protected
by
exception
regions
.
The
In
C
++
,
all
cleanups
should
be
protected
by
exception
regions
.
The
region
starts
just
after
the
reason
why
the
cleanup
is
created
has
region
starts
just
after
the
reason
why
the
cleanup
is
created
has
...
@@ -1192,18 +1197,20 @@ throwing. The only bad part, is that the stack remains large.
...
@@ -1192,18 +1197,20 @@ throwing. The only bad part, is that the stack remains large.
The
below
points
out
some
flaws
in
g
++
'
s
exception
handling
,
as
it
now
The
below
points
out
some
flaws
in
g
++
'
s
exception
handling
,
as
it
now
stands
.
stands
.
Only
exact
type
matching
or
reference
matching
of
throw
types
works
.
Only
exact
type
matching
or
reference
matching
of
throw
types
works
when
Only
works
on
a
SPARC
machines
(
like
Suns
),
i386
machines
,
arm
machines
-
fno
-
rtti
is
used
.
Only
works
on
a
SPARC
(
like
Suns
),
i386
,
arm
and
and
rs6000
machines
.
Partial
support
is
also
in
for
alpha
,
hppa
,
m68k
rs6000
machines
.
Partial
support
is
also
in
for
alpha
,
hppa
,
m68k
and
and
mips
machines
,
but
a
stack
unwinder
called
__unwind_function
has
to
mips
machines
,
but
a
stack
unwinder
called
__unwind_function
has
to
be
be
written
,
and
added
to
libgcc2
for
them
.
All
completely
constructed
written
,
and
added
to
libgcc2
for
them
.
See
below
for
details
on
temps
and
local
variables
are
cleaned
up
in
all
unwinded
scopes
.
__unwind_function
.
All
completely
constructed
temps
and
local
variables
Completed
parts
of
partially
constructed
objects
are
not
cleaned
up
.
are
cleaned
up
in
all
unwinded
scopes
.
Completed
parts
of
partially
Don
'
t
expect
exception
handling
to
work
right
if
you
optimize
,
in
fact
constructed
objects
are
cleaned
up
with
the
exception
that
partially
the
compiler
will
probably
core
dump
.
If
two
EH
regions
are
the
exact
built
arrays
are
not
cleaned
up
as
required
.
Don
'
t
expect
exception
same
size
,
the
backend
cannot
tell
which
one
is
first
.
It
punts
by
handling
to
work
right
if
you
optimize
,
in
fact
the
compiler
will
picking
the
last
one
,
if
they
tie
.
This
is
usually
right
.
We
really
probably
core
dump
.
If
two
EH
regions
are
the
exact
same
size
,
the
should
stick
in
a
nop
,
if
they
are
the
same
size
.
backend
cannot
tell
which
one
is
first
.
It
punts
by
picking
the
last
one
,
if
they
tie
.
This
is
usually
right
.
We
really
should
stick
in
a
nop
,
if
they
are
the
same
size
.
When
we
invoke
the
copy
constructor
for
an
exception
object
because
it
When
we
invoke
the
copy
constructor
for
an
exception
object
because
it
is
passed
by
value
,
and
if
we
take
a
hit
(
exception
)
inside
the
copy
is
passed
by
value
,
and
if
we
take
a
hit
(
exception
)
inside
the
copy
...
@@ -1232,6 +1239,52 @@ When the backend returns a value, it can create new exception regions
...
@@ -1232,6 +1239,52 @@ When the backend returns a value, it can create new exception regions
that
need
protecting
.
The
new
region
should
rethrow
the
object
in
that
need
protecting
.
The
new
region
should
rethrow
the
object
in
context
of
the
last
associated
cleanup
that
ran
to
completion
.
context
of
the
last
associated
cleanup
that
ran
to
completion
.
The
__unwind_function
takes
a
pointer
to
the
throw
handler
,
and
is
expected
to
pop
the
stack
frame
that
was
built
to
call
it
,
as
well
as
the
frame
underneath
and
then
jump
to
the
throw
handler
.
It
must
not
change
the
three
registers
allocated
for
the
pointer
to
the
exception
object
,
the
pointer
to
the
type
descriptor
that
identifies
the
type
of
the
exception
object
,
and
the
pointer
to
the
code
that
threw
.
On
hppa
,
these
are
%
r5
,
%
r6
,
%
r7
.
On
m68k
these
are
a2
,
a3
,
a4
.
On
mips
they
are
s0
,
s1
,
s2
.
On
Alpha
these
are
$
9
,
$
10
,
$
11
.
It
takes
about
a
day
to
write
this
routine
,
if
someone
wants
to
volunteer
to
write
this
routine
for
any
architecture
,
exception
support
for
that
architecture
will
be
added
to
g
++
.
Please
send
in
those
code
donations
.
The
backend
must
be
extended
to
fully
support
exceptions
.
Right
now
there
are
a
few
hooks
into
the
alpha
exception
handling
backend
that
resides
in
the
C
++
frontend
from
that
backend
that
allows
exception
handling
to
work
in
g
++
.
An
exception
region
is
a
segment
of
generated
code
that
has
a
handler
associated
with
it
.
The
exception
regions
are
denoted
in
the
generated
code
as
address
ranges
denoted
by
a
starting
PC
value
and
an
ending
PC
value
of
the
region
.
Some
of
the
limitations
with
this
scheme
are
:
@itemize
@bullet
@item
The
backend
replicates
insns
for
such
things
as
loop
unrolling
and
function
inlining
.
Right
now
,
there
are
no
hooks
into
the
frontend
'
s
exception
handling
backend
to
handle
the
replication
of
insns
.
When
replication
happens
,
a
new
exception
region
descriptor
needs
to
be
generated
for
the
new
region
.
@item
The
backend
expects
to
be
able
to
rearrange
code
,
for
things
like
jump
optimization
.
Any
rearranging
of
the
code
needs
have
exception
region
descriptors
updated
appropriately
.
@item
The
backend
can
eliminate
dead
code
.
Any
associated
exception
region
descriptor
that
refers
to
fully
contained
code
that
has
been
eliminated
should
also
be
removed
,
although
not
doing
this
is
harmless
in
terms
of
semantics
.
#end itemize
The
above
is
not
meant
to
be
exhaustive
,
but
does
include
all
things
I
have
thought
of
so
far
.
I
am
sure
other
limitations
exist
.
@node
Free
Store
,
Concept
Index
,
Exception
Handling
,
Top
@node
Free
Store
,
Concept
Index
,
Exception
Handling
,
Top
@section
Free
Store
@section
Free
Store
...
...
gcc/cp/init.c
View file @
e8abc66f
...
@@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -26,6 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "rtl.h"
#include "rtl.h"
#include "cp-tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "flags.h"
#include "output.h"
#undef NULL
#undef NULL
#define NULL 0
#define NULL 0
...
@@ -1202,8 +1203,7 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
...
@@ -1202,8 +1203,7 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
}
}
if
(
init
&&
TREE_CHAIN
(
parms
)
==
NULL_TREE
if
(
init
&&
TREE_CHAIN
(
parms
)
==
NULL_TREE
&&
TYPE_HAS_CONSTRUCTOR
(
type
)
&&
TYPE_HAS_TRIVIAL_INIT_REF
(
type
)
&&
!
TYPE_NEEDS_CONSTRUCTING
(
type
)
&&
TYPE_MAIN_VARIANT
(
type
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
init
)))
&&
TYPE_MAIN_VARIANT
(
type
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
init
)))
{
{
rval
=
build
(
INIT_EXPR
,
type
,
exp
,
init
);
rval
=
build
(
INIT_EXPR
,
type
,
exp
,
init
);
...
...
gcc/cp/lex.c
View file @
e8abc66f
...
@@ -1801,6 +1801,8 @@ cons_up_default_function (type, full_name, kind)
...
@@ -1801,6 +1801,8 @@ cons_up_default_function (type, full_name, kind)
||
!
flag_implement_inlines
);
||
!
flag_implement_inlines
);
TREE_STATIC
(
fn
)
=
!
DECL_EXTERNAL
(
fn
);
TREE_STATIC
(
fn
)
=
!
DECL_EXTERNAL
(
fn
);
}
}
else
DECL_NOT_REALLY_EXTERN
(
fn
)
=
1
;
/* When on-the-fly synthesis works properly, remove the second and third
/* When on-the-fly synthesis works properly, remove the second and third
conditions here. */
conditions here. */
...
@@ -1849,354 +1851,6 @@ cons_up_default_function (type, full_name, kind)
...
@@ -1849,354 +1851,6 @@ cons_up_default_function (type, full_name, kind)
return
fn
;
return
fn
;
}
}
#if 0
/* Used by default_copy_constructor_body. For the anonymous union
in TYPE, return the member that is at least as large as the rest
of the members, so we can copy it. */
static tree
largest_union_member (type)
tree type;
{
tree f, type_size = TYPE_SIZE (type);
for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f))
if (simple_cst_equal (DECL_SIZE (f), type_size))
return f;
/* We should always find one. */
my_friendly_abort (323);
return NULL_TREE;
}
/* Construct the body of a default assignment operator.
Mostly copied directly from default_copy_constructor_body. */
static void
default_assign_ref_body (bufp, lenp, type, fields)
char **bufp;
int *lenp;
tree type, fields;
{
static struct obstack body;
static int inited = FALSE;
int n_bases = CLASSTYPE_N_BASECLASSES (type);
char *tbuf;
int tgot, tneed;
if (!inited)
{
obstack_init (&body);
inited = TRUE;
}
body.next_free = body.object_base;
obstack_1grow (&body, '{');
/* Small buffer for sprintf(). */
tgot = 100;
tbuf = (char *) alloca (tgot);
/* If we don't need a real op=, just do a bitwise copy. */
if (! TYPE_HAS_COMPLEX_ASSIGN_REF (type))
{
tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));return *this;}";
*lenp = strlen (tbuf);
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
strcpy (*bufp, tbuf);
return;
}
if (TREE_CODE (type) == UNION_TYPE)
{
if (fields)
{
tree main = fields;
char * s;
tree f;
for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f))
if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)),
TYPE_SIZE (TREE_TYPE (f))))
main = f;
s = IDENTIFIER_POINTER (DECL_NAME (main));
tneed = (2 * strlen (s)) + 28;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "{%s=_ctor_arg.%s;return *this;}", s, s);
}
else
tbuf = "{}";
*lenp = strlen (tbuf);
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
strcpy (*bufp, tbuf);
return;
}
/* Construct base classes...
FIXME: Does not deal with multiple inheritance and virtual bases
correctly. See g++.old-deja/g++.jason/opeq5.C for a testcase.
We need to do wacky things if everything between us and the virtual
base (by all paths) has a "complex" op=. */
if (n_bases)
{
tree bases = TYPE_BINFO_BASETYPES (type);
int i = 0;
for (i = 0; i < n_bases; i++)
{
tree binfo = TREE_VEC_ELT (bases, i);
tree btype, name;
char *s;
btype = BINFO_TYPE (binfo);
name = TYPE_NESTED_NAME (btype);
s = IDENTIFIER_POINTER (name);
tneed = (2 * strlen (s)) + 42;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "%s::operator=((%s%s ::%s&)_ctor_arg);", s,
TYPE_READONLY (type) ? "const " : "",
CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct",
s);
obstack_grow (&body, tbuf, strlen (tbuf));
}
}
/* Construct fields. */
if (fields)
{
tree f;
for (f = fields; f; f = TREE_CHAIN (f))
{
if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f))
{
char *s;
tree x;
tree t = TREE_TYPE (f);
if (DECL_NAME (f))
x = f;
else if (t != NULL_TREE
&& TREE_CODE (t) == UNION_TYPE
&& ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE
&& ANON_AGGRNAME_P (TYPE_NAME (t)))
|| (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))
&& TYPE_FIELDS (t) != NULL_TREE)
x = largest_union_member (t);
else
continue;
s = IDENTIFIER_POINTER (DECL_NAME (x));
tneed = (2 * strlen (s)) + 13;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "%s=_ctor_arg.%s;", s, s);
obstack_grow (&body, tbuf, strlen (tbuf));
}
}
}
obstack_grow (&body, "return *this;}", 15);
*lenp = obstack_object_size (&body) - 1;
*bufp = obstack_alloc (&inline_text_obstack, *lenp);
strcpy (*bufp, body.object_base);
}
/* Construct the body of a default copy constructor. */
static void
default_copy_constructor_body (bufp, lenp, type, fields)
char **bufp;
int *lenp;
tree type, fields;
{
static struct obstack prologue;
static int inited = FALSE;
int n_bases = CLASSTYPE_N_BASECLASSES (type);
char sep = ':';
char *tbuf;
int tgot, tneed;
/* Create a buffer to call base class constructors and construct members
(fields). */
if (!inited)
{
obstack_init (&prologue);
inited = TRUE;
}
prologue.next_free = prologue.object_base;
/* If we don't need a real copy ctor, just do a bitwise copy. */
if (! TYPE_HAS_COMPLEX_INIT_REF (type))
{
tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));}";
*lenp = strlen (tbuf);
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
strcpy (*bufp, tbuf);
return;
}
/* Small buffer for sprintf(). */
tgot = 100;
tbuf = (char *) alloca (tgot);
if (TREE_CODE (type) == UNION_TYPE)
{
if (fields)
{
tree main = fields;
char * s;
tree f;
for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f))
if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)),
TYPE_SIZE (TREE_TYPE (f))))
main = f;
s = IDENTIFIER_POINTER (DECL_NAME (main));
tneed = (2 * strlen (s)) + 16;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, ":%s(_ctor_arg.%s){}", s, s);
}
else
tbuf = "{}";
*lenp = strlen (tbuf);
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
strcpy (*bufp, tbuf);
return;
}
/* Construct base classes... */
if (n_bases)
{
/* Note that CLASSTYPE_VBASECLASSES isn't set yet... */
tree v = get_vbase_types (type);
tree bases = TYPE_BINFO_BASETYPES (type);
int i = 0;
for (;;)
{
tree binfo, btype, name;
char *s;
if (v)
{
binfo = v;
v = TREE_CHAIN (v);
}
else if (i < n_bases)
{
binfo = TREE_VEC_ELT (bases, i++);
if (TREE_VIA_VIRTUAL (binfo))
continue;
}
else
break;
btype = BINFO_TYPE (binfo);
name = TYPE_NESTED_NAME (btype);
s = IDENTIFIER_POINTER (name);
tneed = (2 * strlen (s)) + 39;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "%c%s((%s%s ::%s&)_ctor_arg)", sep, s,
TYPE_READONLY (type) ? "const " : "",
CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct",
s);
sep = ',';
obstack_grow (&prologue, tbuf, strlen (tbuf));
}
}
/* Construct fields. */
if (fields)
{
tree f;
for (f = fields; f; f = TREE_CHAIN (f))
{
if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f))
{
char *s;
tree x;
tree t = TREE_TYPE (f);
if (DECL_NAME (f))
x = f;
else if (t != NULL_TREE
&& TREE_CODE (t) == UNION_TYPE
&& ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE
&& ANON_AGGRNAME_P (TYPE_NAME (t)))
|| (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))
&& TYPE_FIELDS (t) != NULL_TREE)
x = largest_union_member (t);
else
continue;
s = IDENTIFIER_POINTER (DECL_NAME (x));
tneed = (2 * strlen (s)) + 30;
if (tgot < tneed)
{
tgot = tneed;
tbuf = (char *) alloca (tgot);
}
sprintf (tbuf, "%c%s(_ctor_arg.%s)", sep, s, s);
sep = ',';
obstack_grow (&prologue, tbuf, strlen (tbuf));
}
}
}
/* Concatenate constructor body to prologue. */
*lenp = obstack_object_size (&prologue) + 2;
*bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
obstack_1grow (&prologue, '\0');
strcpy (*bufp, prologue.object_base);
strcat (*bufp, "{}");
}
#endif
/* Heuristic to tell whether the user is missing a semicolon
/* Heuristic to tell whether the user is missing a semicolon
after a struct or enum declaration. Emit an error message
after a struct or enum declaration. Emit an error message
if we know the user has blown it. */
if we know the user has blown it. */
...
...
gcc/cp/method.c
View file @
e8abc66f
...
@@ -2052,7 +2052,7 @@ do_build_copy_constructor (fndecl)
...
@@ -2052,7 +2052,7 @@ do_build_copy_constructor (fndecl)
parm
=
TREE_CHAIN
(
parm
);
parm
=
TREE_CHAIN
(
parm
);
parm
=
convert_from_reference
(
parm
);
parm
=
convert_from_reference
(
parm
);
if
(
!
TYPE_HAS_COMPLEX
_INIT_REF
(
current_class_type
))
if
(
TYPE_HAS_TRIVIAL
_INIT_REF
(
current_class_type
))
{
{
t
=
build
(
INIT_EXPR
,
void_type_node
,
C_C_D
,
parm
);
t
=
build
(
INIT_EXPR
,
void_type_node
,
C_C_D
,
parm
);
TREE_SIDE_EFFECTS
(
t
)
=
1
;
TREE_SIDE_EFFECTS
(
t
)
=
1
;
...
@@ -2140,7 +2140,7 @@ do_build_assign_ref (fndecl)
...
@@ -2140,7 +2140,7 @@ do_build_assign_ref (fndecl)
parm
=
convert_from_reference
(
parm
);
parm
=
convert_from_reference
(
parm
);
if
(
!
TYPE_HAS_COMPLEX
_ASSIGN_REF
(
current_class_type
))
if
(
TYPE_HAS_TRIVIAL
_ASSIGN_REF
(
current_class_type
))
{
{
tree
t
=
build
(
MODIFY_EXPR
,
void_type_node
,
C_C_D
,
parm
);
tree
t
=
build
(
MODIFY_EXPR
,
void_type_node
,
C_C_D
,
parm
);
TREE_SIDE_EFFECTS
(
t
)
=
1
;
TREE_SIDE_EFFECTS
(
t
)
=
1
;
...
...
gcc/cp/parse.y
View file @
e8abc66f
...
@@ -53,6 +53,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -53,6 +53,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "flags.h"
#include "flags.h"
#include "lex.h"
#include "lex.h"
#include "cp-tree.h"
#include "cp-tree.h"
#include "output.h"
/* Since parsers are distinct for each language, put the language string
/* Since parsers are distinct for each language, put the language string
definition here. (fnf) */
definition here. (fnf) */
...
...
gcc/cp/pt.c
View file @
e8abc66f
...
@@ -38,6 +38,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -38,6 +38,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "decl.h"
#include "decl.h"
#include "parse.h"
#include "parse.h"
#include "lex.h"
#include "lex.h"
#include "output.h"
extern
struct
obstack
permanent_obstack
;
extern
struct
obstack
permanent_obstack
;
extern
tree
grokdeclarator
();
extern
tree
grokdeclarator
();
...
@@ -2510,11 +2511,17 @@ do_function_instantiation (declspecs, declarator, storage)
...
@@ -2510,11 +2511,17 @@ do_function_instantiation (declspecs, declarator, storage)
tree
declspecs
,
declarator
,
storage
;
tree
declspecs
,
declarator
,
storage
;
{
{
tree
decl
=
grokdeclarator
(
declarator
,
declspecs
,
NORMAL
,
0
,
0
);
tree
decl
=
grokdeclarator
(
declarator
,
declspecs
,
NORMAL
,
0
,
0
);
tree
name
=
DECL_NAME
(
decl
)
;
tree
name
;
tree
fn
=
IDENTIFIER_GLOBAL_VALUE
(
name
)
;
tree
fn
;
tree
result
=
NULL_TREE
;
tree
result
=
NULL_TREE
;
int
extern_p
=
0
;
int
extern_p
=
0
;
if
(
fn
)
/* If we've already seen this template instance, use it. */
if
(
name
=
DECL_ASSEMBLER_NAME
(
decl
),
fn
=
IDENTIFIER_GLOBAL_VALUE
(
name
),
fn
&&
DECL_TEMPLATE_INSTANTIATION
(
fn
))
result
=
fn
;
else
if
(
name
=
DECL_NAME
(
decl
),
fn
=
IDENTIFIER_GLOBAL_VALUE
(
name
),
fn
)
{
{
for
(
fn
=
get_first_fn
(
fn
);
fn
;
fn
=
DECL_CHAIN
(
fn
))
for
(
fn
=
get_first_fn
(
fn
);
fn
;
fn
=
DECL_CHAIN
(
fn
))
if
(
decls_match
(
fn
,
decl
)
if
(
decls_match
(
fn
,
decl
)
...
@@ -2578,12 +2585,14 @@ mark_class_instantiated (t, extern_p)
...
@@ -2578,12 +2585,14 @@ mark_class_instantiated (t, extern_p)
rest_of_type_compilation
(
t
,
1
);
rest_of_type_compilation
(
t
,
1
);
}
}
}
}
void
void
do_type_instantiation
(
name
,
storage
)
do_type_instantiation
(
name
,
storage
)
tree
name
,
storage
;
tree
name
,
storage
;
{
{
tree
t
=
TREE_TYPE
(
name
);
tree
t
=
TREE_TYPE
(
name
);
int
extern_p
;
int
extern_p
=
0
;
int
nomem_p
=
0
;
/* With -fexternal-templates, explicit instantiations are treated the same
/* With -fexternal-templates, explicit instantiations are treated the same
as implicit ones. */
as implicit ones. */
...
@@ -2598,7 +2607,9 @@ do_type_instantiation (name, storage)
...
@@ -2598,7 +2607,9 @@ do_type_instantiation (name, storage)
}
}
if
(
storage
==
NULL_TREE
)
if
(
storage
==
NULL_TREE
)
extern_p
=
0
;
/* OK */
;
else
if
(
storage
==
ridpointers
[(
int
)
RID_INLINE
])
nomem_p
=
1
;
else
if
(
storage
==
ridpointers
[(
int
)
RID_EXTERN
])
else
if
(
storage
==
ridpointers
[(
int
)
RID_EXTERN
])
extern_p
=
1
;
extern_p
=
1
;
else
else
...
@@ -2619,6 +2630,9 @@ do_type_instantiation (name, storage)
...
@@ -2619,6 +2630,9 @@ do_type_instantiation (name, storage)
repo_template_instantiated
(
t
,
extern_p
);
repo_template_instantiated
(
t
,
extern_p
);
}
}
if
(
nomem_p
)
return
;
{
{
tree
tmp
;
tree
tmp
;
/* Classes nested in template classes currently don't have an
/* Classes nested in template classes currently don't have an
...
...
gcc/cp/repo.c
View file @
e8abc66f
...
@@ -33,14 +33,17 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -33,14 +33,17 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
extern
char
*
rindex
();
extern
char
*
rindex
();
extern
char
*
getenv
();
extern
char
*
getenv
();
extern
char
*
getpwd
();
static
tree
pending_repo
;
static
tree
pending_repo
;
static
tree
original_repo
;
static
tree
original_repo
;
static
char
repo_name
[
1024
]
;
static
char
*
repo_name
;
static
FILE
*
repo_file
;
static
FILE
*
repo_file
;
extern
int
flag_use_repository
;
extern
int
flag_use_repository
;
extern
int
errorcount
,
sorrycount
;
extern
int
errorcount
,
sorrycount
;
extern
struct
obstack
temporary_obstack
;
extern
struct
obstack
permanent_obstack
;
#define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE))
#define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE))
#define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE))
#define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE))
...
@@ -187,7 +190,6 @@ save_string (s, len)
...
@@ -187,7 +190,6 @@ save_string (s, len)
char
*
s
;
char
*
s
;
int
len
;
int
len
;
{
{
extern
struct
obstack
temporary_obstack
;
return
obstack_copy0
(
&
temporary_obstack
,
s
,
len
);
return
obstack_copy0
(
&
temporary_obstack
,
s
,
len
);
}
}
...
@@ -244,36 +246,42 @@ open_repo_file (filename)
...
@@ -244,36 +246,42 @@ open_repo_file (filename)
char
*
filename
;
char
*
filename
;
{
{
register
char
*
p
,
*
q
;
register
char
*
p
,
*
q
;
char
*
file
=
get_base_filename
(
filename
);
char
*
s
=
get_base_filename
(
filename
);
char
*
s
;
if
(
file
==
NULL
)
if
(
s
==
NULL
)
return
;
return
;
s
=
rindex
(
file
,
'/'
);
p
=
rindex
(
s
,
'/'
);
if
(
s
==
NULL
)
if
(
!
p
)
s
=
file
;
p
=
s
;
else
p
=
rindex
(
p
,
'.'
);
++
s
;
if
(
!
p
)
p
=
s
+
strlen
(
s
);
for
(
p
=
repo_name
,
q
=
file
;
q
<
s
;
)
obstack_grow
(
&
permanent_obstack
,
s
,
p
-
s
);
*
p
++
=
*
q
++
;
repo_name
=
obstack_copy0
(
&
permanent_obstack
,
".rpo"
,
4
);
/* *p++ = '.'; */
if
((
s
=
rindex
(
q
,
'.'
))
==
NULL
)
strcpy
(
p
,
q
);
else
for
(;
q
<
s
;)
*
p
++
=
*
q
++
;
strcat
(
p
,
".rpo"
);
repo_file
=
fopen
(
repo_name
,
"r"
);
repo_file
=
fopen
(
repo_name
,
"r"
);
}
}
static
char
*
afgets
(
stream
)
FILE
*
stream
;
{
int
c
;
while
((
c
=
getc
(
stream
))
!=
EOF
&&
c
!=
'\n'
)
obstack_1grow
(
&
temporary_obstack
,
c
);
if
(
obstack_object_size
(
&
temporary_obstack
)
==
0
)
return
NULL
;
obstack_1grow
(
&
temporary_obstack
,
'\0'
);
return
obstack_finish
(
&
temporary_obstack
);
}
void
void
init_repo
(
filename
)
init_repo
(
filename
)
char
*
filename
;
char
*
filename
;
{
{
char
buf
[
1024
]
;
char
*
buf
;
if
(
!
flag_use_repository
)
if
(
!
flag_use_repository
)
return
;
return
;
...
@@ -283,23 +291,19 @@ init_repo (filename)
...
@@ -283,23 +291,19 @@ init_repo (filename)
if
(
repo_file
==
0
)
if
(
repo_file
==
0
)
return
;
return
;
while
(
fgets
(
buf
,
1024
,
repo_file
))
while
(
buf
=
afgets
(
repo_file
))
{
{
switch
(
buf
[
0
])
switch
(
buf
[
0
])
{
{
case
'A'
:
case
'A'
:
case
'
G
'
:
case
'
D
'
:
case
'M'
:
case
'M'
:
break
;
break
;
case
'C'
:
case
'C'
:
case
'O'
:
case
'O'
:
{
{
char
*
q
;
tree
id
=
get_identifier
(
buf
+
2
);
tree
id
,
orig
;
tree
orig
;
for
(
q
=
&
buf
[
2
];
*
q
&&
*
q
!=
' '
&&
*
q
!=
'\n'
;
++
q
)
;
q
=
save_string
(
&
buf
[
2
],
q
-
&
buf
[
2
]);
id
=
get_identifier
(
q
);
if
(
buf
[
0
]
==
'C'
)
if
(
buf
[
0
]
==
'C'
)
{
{
...
@@ -315,6 +319,7 @@ init_repo (filename)
...
@@ -315,6 +319,7 @@ init_repo (filename)
default
:
default
:
error
(
"mysterious repository information in %s"
,
repo_name
);
error
(
"mysterious repository information in %s"
,
repo_name
);
}
}
obstack_free
(
&
temporary_obstack
,
buf
);
}
}
}
}
...
@@ -382,9 +387,8 @@ finish_repo ()
...
@@ -382,9 +387,8 @@ finish_repo ()
fprintf
(
repo_file
,
"M %s
\n
"
,
main_input_filename
);
fprintf
(
repo_file
,
"M %s
\n
"
,
main_input_filename
);
p
=
getenv
(
"COLLECT_GCC"
);
p
=
getpwd
();
if
(
p
!=
0
)
fprintf
(
repo_file
,
"D %s
\n
"
,
p
);
fprintf
(
repo_file
,
"G %s
\n
"
,
p
);
p
=
getenv
(
"COLLECT_GCC_OPTIONS"
);
p
=
getenv
(
"COLLECT_GCC_OPTIONS"
);
if
(
p
!=
0
)
if
(
p
!=
0
)
...
@@ -395,9 +399,7 @@ finish_repo ()
...
@@ -395,9 +399,7 @@ finish_repo ()
tree
val
=
TREE_VALUE
(
t
);
tree
val
=
TREE_VALUE
(
t
);
char
type
=
IDENTIFIER_REPO_CHOSEN
(
val
)
?
'C'
:
'O'
;
char
type
=
IDENTIFIER_REPO_CHOSEN
(
val
)
?
'C'
:
'O'
;
fprintf
(
repo_file
,
"%c %s "
,
type
,
IDENTIFIER_POINTER
(
val
));
fprintf
(
repo_file
,
"%c %s
\n
"
,
type
,
IDENTIFIER_POINTER
(
val
));
ASM_OUTPUT_LABELREF
(
repo_file
,
IDENTIFIER_POINTER
(
val
));
putc
(
'\n'
,
repo_file
);
}
}
out
:
out
:
...
...
gcc/cp/search.c
View file @
e8abc66f
...
@@ -28,12 +28,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -28,12 +28,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "obstack.h"
#include "obstack.h"
#include "flags.h"
#include "flags.h"
#include "rtl.h"
#include "rtl.h"
#include "output.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
#define obstack_chunk_free free
void
init_search
();
void
init_search
();
extern
struct
obstack
*
current_obstack
;
extern
struct
obstack
*
current_obstack
;
extern
tree
abort_fndecl
;
#include "stack.h"
#include "stack.h"
...
@@ -2626,6 +2628,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, t, vbase_offsets)
...
@@ -2626,6 +2628,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, t, vbase_offsets)
current_fndecl
=
FNADDR_FROM_VTABLE_ENTRY
(
current_fndecl
);
current_fndecl
=
FNADDR_FROM_VTABLE_ENTRY
(
current_fndecl
);
current_fndecl
=
TREE_OPERAND
(
current_fndecl
,
0
);
current_fndecl
=
TREE_OPERAND
(
current_fndecl
,
0
);
if
(
current_fndecl
if
(
current_fndecl
&&
current_fndecl
!=
abort_fndecl
&&
(
vc
=
virtual_context
(
current_fndecl
,
t
,
vbase
))
!=
vbase
)
&&
(
vc
=
virtual_context
(
current_fndecl
,
t
,
vbase
))
!=
vbase
)
{
{
/* This may in fact need a runtime fixup. */
/* This may in fact need a runtime fixup. */
...
...
gcc/cp/tree.c
View file @
e8abc66f
...
@@ -153,7 +153,7 @@ lvalue_p (ref)
...
@@ -153,7 +153,7 @@ lvalue_p (ref)
return
1
;
return
1
;
case
CALL_EXPR
:
case
CALL_EXPR
:
if
(
TREE_ADDRESSABL
E
(
TREE_TYPE
(
ref
)))
if
(
IS_AGGR_TYP
E
(
TREE_TYPE
(
ref
)))
return
1
;
return
1
;
break
;
break
;
...
@@ -217,8 +217,12 @@ build_cplus_new (type, init, with_cleanup_p)
...
@@ -217,8 +217,12 @@ build_cplus_new (type, init, with_cleanup_p)
tree
init
;
tree
init
;
int
with_cleanup_p
;
int
with_cleanup_p
;
{
{
tree
slot
=
build
(
VAR_DECL
,
type
);
tree
slot
;
tree
rval
=
build
(
NEW_EXPR
,
type
,
tree
rval
;
slot
=
build
(
VAR_DECL
,
type
);
layout_decl
(
slot
,
0
);
rval
=
build
(
NEW_EXPR
,
type
,
TREE_OPERAND
(
init
,
0
),
TREE_OPERAND
(
init
,
1
),
slot
);
TREE_OPERAND
(
init
,
0
),
TREE_OPERAND
(
init
,
1
),
slot
);
TREE_SIDE_EFFECTS
(
rval
)
=
1
;
TREE_SIDE_EFFECTS
(
rval
)
=
1
;
TREE_ADDRESSABLE
(
rval
)
=
1
;
TREE_ADDRESSABLE
(
rval
)
=
1
;
...
...
gcc/cp/typeck.c
View file @
e8abc66f
...
@@ -37,6 +37,7 @@ extern void warning ();
...
@@ -37,6 +37,7 @@ extern void warning ();
#include "rtl.h"
#include "rtl.h"
#include "cp-tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "flags.h"
#include "output.h"
int
mark_addressable
();
int
mark_addressable
();
static
tree
convert_for_assignment
();
static
tree
convert_for_assignment
();
...
@@ -2665,8 +2666,7 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
...
@@ -2665,8 +2666,7 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
/* Convert `float' to `double'. */
/* Convert `float' to `double'. */
result
=
tree_cons
(
NULL_TREE
,
convert
(
double_type_node
,
val
),
result
);
result
=
tree_cons
(
NULL_TREE
,
convert
(
double_type_node
,
val
),
result
);
else
if
(
TYPE_LANG_SPECIFIC
(
TREE_TYPE
(
val
))
else
if
(
TYPE_LANG_SPECIFIC
(
TREE_TYPE
(
val
))
&&
(
!
TYPE_HAS_INIT_REF
(
TREE_TYPE
(
val
))
&&
!
TYPE_HAS_TRIVIAL_INIT_REF
(
TREE_TYPE
(
val
)))
||
TYPE_HAS_COMPLEX_INIT_REF
(
TREE_TYPE
(
val
))))
{
{
cp_warning
(
"cannot pass objects of type `%T' through `...'"
,
cp_warning
(
"cannot pass objects of type `%T' through `...'"
,
TREE_TYPE
(
val
));
TREE_TYPE
(
val
));
...
@@ -5454,6 +5454,26 @@ init_noncopied_parts (lhs, list)
...
@@ -5454,6 +5454,26 @@ init_noncopied_parts (lhs, list)
return
parts
;
return
parts
;
}
}
tree
expand_target_expr
(
t
)
tree
t
;
{
tree
xval
=
make_node
(
RTL_EXPR
);
rtx
rtxval
;
do_pending_stack_adjust
();
start_sequence_for_rtl_expr
(
xval
);
emit_note
(
0
,
-
1
);
rtxval
=
expand_expr
(
t
,
NULL
,
VOIDmode
,
0
);
do_pending_stack_adjust
();
TREE_SIDE_EFFECTS
(
xval
)
=
1
;
RTL_EXPR_SEQUENCE
(
xval
)
=
get_insns
();
end_sequence
();
RTL_EXPR_RTL
(
xval
)
=
rtxval
;
TREE_TYPE
(
xval
)
=
TREE_TYPE
(
t
);
return
xval
;
}
/* Build an assignment expression of lvalue LHS from value RHS.
/* Build an assignment expression of lvalue LHS from value RHS.
MODIFYCODE is the code for a binary operator that we use
MODIFYCODE is the code for a binary operator that we use
to combine the old value of LHS with RHS to get the new value.
to combine the old value of LHS with RHS to get the new value.
...
@@ -5586,7 +5606,7 @@ build_modify_expr (lhs, modifycode, rhs)
...
@@ -5586,7 +5606,7 @@ build_modify_expr (lhs, modifycode, rhs)
/* Do the default thing */
;
/* Do the default thing */
;
else
if
(
!
TYPE_HAS_CONSTRUCTOR
(
lhstype
))
else
if
(
!
TYPE_HAS_CONSTRUCTOR
(
lhstype
))
cp_error
(
"`%T' has no constructors"
,
lhstype
);
cp_error
(
"`%T' has no constructors"
,
lhstype
);
else
if
(
!
TYPE_NEEDS_CONSTRUCTING
(
lhstype
)
else
if
(
TYPE_HAS_TRIVIAL_INIT_REF
(
lhstype
)
&&
TYPE_MAIN_VARIANT
(
lhstype
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
newrhs
)))
&&
TYPE_MAIN_VARIANT
(
lhstype
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
newrhs
)))
/* Do the default thing */
;
/* Do the default thing */
;
else
else
...
@@ -5607,8 +5627,7 @@ build_modify_expr (lhs, modifycode, rhs)
...
@@ -5607,8 +5627,7 @@ build_modify_expr (lhs, modifycode, rhs)
/* Do the default thing */
;
/* Do the default thing */
;
else
if
(
!
TYPE_HAS_ASSIGNMENT
(
lhstype
))
else
if
(
!
TYPE_HAS_ASSIGNMENT
(
lhstype
))
cp_error
(
"`%T' does not define operator="
,
lhstype
);
cp_error
(
"`%T' does not define operator="
,
lhstype
);
else
if
(
!
TYPE_HAS_REAL_ASSIGNMENT
(
lhstype
)
else
if
(
TYPE_HAS_TRIVIAL_ASSIGN_REF
(
lhstype
)
&&
!
TYPE_HAS_COMPLEX_ASSIGN_REF
(
lhstype
)
&&
TYPE_MAIN_VARIANT
(
lhstype
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
newrhs
)))
&&
TYPE_MAIN_VARIANT
(
lhstype
)
==
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
newrhs
)))
/* Do the default thing */
;
/* Do the default thing */
;
else
else
...
@@ -6002,28 +6021,12 @@ build_modify_expr (lhs, modifycode, rhs)
...
@@ -6002,28 +6021,12 @@ build_modify_expr (lhs, modifycode, rhs)
&&
TYPE_NEEDS_CONSTRUCTING
(
lhstype
))
&&
TYPE_NEEDS_CONSTRUCTING
(
lhstype
))
newrhs
=
build_cplus_new
(
lhstype
,
newrhs
,
0
);
newrhs
=
build_cplus_new
(
lhstype
,
newrhs
,
0
);
if
(
TREE_CODE
(
newrhs
)
==
TARGET_EXPR
)
{
/* Can't initialize directly from a TARGET_EXPR, since that would
/* Can't initialize directly from a TARGET_EXPR, since that would
cause the lhs to be constructed twice. So we force the
cause the lhs to be constructed twice. So we force the
TARGET_EXPR to be expanded. expand_expr should really do this
TARGET_EXPR to be expanded. expand_expr should really do this
by itself. */
by itself. */
if
(
TREE_CODE
(
newrhs
)
==
TARGET_EXPR
)
tree
xval
=
make_node
(
RTL_EXPR
);
newrhs
=
expand_target_expr
(
newrhs
);
rtx
rtxval
;
do_pending_stack_adjust
();
start_sequence_for_rtl_expr
(
xval
);
emit_note
(
0
,
-
1
);
rtxval
=
expand_expr
(
newrhs
,
NULL
,
VOIDmode
,
0
);
do_pending_stack_adjust
();
TREE_SIDE_EFFECTS
(
xval
)
=
1
;
RTL_EXPR_SEQUENCE
(
xval
)
=
get_insns
();
end_sequence
();
RTL_EXPR_RTL
(
xval
)
=
rtxval
;
TREE_TYPE
(
xval
)
=
lhstype
;
newrhs
=
xval
;
}
}
}
if
(
TREE_CODE
(
newrhs
)
==
ERROR_MARK
)
if
(
TREE_CODE
(
newrhs
)
==
ERROR_MARK
)
...
@@ -6964,6 +6967,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
...
@@ -6964,6 +6967,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
rhs
=
build_cplus_new
(
type
,
TREE_OPERAND
(
rhs
,
0
),
0
);
rhs
=
build_cplus_new
(
type
,
TREE_OPERAND
(
rhs
,
0
),
0
);
return
rhs
;
return
rhs
;
}
}
else
if
(
TYPE_HAS_TRIVIAL_INIT_REF
(
type
))
return
rhs
;
}
}
if
(
TYPE_MAIN_VARIANT
(
type
)
==
TYPE_MAIN_VARIANT
(
rhstype
)
if
(
TYPE_MAIN_VARIANT
(
type
)
==
TYPE_MAIN_VARIANT
(
rhstype
)
||
(
IS_AGGR_TYPE
(
rhstype
)
&&
UNIQUELY_DERIVED_FROM_P
(
type
,
rhstype
)))
||
(
IS_AGGR_TYPE
(
rhstype
)
&&
UNIQUELY_DERIVED_FROM_P
(
type
,
rhstype
)))
...
@@ -7227,6 +7232,13 @@ c_expand_return (retval)
...
@@ -7227,6 +7232,13 @@ c_expand_return (retval)
(3) If an X(X&) constructor is defined, the return
(3) If an X(X&) constructor is defined, the return
value must be returned via that. */
value must be returned via that. */
/* If we're returning in a register, we can't initialize the
return value from a TARGET_EXPR. */
if
(
TREE_CODE
(
retval
)
==
TARGET_EXPR
&&
TYPE_MAIN_VARIANT
(
TREE_TYPE
(
retval
))
==
TYPE_MAIN_VARIANT
(
valtype
)
&&
!
current_function_returns_struct
)
retval
=
expand_target_expr
(
retval
);
if
(
retval
==
result
if
(
retval
==
result
/* Watch out for constructors, which "return" aggregates
/* Watch out for constructors, which "return" aggregates
via initialization, but which otherwise "return" a pointer. */
via initialization, but which otherwise "return" a pointer. */
...
@@ -7243,12 +7255,8 @@ c_expand_return (retval)
...
@@ -7243,12 +7255,8 @@ c_expand_return (retval)
use_temp
=
obey_regdecls
;
use_temp
=
obey_regdecls
;
}
}
}
}
else
if
(
IS_AGGR_TYPE
(
valtype
)
&&
TYPE_NEEDS_CONSTRUCTING
(
valtype
)
)
else
if
(
IS_AGGR_TYPE
(
valtype
)
&&
current_function_returns_struct
)
{
{
/* Throw away the cleanup that `build_functional_cast' gave us. */
if
(
TREE_CODE
(
retval
)
==
WITH_CLEANUP_EXPR
&&
TREE_CODE
(
TREE_OPERAND
(
retval
,
0
))
==
TARGET_EXPR
)
retval
=
TREE_OPERAND
(
retval
,
0
);
expand_aggr_init
(
result
,
retval
,
0
,
LOOKUP_ONLYCONVERTING
);
expand_aggr_init
(
result
,
retval
,
0
,
LOOKUP_ONLYCONVERTING
);
expand_cleanups_to
(
NULL_TREE
);
expand_cleanups_to
(
NULL_TREE
);
DECL_INITIAL
(
result
)
=
NULL_TREE
;
DECL_INITIAL
(
result
)
=
NULL_TREE
;
...
...
gcc/cp/typeck2.c
View file @
e8abc66f
...
@@ -540,11 +540,12 @@ store_init_value (decl, init)
...
@@ -540,11 +540,12 @@ store_init_value (decl, init)
/* Take care of C++ business up here. */
/* Take care of C++ business up here. */
type
=
TYPE_MAIN_VARIANT
(
type
);
type
=
TYPE_MAIN_VARIANT
(
type
);
/* implicitly tests if IS_AGGR_TYPE. */
if
(
IS_AGGR_TYPE
(
type
))
if
(
TYPE_NEEDS_CONSTRUCTING
(
type
)
&&
TREE_CODE
(
init
)
!=
CONSTRUCTOR
)
my_friendly_abort
(
109
);
else
if
(
IS_AGGR_TYPE
(
type
))
{
{
if
(
!
TYPE_HAS_TRIVIAL_INIT_REF
(
type
)
&&
TREE_CODE
(
init
)
!=
CONSTRUCTOR
)
my_friendly_abort
(
109
);
/* Although we are not allowed to declare variables of signature
/* Although we are not allowed to declare variables of signature
type, we complain about a possible constructor call in such a
type, we complain about a possible constructor call in such a
declaration as well. */
declaration as well. */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment