Commit 1eee69dd by Jason Merrill Committed by Jason Merrill

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.

From-SVN: r153816
parent d7c0c068
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
......
......@@ -6768,6 +6768,36 @@ grokfndecl (tree ctype,
|| 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)
{
......@@ -7007,15 +7037,48 @@ grokvardecl (tree type,
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;
......
......@@ -3990,7 +3990,8 @@ 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 (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)
......
......@@ -12479,7 +12479,7 @@ tsubst_copy_and_build (tree t,
}
/* 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. */
......@@ -12500,7 +12500,33 @@ check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain)
}
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
......
......@@ -2,6 +2,9 @@
// 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;
......
......@@ -4,6 +4,8 @@
// 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" }
......
......@@ -3,6 +3,7 @@
// { 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; }
......@@ -4,4 +4,4 @@
// { dg-do compile }
enum { a = 3 } x;
enum { a = 3 } x; // { dg-warning "anonymous type" }
......@@ -10,5 +10,5 @@ template <typename T> class X {};
void fn ()
{
class L {};
X<L> f;
X<L> f; // { dg-error "uses local type|trying to instantiate|no type|invalid type" "" }
}
......@@ -4,5 +4,5 @@ template <typename T> void foo() {}
int main () {
struct S {};
foo<S> ();
foo<S> (); // { dg-error "match" }
}
......@@ -49,7 +49,7 @@ foo() {std::cout << "foo created" << std::endl; }
};
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.*
}
......@@ -4,8 +4,3 @@
typedef const struct { int i; } T; // { dg-error "" } referenced below
void f (T* t); // { dg-error "" } uses unnamed type
int main()
{
f(0);
}
......@@ -3,16 +3,13 @@ typedef struct {
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" }
}
......@@ -7,7 +7,7 @@ extern GDBM_FILE gdbm_open();
}
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();
......
......@@ -8,7 +8,7 @@ void fn(T)
{
enum tern { H, L, X, U };
vector<tern> ternvec;
vector<tern> ternvec; // { dg-error "" } composed from a local type
}
template void fn(int);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment