diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e21bb0f0907..fa83612725d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2007-08-22 Jason Merrill + + PR c++/29365 + * pt.c (outermost_tinst_level): New function. + * lex.c (in_main_input_context): New function. + * decl2.c (constrain_class_visibility): Use it to avoid warning + about uses of the anonymous namespace in the main input file. + 2007-08-21 Jakub Jelinek * init.c (build_new_1): Use get_target_expr instead of save_expr. @@ -939,7 +947,6 @@ 2007-04-16 Seongbae Park PR c++/29365 - * cp/decl2.c (constrain_class_visibility): Do not warn about the use of anonymous namespace in the main input file. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c715cd7a035..5aea98bb801 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4374,6 +4374,7 @@ extern void yyerror (const char *); extern void yyhook (int); extern bool cxx_init (void); extern void cxx_finish (void); +extern bool in_main_input_context (void); /* in method.c */ extern void init_method (void); @@ -4465,6 +4466,7 @@ extern tree build_non_dependent_args (tree); extern bool reregister_specialization (tree, tree, tree); extern tree fold_non_dependent_expr (tree); extern bool explicit_class_specialization_p (tree); +extern tree outermost_tinst_level (void); /* in repo.c */ extern void init_repo (void); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 97a03c7eb6d..2708e5819f9 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1854,8 +1854,7 @@ constrain_class_visibility (tree type) if (subvis == VISIBILITY_ANON) { - if (strcmp (main_input_filename, - DECL_SOURCE_FILE (TYPE_MAIN_DECL (ftype)))) + if (!in_main_input_context ()) warning (0, "\ %qT has a field %qD whose type uses the anonymous namespace", type, t); @@ -1875,8 +1874,7 @@ constrain_class_visibility (tree type) if (subvis == VISIBILITY_ANON) { - if (strcmp (main_input_filename, - DECL_SOURCE_FILE (TYPE_MAIN_DECL (TREE_TYPE (t))))) + if (!in_main_input_context()) warning (0, "\ %qT has a base %qT whose type uses the anonymous namespace", type, TREE_TYPE (t)); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 3a2caecc43a..e62887dcfc1 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -849,3 +849,18 @@ make_aggr_type (enum tree_code code) return t; } + +/* Returns true if we are currently in the main source file, or in a + template instantiation started from the main source file. */ + +bool +in_main_input_context (void) +{ + tree tl = outermost_tinst_level(); + + if (tl) + return strcmp (main_input_filename, + LOCATION_FILE (TINST_LOCATION (tl))) == 0; + else + return strcmp (main_input_filename, input_filename) == 0; +} diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3f218e6248a..b4a9b689005 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6045,6 +6045,15 @@ reopen_tinst_level (tree level) pop_tinst_level (); } +/* Returns the TINST_LEVEL which gives the original instantiation + context. */ + +tree +outermost_tinst_level (void) +{ + return tree_last (current_tinst_level); +} + /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the vector of template arguments, as for tsubst. diff --git a/gcc/testsuite/g++.dg/warn/anonymous-namespace-1.C b/gcc/testsuite/g++.dg/warn/anonymous-namespace-1.C index 6949f158926..cf193e0cba5 100644 --- a/gcc/testsuite/g++.dg/warn/anonymous-namespace-1.C +++ b/gcc/testsuite/g++.dg/warn/anonymous-namespace-1.C @@ -13,5 +13,6 @@ class foobar1 good g; }; +#line 17 "foo.C" class foobar : public bad { }; // { dg-warning "uses the anonymous namespace" } class foobar2 { bad b; }; // { dg-warning "uses the anonymous namespace" } diff --git a/gcc/testsuite/g++.dg/warn/anonymous-namespace-2.C b/gcc/testsuite/g++.dg/warn/anonymous-namespace-2.C index 4d87b69d396..4048f3959df 100644 --- a/gcc/testsuite/g++.dg/warn/anonymous-namespace-2.C +++ b/gcc/testsuite/g++.dg/warn/anonymous-namespace-2.C @@ -10,20 +10,20 @@ namespace { struct g1 { good * A; }; -struct b1 { // { dg-warning "uses the anonymous namespace" } - bad * B; -}; - struct g2 { good * A[1]; }; +struct g3 { + good (*A)[1]; +}; + +#line 21 "foo.C" +struct b1 { // { dg-warning "uses the anonymous namespace" } + bad * B; +}; struct b2 { // { dg-warning "uses the anonymous namespace" } bad * B[1]; }; - -struct g3 { - good (*A)[1]; -}; struct b3 { // { dg-warning "uses the anonymous namespace" } bad (*B)[1]; }; diff --git a/gcc/testsuite/g++.dg/warn/anonymous-namespace-3.C b/gcc/testsuite/g++.dg/warn/anonymous-namespace-3.C new file mode 100644 index 00000000000..fee48b46017 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/anonymous-namespace-3.C @@ -0,0 +1,13 @@ +// Test for the warning of exposing types from an anonymous namespace +// { dg-do compile } +// +#include +#include "anonymous-namespace-3.h" + +struct B { std::auto_ptr p; }; + +#line 10 "foo.C" +struct C +{ // { dg-warning "uses the anonymous namespace" } + std::auto_ptr p; +}; diff --git a/gcc/testsuite/g++.dg/warn/anonymous-namespace-3.h b/gcc/testsuite/g++.dg/warn/anonymous-namespace-3.h new file mode 100644 index 00000000000..0c7c1f8e406 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/anonymous-namespace-3.h @@ -0,0 +1 @@ +namespace { struct A; }