diff options
author | Jason Merrill <jason@redhat.com> | 2009-11-02 11:14:26 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-11-02 11:14:26 -0500 |
commit | 1eee69dd7102f777d5a147beb7d7686a7057df78 (patch) | |
tree | 8bf6182385501879c97b8e139429d6712bc20e8d /gcc | |
parent | d7c0c068dd5d174f5183c2187499332198aea683 (diff) | |
download | gcc-1eee69dd7102f777d5a147beb7d7686a7057df78.zip gcc-1eee69dd7102f777d5a147beb7d7686a7057df78.tar.gz gcc-1eee69dd7102f777d5a147beb7d7686a7057df78.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/decl.c | 77 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle32.C | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/linkage2.C (renamed from gcc/testsuite/g++.dg/other/linkage2.C) | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/nolinkage1.C | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/debug/dwarf2/anonname1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/anon-struct4.C | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/anon2.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/anon3.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/arg2.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/local4.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.law/operators32.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/anon9.C | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/linkage1.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/linkage2.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/enum6.C | 2 |
19 files changed, 149 insertions, 34 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 044b568..1921f72 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +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 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 33023a7..de29d0b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 592ee08..b1fe4b9 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9983a95..2f0fa12 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2d1378a..52a26bc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,21 @@ +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 diff --git a/gcc/testsuite/g++.dg/abi/mangle32.C b/gcc/testsuite/g++.dg/abi/mangle32.C index de02887..244d074 100644 --- a/gcc/testsuite/g++.dg/abi/mangle32.C +++ b/gcc/testsuite/g++.dg/abi/mangle32.C @@ -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; diff --git a/gcc/testsuite/g++.dg/other/linkage2.C b/gcc/testsuite/g++.dg/cpp0x/linkage2.C index 4e3e6f1..f41c21a 100644 --- a/gcc/testsuite/g++.dg/other/linkage2.C +++ b/gcc/testsuite/g++.dg/cpp0x/linkage2.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/cpp0x/nolinkage1.C b/gcc/testsuite/g++.dg/cpp0x/nolinkage1.C index a31394b..b69b6dd 100644 --- a/gcc/testsuite/g++.dg/cpp0x/nolinkage1.C +++ b/gcc/testsuite/g++.dg/cpp0x/nolinkage1.C @@ -3,6 +3,7 @@ // { dg-additional-sources "nolinkage1a.cc" } // { dg-do link } +// { dg-options -std=c++0x } #include "nolinkage1.h" diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/anonname1.C b/gcc/testsuite/g++.dg/debug/dwarf2/anonname1.C index dcd2d8d..c9da2d6 100644 --- a/gcc/testsuite/g++.dg/debug/dwarf2/anonname1.C +++ b/gcc/testsuite/g++.dg/debug/dwarf2/anonname1.C @@ -1,6 +1,6 @@ // 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\]" } } diff --git a/gcc/testsuite/g++.dg/ext/anon-struct4.C b/gcc/testsuite/g++.dg/ext/anon-struct4.C index 53302d8..4f0fcd1 100644 --- a/gcc/testsuite/g++.dg/ext/anon-struct4.C +++ b/gcc/testsuite/g++.dg/ext/anon-struct4.C @@ -1,3 +1,4 @@ // PR c++/14401 struct { struct { int& i ; } bar ; } foo ; // { dg-error "uninitialized" "uninit" } +// { dg-warning "anonymous" "anon" { target *-*-* } 3 } diff --git a/gcc/testsuite/g++.dg/lookup/anon2.C b/gcc/testsuite/g++.dg/lookup/anon2.C index 3143b62..d556ba0 100644 --- a/gcc/testsuite/g++.dg/lookup/anon2.C +++ b/gcc/testsuite/g++.dg/lookup/anon2.C @@ -1,9 +1,9 @@ // { 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; } diff --git a/gcc/testsuite/g++.dg/other/anon3.C b/gcc/testsuite/g++.dg/other/anon3.C index 87cbfb5..87116eb 100644 --- a/gcc/testsuite/g++.dg/other/anon3.C +++ b/gcc/testsuite/g++.dg/other/anon3.C @@ -4,4 +4,4 @@ // { dg-do compile } -enum { a = 3 } x; +enum { a = 3 } x; // { dg-warning "anonymous type" } diff --git a/gcc/testsuite/g++.dg/template/arg2.C b/gcc/testsuite/g++.dg/template/arg2.C index 1314b25..9fb7a68 100644 --- a/gcc/testsuite/g++.dg/template/arg2.C +++ b/gcc/testsuite/g++.dg/template/arg2.C @@ -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" "" } } diff --git a/gcc/testsuite/g++.dg/template/local4.C b/gcc/testsuite/g++.dg/template/local4.C index 41e2370..cfa3736 100644 --- a/gcc/testsuite/g++.dg/template/local4.C +++ b/gcc/testsuite/g++.dg/template/local4.C @@ -4,5 +4,5 @@ template <typename T> void foo() {} int main () { struct S {}; - foo<S> (); + foo<S> (); // { dg-error "match" } } diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators32.C b/gcc/testsuite/g++.old-deja/g++.law/operators32.C index 89f0b66..91de03e 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/operators32.C +++ b/gcc/testsuite/g++.old-deja/g++.law/operators32.C @@ -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.* } diff --git a/gcc/testsuite/g++.old-deja/g++.other/anon9.C b/gcc/testsuite/g++.old-deja/g++.other/anon9.C index f4b1923..a364db8 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/anon9.C +++ b/gcc/testsuite/g++.old-deja/g++.other/anon9.C @@ -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); -} diff --git a/gcc/testsuite/g++.old-deja/g++.other/linkage1.C b/gcc/testsuite/g++.old-deja/g++.other/linkage1.C index de9a6ac..e9b5a9d 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/linkage1.C +++ b/gcc/testsuite/g++.old-deja/g++.other/linkage1.C @@ -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" } } diff --git a/gcc/testsuite/g++.old-deja/g++.other/linkage2.C b/gcc/testsuite/g++.old-deja/g++.other/linkage2.C index 64f74f7..2385b22 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/linkage2.C +++ b/gcc/testsuite/g++.old-deja/g++.other/linkage2.C @@ -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(); diff --git a/gcc/testsuite/g++.old-deja/g++.pt/enum6.C b/gcc/testsuite/g++.old-deja/g++.pt/enum6.C index 561254d..254b48b 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/enum6.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/enum6.C @@ -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); |