OSDN Git Service

* decl2.c (determine_visibility): Make anonymous types internal.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Sep 2009 21:25:18 +0000 (21:25 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Sep 2009 21:25:18 +0000 (21:25 +0000)
(mark_used): Complain about types without linkage used in
decls with internal linkage.
(vague_linkage_fn_p): Split out from...
* decl.c (maybe_commonize_var): ...here.
(grokdeclarator): Adjust linkage when a typedef gives linkage name.
* tree.c (no_linkage_check): Check the enclosing class and template
arguments.

* cp-tree.h (TYPE_NAMESPACE_SCOPE_P): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151868 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/nolinkage1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/nolinkage1.h [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/nolinkage1a.cc [new file with mode: 0644]

index 350aa3e..6c2ce9c 100644 (file)
@@ -1,5 +1,16 @@
 2009-09-18  Jason Merrill  <jason@redhat.com>
 
+       * decl2.c (determine_visibility): Make anonymous types internal.
+       (mark_used): Complain about types without linkage used in
+       decls with internal linkage.
+       (vague_linkage_fn_p): Split out from...
+       * decl.c (maybe_commonize_var): ...here.
+       (grokdeclarator): Adjust linkage when a typedef gives linkage name.
+       * tree.c (no_linkage_check): Check the enclosing class and template
+       arguments.
+
+       * cp-tree.h (TYPE_NAMESPACE_SCOPE_P): New.
+
        * pt.c (get_pattern_parm): New.
        (listify): Split out from...
        (listify_autos): ...here.
index 7801f98..816b4ca 100644 (file)
@@ -2129,6 +2129,9 @@ struct GTY(()) lang_decl {
   (!DECL_TEMPLATE_PARM_P (NODE)                                        \
    && TREE_CODE (CP_DECL_CONTEXT (NODE)) == NAMESPACE_DECL)
 
+#define TYPE_NAMESPACE_SCOPE_P(NODE) \
+  (TREE_CODE (CP_TYPE_CONTEXT (NODE)) == NAMESPACE_DECL)
+
 /* 1 iff NODE is a class member.  */
 #define DECL_CLASS_SCOPE_P(NODE) \
   (DECL_CONTEXT (NODE) && TYPE_P (DECL_CONTEXT (NODE)))
@@ -4457,6 +4460,7 @@ extern bool check_java_method                     (tree);
 extern tree build_memfn_type                   (tree, tree, cp_cv_quals);
 extern void maybe_retrofit_in_chrg             (tree);
 extern void maybe_make_one_only                        (tree);
+extern bool vague_linkage_fn_p                 (tree);
 extern void grokclassfn                                (tree, tree,
                                                 enum overload_flags);
 extern tree grok_array_decl                    (tree, tree);
index 0cfcb4f..614dbb0 100644 (file)
@@ -4615,13 +4615,7 @@ maybe_commonize_var (tree decl)
       /* Don't mess with __FUNCTION__.  */
       && ! DECL_ARTIFICIAL (decl)
       && DECL_FUNCTION_SCOPE_P (decl)
-      /* Unfortunately, import_export_decl has not always been called
-        before the function is processed, so we cannot simply check
-        DECL_COMDAT.  */
-      && (DECL_COMDAT (DECL_CONTEXT (decl))
-         || ((DECL_DECLARED_INLINE_P (DECL_CONTEXT (decl))
-              || DECL_TEMPLATE_INSTANTIATION (DECL_CONTEXT (decl)))
-             && TREE_PUBLIC (DECL_CONTEXT (decl)))))
+      && vague_linkage_fn_p (DECL_CONTEXT (decl)))
     {
       if (flag_weak)
        {
@@ -8845,6 +8839,10 @@ grokdeclarator (const cp_declarator *declarator,
            DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
              = TYPE_IDENTIFIER (type);
 
+         /* Adjust linkage now that we aren't anonymous anymore.  */
+         set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
+         determine_visibility (TYPE_MAIN_DECL (type));
+
          /* FIXME remangle member functions; member functions of a
             type with external linkage have external linkage.  */
        }
index eb48c55..3e8c0d7 100644 (file)
@@ -1605,6 +1605,22 @@ maybe_make_one_only (tree decl)
     }
 }
 
+/* Returns true iff DECL, a FUNCTION_DECL, has vague linkage.  This
+   predicate will give the right answer during parsing of the function,
+   which other tests may not.  */
+
+bool
+vague_linkage_fn_p (tree fn)
+{
+  /* Unfortunately, import_export_decl has not always been called
+     before the function is processed, so we cannot simply check
+     DECL_COMDAT.  */
+  return (DECL_COMDAT (fn)
+         || ((DECL_DECLARED_INLINE_P (fn)
+              || DECL_TEMPLATE_INSTANTIATION (fn))
+             && TREE_PUBLIC (fn)));
+}
+
 /* Determine whether or not we want to specifically import or export CTYPE,
    using various heuristics.  */
 
@@ -2075,6 +2091,16 @@ determine_visibility (tree decl)
          || ! DECL_VISIBILITY_SPECIFIED (decl))
        constrain_visibility (decl, tvis);
     }
+  else if (no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/true))
+    /* DR 757: A type without linkage shall not be used as the type of a
+       variable or function with linkage, unless
+       o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
+       o the variable or function is not used (3.2 [basic.def.odr]) or is
+       defined in the same translation unit.
+
+       Since non-extern "C" decls need to be defined in the same
+       translation unit, we can make the type internal.  */
+    constrain_visibility (decl, VISIBILITY_ANON);
 
   /* If visibility changed and DECL already has DECL_RTL, ensure
      symbol flags are updated.  */
@@ -3966,7 +3992,7 @@ mark_used (tree decl)
    o the variable or function has extern "C" linkage (7.5 [dcl.link]), or
    o the variable or function is not used (3.2 [basic.def.odr]) or is
    defined in the same translation unit.  */
-  if (TREE_PUBLIC (decl)
+  if (decl_linkage (decl) != lk_none
       && !DECL_EXTERN_C_P (decl)
       && !DECL_ARTIFICIAL (decl)
       && !decl_defined_p (decl)
index 808a18a..51752a3 100644 (file)
@@ -1513,7 +1513,7 @@ verify_stmt_tree (tree t)
 
 /* Check if the type T depends on a type with no linkage and if so, return
    it.  If RELAXED_P then do not consider a class type declared within
-   a TREE_PUBLIC function to have no linkage.  */
+   a vague-linkage function to have no linkage.  */
 
 tree
 no_linkage_check (tree t, bool relaxed_p)
@@ -1527,8 +1527,6 @@ no_linkage_check (tree t, bool relaxed_p)
 
   switch (TREE_CODE (t))
     {
-      tree fn;
-
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (t))
        goto ptrmem;
@@ -1536,13 +1534,42 @@ no_linkage_check (tree t, bool relaxed_p)
     case UNION_TYPE:
       if (!CLASS_TYPE_P (t))
        return NULL_TREE;
+
+      /* Check template type-arguments.  I think that types with no linkage
+         can't occur in non-type arguments, though that might change with
+         constexpr.  */
+      r = CLASSTYPE_TEMPLATE_INFO (t);
+      if (r)
+       {
+         tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (r));
+         int i;
+
+         for (i = TREE_VEC_LENGTH (args); i-- > 0; )
+           {
+             tree elt = TREE_VEC_ELT (args, i);
+             if (TYPE_P (elt)
+                 && (r = no_linkage_check (elt, relaxed_p), r))
+               return r;
+           }
+       }
       /* Fall through.  */
     case ENUMERAL_TYPE:
-      if (TYPE_ANONYMOUS_P (t))
-       return t;
-      fn = decl_function_context (TYPE_MAIN_DECL (t));
-      if (fn && (!relaxed_p || !TREE_PUBLIC (fn)))
+      /* Only treat anonymous types as having no linkage if they're at
+        namespace scope.  This doesn't have a core issue number yet.  */
+      if (TYPE_ANONYMOUS_P (t) && TYPE_NAMESPACE_SCOPE_P (t))
        return t;
+
+      r = CP_TYPE_CONTEXT (t);
+      if (TYPE_P (r))
+       return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
+      else if (TREE_CODE (r) == FUNCTION_DECL)
+       {
+         if (!relaxed_p || !TREE_PUBLIC (r) || !vague_linkage_fn_p (r))
+           return t;
+         else
+           return no_linkage_check (CP_DECL_CONTEXT (r), relaxed_p);
+       }
+
       return NULL_TREE;
 
     case ARRAY_TYPE:
index 43f42b5..3604d5b 100644 (file)
@@ -1,5 +1,7 @@
 2009-09-18  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/nolinkage1{.C,.h,a.cc}: New.
+
        * g++.dg/cpp0x/initlist-deduce.C: New.
 
 2009-09-18  Janis Johnson  <janis187@us.ibm.com>
diff --git a/gcc/testsuite/g++.dg/cpp0x/nolinkage1.C b/gcc/testsuite/g++.dg/cpp0x/nolinkage1.C
new file mode 100644 (file)
index 0000000..a31394b
--- /dev/null
@@ -0,0 +1,21 @@
+// DR 757 allows using types without linkage in declarations with linkage.
+// Test that this doesn't lead to link-time collisions.
+
+// { dg-additional-sources "nolinkage1a.cc" }
+// { dg-do link }
+
+#include "nolinkage1.h"
+
+typedef struct { int i; } *AP;
+
+void f(AP) { }
+
+A<AP> a;
+
+static void g()
+{
+  struct B { };
+  A<B> a;
+}
+
+int main() { g(); f(0); }
diff --git a/gcc/testsuite/g++.dg/cpp0x/nolinkage1.h b/gcc/testsuite/g++.dg/cpp0x/nolinkage1.h
new file mode 100644 (file)
index 0000000..3cb5f63
--- /dev/null
@@ -0,0 +1,8 @@
+template <class T>
+struct A
+{
+  A();
+};
+
+template <class T>
+A<T>::A() {  }
diff --git a/gcc/testsuite/g++.dg/cpp0x/nolinkage1a.cc b/gcc/testsuite/g++.dg/cpp0x/nolinkage1a.cc
new file mode 100644 (file)
index 0000000..f8528f3
--- /dev/null
@@ -0,0 +1,15 @@
+#include "nolinkage1.h"
+
+typedef struct { double d; } *BP;
+
+void f(BP) {  }
+
+A<BP> b;
+
+static void g()
+{
+  struct B { };
+  A<B> a;
+}
+
+int dummy() { g(); f(0); }