mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 03:46:53 -05:00
decl.c (start_decl_1): Call cp_apply_type_quals_to_decl after completing the type.
* decl.c (start_decl_1): Call cp_apply_type_quals_to_decl after completing the type. * g++.dg/opt/const5.C: New test. From-SVN: r129388
This commit is contained in:
committed by
Mark Mitchell
parent
08fee57014
commit
fb9bdffedb
@@ -1,3 +1,8 @@
|
||||
2007-10-16 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* decl.c (start_decl_1): Call cp_apply_type_quals_to_decl after
|
||||
completing the type.
|
||||
|
||||
2007-10-13 Simon Martin <simartin@users.sourceforge.net>
|
||||
|
||||
PR c++/26698
|
||||
|
||||
@@ -4025,10 +4025,19 @@ start_decl (const cp_declarator *declarator,
|
||||
return tem;
|
||||
}
|
||||
|
||||
/* Process the declaration of a variable DECL. INITIALIZED is true
|
||||
iff DECL is explicitly initialized. (INITIALIZED is false if the
|
||||
variable is initialized via an implicitly-called constructor.)
|
||||
This function must be called for ordinary variables (including, for
|
||||
example, implicit instantiations of templates), but must not be
|
||||
called for template declarations. */
|
||||
|
||||
void
|
||||
start_decl_1 (tree decl, bool initialized)
|
||||
{
|
||||
tree type;
|
||||
bool complete_p;
|
||||
bool aggregate_definition_p;
|
||||
|
||||
gcc_assert (!processing_template_decl);
|
||||
|
||||
@@ -4036,21 +4045,37 @@ start_decl_1 (tree decl, bool initialized)
|
||||
return;
|
||||
|
||||
gcc_assert (TREE_CODE (decl) == VAR_DECL);
|
||||
|
||||
type = TREE_TYPE (decl);
|
||||
complete_p = COMPLETE_TYPE_P (type);
|
||||
aggregate_definition_p = IS_AGGR_TYPE (type) && !DECL_EXTERNAL (decl);
|
||||
|
||||
/* If an explicit initializer is present, or if this is a definition
|
||||
of an aggregate, then we need a complete type at this point.
|
||||
(Scalars are always complete types, so there is nothing to
|
||||
check.) This code just sets COMPLETE_P; errors (if necessary)
|
||||
are issued below. */
|
||||
if ((initialized || aggregate_definition_p)
|
||||
&& !complete_p
|
||||
&& COMPLETE_TYPE_P (complete_type (type)))
|
||||
{
|
||||
complete_p = true;
|
||||
/* We will not yet have set TREE_READONLY on DECL if the type
|
||||
was "const", but incomplete, before this point. But, now, we
|
||||
have a complete type, so we can try again. */
|
||||
cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
|
||||
}
|
||||
|
||||
if (initialized)
|
||||
/* Is it valid for this decl to have an initializer at all?
|
||||
If not, set INITIALIZED to zero, which will indirectly
|
||||
tell `cp_finish_decl' to ignore the initializer once it is parsed. */
|
||||
/* Is it valid for this decl to have an initializer at all? */
|
||||
{
|
||||
/* Don't allow initializations for incomplete types except for
|
||||
arrays which might be completed by the initialization. */
|
||||
if (COMPLETE_TYPE_P (complete_type (type)))
|
||||
if (complete_p)
|
||||
; /* A complete type is ok. */
|
||||
else if (TREE_CODE (type) != ARRAY_TYPE)
|
||||
{
|
||||
error ("variable %q#D has initializer but incomplete type", decl);
|
||||
initialized = 0;
|
||||
type = TREE_TYPE (decl) = error_mark_node;
|
||||
}
|
||||
else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
|
||||
@@ -4058,30 +4083,15 @@ start_decl_1 (tree decl, bool initialized)
|
||||
if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
|
||||
error ("elements of array %q#D have incomplete type", decl);
|
||||
/* else we already gave an error in start_decl. */
|
||||
initialized = 0;
|
||||
}
|
||||
}
|
||||
else if (IS_AGGR_TYPE (type)
|
||||
&& ! DECL_EXTERNAL (decl))
|
||||
else if (aggregate_definition_p && !complete_p)
|
||||
{
|
||||
if (!COMPLETE_TYPE_P (complete_type (type)))
|
||||
{
|
||||
error ("aggregate %q#D has incomplete type and cannot be defined",
|
||||
decl);
|
||||
/* Change the type so that assemble_variable will give
|
||||
DECL an rtl we can live with: (mem (const_int 0)). */
|
||||
type = TREE_TYPE (decl) = error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If any base type in the hierarchy of TYPE needs a constructor,
|
||||
then we set initialized to 1. This way any nodes which are
|
||||
created for the purposes of initializing this aggregate
|
||||
will live as long as it does. This is necessary for global
|
||||
aggregates which do not have their initializers processed until
|
||||
the end of the file. */
|
||||
initialized = TYPE_NEEDS_CONSTRUCTING (type);
|
||||
}
|
||||
error ("aggregate %q#D has incomplete type and cannot be defined",
|
||||
decl);
|
||||
/* Change the type so that assemble_variable will give
|
||||
DECL an rtl we can live with: (mem (const_int 0)). */
|
||||
type = TREE_TYPE (decl) = error_mark_node;
|
||||
}
|
||||
|
||||
/* Create a new scope to hold this declaration if necessary.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
2007-10-16 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* g++.dg/opt/const5.C: New test.
|
||||
|
||||
2007-10-15 Thomas Koenig <tkoenig@gcc.gnu.org>
|
||||
|
||||
PR fortran/33354
|
||||
|
||||
13
gcc/testsuite/g++.dg/opt/const5.C
Normal file
13
gcc/testsuite/g++.dg/opt/const5.C
Normal file
@@ -0,0 +1,13 @@
|
||||
// We don't have a good way of determining how ".rodata" is spelled on
|
||||
// all targets, so we limit this test to a few common targets where we
|
||||
// do know the spelling.
|
||||
// { dg-do compile { target i?86-*-linux* x86_64-*-linux* } }
|
||||
// { dg-final { scan-assembler "\\.rodata" } }
|
||||
|
||||
template <typename T>
|
||||
struct B {
|
||||
int i;
|
||||
};
|
||||
|
||||
// This declaration should be placed in .rodata.
|
||||
const B<int> const_B __attribute__((used)) = { 3 };
|
||||
Reference in New Issue
Block a user