* decl2.c (mark_used): Check cxx_dialect.
* decl.c (grokfndecl): Do check type linkage in C++98 mode.
(grokvardecl): Likewise.
* pt.c (check_instantiated_arg): Likewise.
From-SVN: r153816
+2009-11-02 Jason Merrill <jason@redhat.com>
+
+ Restrict DR 757 change to C++0x mode.
+ * decl2.c (mark_used): Check cxx_dialect.
+ * decl.c (grokfndecl): Do check type linkage in C++98 mode.
+ (grokvardecl): Likewise.
+ * pt.c (check_instantiated_arg): Likewise.
+
2009-11-02 Jakub Jelinek <jakub@redhat.com>
PR c++/41774
|| decl_function_context (TYPE_MAIN_DECL (ctype))))
publicp = 0;
+ if (publicp && cxx_dialect == cxx98)
+ {
+ /* [basic.link]: A name with no linkage (notably, the name of a class
+ or enumeration declared in a local scope) shall not be used to
+ declare an entity with linkage.
+
+ DR 757 relaxes this restriction for C++0x. */
+ t = no_linkage_check (TREE_TYPE (decl),
+ /*relaxed_p=*/false);
+ if (t)
+ {
+ if (TYPE_ANONYMOUS_P (t))
+ {
+ if (DECL_EXTERN_C_P (decl))
+ /* Allow this; it's pretty common in C. */;
+ else
+ {
+ permerror (input_location, "non-local function %q#D uses anonymous type",
+ decl);
+ if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
+ permerror (input_location, "%q+#D does not refer to the unqualified "
+ "type, so it is not used for linkage",
+ TYPE_NAME (t));
+ }
+ }
+ else
+ permerror (input_location, "non-local function %q#D uses local type %qT", decl, t);
+ }
+ }
+
TREE_PUBLIC (decl) = publicp;
if (! publicp)
{
if (declspecs->specs[(int)ds_thread])
DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+ /* If the type of the decl has no linkage, make sure that we'll
+ notice that in mark_used. */
+ if (cxx_dialect > cxx98
+ && decl_linkage (decl) != lk_none
+ && DECL_LANG_SPECIFIC (decl) == NULL
+ && !DECL_EXTERN_C_P (decl)
+ && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
+ retrofit_lang_decl (decl);
+
if (TREE_PUBLIC (decl))
{
- /* If the type of the decl has no linkage, make sure that we'll
- notice that in mark_used. */
- if (DECL_LANG_SPECIFIC (decl) == NULL
- && TREE_PUBLIC (decl)
- && !DECL_EXTERN_C_P (decl)
- && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
- retrofit_lang_decl (decl);
+ /* [basic.link]: A name with no linkage (notably, the name of a class
+ or enumeration declared in a local scope) shall not be used to
+ declare an entity with linkage.
+
+ DR 757 relaxes this restriction for C++0x. */
+ tree t = (cxx_dialect > cxx98 ? NULL_TREE
+ : no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false));
+ if (t)
+ {
+ if (TYPE_ANONYMOUS_P (t))
+ {
+ if (DECL_EXTERN_C_P (decl))
+ /* Allow this; it's pretty common in C. */
+ ;
+ else
+ {
+ /* DRs 132, 319 and 389 seem to indicate types with
+ no linkage can only be used to declare extern "C"
+ entities. Since it's not always an error in the
+ ISO C++ 90 Standard, we only issue a warning. */
+ warning (0, "non-local variable %q#D uses anonymous type",
+ decl);
+ if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
+ warning (0, "%q+#D does not refer to the unqualified "
+ "type, so it is not used for linkage",
+ TYPE_NAME (t));
+ }
+ }
+ else
+ warning (0, "non-local variable %q#D uses local type %qT", decl, t);
+ }
}
else
DECL_INTERFACE_KNOWN (decl) = 1;
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 (decl_linkage (decl) != lk_none
+ if (cxx_dialect > cxx98
+ && decl_linkage (decl) != lk_none
&& !DECL_EXTERN_C_P (decl)
&& !DECL_ARTIFICIAL (decl)
&& !decl_defined_p (decl)
}
/* Verify that the instantiated ARGS are valid. For type arguments,
- make sure that the type is not variably modified. For non-type arguments,
+ make sure that the type's linkage is ok. For non-type arguments,
make sure they are constants if they are integral or enumerations.
Emit an error under control of COMPLAIN, and return TRUE on error. */
}
else if (TYPE_P (t))
{
- if (variably_modified_type_p (t, NULL_TREE))
+ /* [basic.link]: A name with no linkage (notably, the name
+ of a class or enumeration declared in a local scope)
+ shall not be used to declare an entity with linkage.
+ This implies that names with no linkage cannot be used as
+ template arguments
+
+ DR 757 relaxes this restriction for C++0x. */
+ tree nt = (cxx_dialect > cxx98 ? NULL_TREE
+ : no_linkage_check (t, /*relaxed_p=*/false));
+
+ if (nt)
+ {
+ /* DR 488 makes use of a type with no linkage cause
+ type deduction to fail. */
+ if (complain & tf_error)
+ {
+ if (TYPE_ANONYMOUS_P (nt))
+ error ("%qT is/uses anonymous type", t);
+ else
+ error ("template argument for %qD uses local type %qT",
+ tmpl, t);
+ }
+ return true;
+ }
+ /* In order to avoid all sorts of complications, we do not
+ allow variably-modified types as template arguments. */
+ else if (variably_modified_type_p (t, NULL_TREE))
{
if (complain & tf_error)
error ("%qT is a variably modified type", t);
+2009-11-02 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/other/linkage2.C: Move to...
+ * g++.dg/cpp0x/linkage2.C: ..here.
+ * g++.dg/abi/mangle32.C: Add -std=c++0x.
+ * g++.dg/cpp0x/nolinkage1.C: Likewise.
+ * g++.dg/debug/dwarf2/anonname1.C: Likewise.
+ * g++.dg/ext/anon-struct4.C: Revert earlier change.
+ * g++.dg/lookup/anon2.C: Likewise.
+ * g++.dg/other/anon3.C: Likewise.
+ * g++.dg/template/arg2.C: Likewise.
+ * g++.dg/template/local4.C: Likewise.
+ * g++.old-deja/g++.law/operators32.C: Likewise.
+ * g++.old-deja/g++.other/linkage2.C: Likewise.
+ * g++.old-deja/g++.pt/enum6.C: Likewise.
+ * g++.old-deja/g++.other/anon9.C: Likewise.
+ * g++.old-deja/g++.other/linkage1.C: Likewise.
+
2009-11-02 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
PR tree-optimization/41857
// namespace-scope unnamed types have no linkage, so we only test that they
// are distinct.
+
+// { dg-options -std=c++0x }
+
typedef struct { } *A;
typedef struct { } *B;
// o the variable or function is not used (3.2 [basic.def.odr]) or is
// defined in the same translation unit.
+// { dg-options -std=c++0x }
+
template <typename T> struct B {
void g(T){}
void h(T); // { dg-error "never defined" }
// { dg-additional-sources "nolinkage1a.cc" }
// { dg-do link }
+// { dg-options -std=c++0x }
#include "nolinkage1.h"
// PR debug/41828
// { dg-do compile }
-// { dg-options "-gdwarf-2 -dA" }
+// { dg-options "-gdwarf-2 -dA -std=c++0x" }
// { dg-final { scan-assembler-not "<anonymous" } }
// { dg-final { scan-assembler-not "\._\[0-9\]" } }
// { dg-final { scan-assembler-not "\$_\[0-9\]" } }
// PR c++/14401
struct { struct { int& i ; } bar ; } foo ; // { dg-error "uninitialized" "uninit" }
+// { dg-warning "anonymous" "anon" { target *-*-* } 3 }
// { dg-do compile }
// { dg-options "" }
-// Make sure we don't issue a diagnostic if a type with no linkage is used
-// to declare a a variable that has linkage if that variable is defined.
+// Make sure we issue a diagnostic if a type with no linkage is used
+// to declare a a variable that has linkage.
-struct { int i; } a;
+struct { int i; } a; // { dg-warning "anonymous type" }
void foo() { a.i; }
// { dg-do compile }
-enum { a = 3 } x;
+enum { a = 3 } x; // { dg-warning "anonymous type" }
void fn ()
{
class L {};
- X<L> f;
+ X<L> f; // { dg-error "uses local type|trying to instantiate|no type|invalid type" "" }
}
int main () {
struct S {};
- foo<S> ();
+ foo<S> (); // { dg-error "match" }
}
};
foo **f2;
-allocate2d(d1, d2, f2);
-ffree(d1, f2);
+allocate2d(d1, d2, f2);// { dg-error "" } type.*// ERROR - trying to.*
+ffree(d1, f2);// { dg-error "" } type.*// ERROR - trying to.*
}
typedef const struct { int i; } T; // { dg-error "" } referenced below
void f (T* t); // { dg-error "" } uses unnamed type
-
-int main()
-{
- f(0);
-}
int i;
} *p;
-void f (p) { }
-p q;
+void f (p) { } // { dg-error "uses anonymous type" }
+p q; // { dg-warning "uses anonymous type" }
int main()
{
- extern p j; // { dg-error "anonymous type" }
- j+1;
+ extern p j; // { dg-warning "uses anonymous type" }
struct A { int j; };
- extern A a; // { dg-error "local type" }
- a.j+1;
- extern void f (A); // { dg-error "local type" }
- f(a);
+ extern A a; // { dg-warning "uses local type" }
+ extern void f (A); // { dg-error "uses local type" }
}
}
typedef struct { int dummy[10]; } *FAIL_FILE;
-extern FAIL_FILE fail_open(); // OK because it's never used
+extern FAIL_FILE fail_open(); // { dg-error "" } non-local function
typedef struct { int dummy[10]; } *SUCCESS_FILE, S;
extern SUCCESS_FILE success_open();
{
enum tern { H, L, X, U };
- vector<tern> ternvec;
+ vector<tern> ternvec; // { dg-error "" } composed from a local type
}
template void fn(int);