]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
decl.c (start_decl_1): Call cp_apply_type_quals_to_decl after completing the type.
authorMark Mitchell <mark@codesourcery.com>
Tue, 16 Oct 2007 21:09:41 +0000 (21:09 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 16 Oct 2007 21:09:41 +0000 (21:09 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/const5.C [new file with mode: 0644]

index e884dc47c69b6ba8c05b93098b58607317556cf7..dd3f12fd4b1be7070dff14eda701a53b502851e5 100644 (file)
@@ -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
index 90cb6e8182b0720f42f1b90b8258fbad3c161874..affff6379284b95e6ead0f74434d2d9972e60622 100644 (file)
@@ -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.
index 7f93bf081592f665a7322ff40a579dd6ac648cb9..6ad8587b1fac67cefc87003f3995f8ce000abf7d 100644 (file)
@@ -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
diff --git a/gcc/testsuite/g++.dg/opt/const5.C b/gcc/testsuite/g++.dg/opt/const5.C
new file mode 100644 (file)
index 0000000..3785271
--- /dev/null
@@ -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 };