diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c00848ca57f..44bf040fe51 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-09-09 Paolo Carlini + + PR c++/53184 + * doc/invoke.texi ([Wsubobject-linkage]): Document. + 2015-09-09 Tom de Vries * params-list.h: Add missing copyright notice. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 964f6dda762..3acc84f433b 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2015-09-09 Paolo Carlini + + PR c++/53184 + * c.opt ([Wsubobject-linkage]): Add. + 2015-09-03 Martin Sebor PR c/66516 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 050dcb02734..d519d7a000b 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -944,6 +944,11 @@ Wuseless-cast C++ ObjC++ Var(warn_useless_cast) Warning Warn about useless casts +Wsubobject-linkage +C++ ObjC++ Var(warn_subobject_linkage) Warning Init(1) +Warn if a class type has a base or a field whose type uses the anonymous +namespace or depends on a type with no linkage + ansi C ObjC C++ ObjC++ A synonym for -std=c89 (for C) or -std=c++98 (for C++) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 515a1e88a9d..1cc576a3f22 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2015-09-09 Paolo Carlini + + PR c++/53184 + * decl2.c (constrain_class_visibility): Use Wsubobject-linkage. + 2015-09-09 Jakub Jelinek PR c++/67504 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 74ba380c44d..6c1f0842331 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2564,10 +2564,25 @@ constrain_class_visibility (tree type) if (subvis == VISIBILITY_ANON) { - if (!in_main_input_context ()) - warning (0, "\ + if (!in_main_input_context()) + { + tree nlt = no_linkage_check (ftype, /*relaxed_p=*/false); + if (nlt) + { + if (same_type_p (TREE_TYPE (t), nlt)) + warning (OPT_Wsubobject_linkage, "\ +%qT has a field %qD whose type has no linkage", + type, t); + else + warning (OPT_Wsubobject_linkage, "\ +%qT has a field %qD whose type depends on the type %qT which has no linkage", + type, t, nlt); + } + else + warning (OPT_Wsubobject_linkage, "\ %qT has a field %qD whose type uses the anonymous namespace", - type, t); + type, t); + } } else if (MAYBE_CLASS_TYPE_P (ftype) && vis < VISIBILITY_HIDDEN @@ -2585,9 +2600,24 @@ constrain_class_visibility (tree type) if (subvis == VISIBILITY_ANON) { if (!in_main_input_context()) - warning (0, "\ + { + tree nlt = no_linkage_check (TREE_TYPE (t), /*relaxed_p=*/false); + if (nlt) + { + if (same_type_p (TREE_TYPE (t), nlt)) + warning (OPT_Wsubobject_linkage, "\ +%qT has a base %qT whose type has no linkage", + type, TREE_TYPE (t)); + else + warning (OPT_Wsubobject_linkage, "\ +%qT has a base %qT whose type depends on the type %qT which has no linkage", + type, TREE_TYPE (t), nlt); + } + else + warning (OPT_Wsubobject_linkage, "\ %qT has a base %qT whose type uses the anonymous namespace", - type, TREE_TYPE (t)); + type, TREE_TYPE (t)); + } } else if (vis < VISIBILITY_HIDDEN && subvis >= VISIBILITY_HIDDEN) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 76e5e29450e..403cebe2c15 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -282,7 +282,7 @@ Objective-C and Objective-C++ Dialects}. -Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{]} @gol -Wsuggest-final-types @gol -Wsuggest-final-methods -Wsuggest-override @gol --Wmissing-format-attribute @gol +-Wmissing-format-attribute -Wsubobject-linkage @gol -Wswitch -Wswitch-default -Wswitch-enum -Wswitch-bool -Wsync-nand @gol -Wsystem-headers -Wtautological-compare -Wtrampolines -Wtrigraphs @gol -Wtype-limits -Wundef @gol @@ -4923,6 +4923,13 @@ types. @option{-Wconversion-null} is enabled by default. Warn when a literal '0' is used as null pointer constant. This can be useful to facilitate the conversion to @code{nullptr} in C++11. +@item -Wsubobject-linkage @r{(C++ and Objective-C++ only)} +@opindex Wsubobject-linkage +@opindex Wno-subobject-linkage +Warn if a class type has a base or a field whose type uses the anonymous +namespace or depends on a type with no linkage. This warning is +enabled by default. + @item -Wdate-time @opindex Wdate-time @opindex Wno-date-time diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 360fe70b8d0..8215fbea23f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-09-09 Paolo Carlini + + PR c++/53184 + * g++.dg/warn/Wsubobject-linkage-1.C: New. + * g++.dg/warn/Wsubobject-linkage-2.C: Likewise. + * g++.dg/warn/Wsubobject-linkage-3.C: Likewise. + * g++.dg/warn/Wsubobject-linkage-4.C: Likewise. + 2015-09-09 Kyrylo Tkachov * gcc.target/aarch64/mod_2.x: New file. diff --git a/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-1.C b/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-1.C new file mode 100644 index 00000000000..adcaa6dbdaf --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-1.C @@ -0,0 +1,9 @@ +// PR c++/53184 + +typedef volatile struct { } Foo; + +#line 6 "foo.C" +struct Bar { Foo foo; }; // { dg-warning "no linkage" } +// { dg-bogus "anonymous namespace" "" { target *-*-* } 6 } +struct Bar2 : Foo { }; // { dg-warning "no linkage" } +// { dg-bogus "anonymous namespace" "" { target *-*-* } 8 } diff --git a/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-2.C b/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-2.C new file mode 100644 index 00000000000..4bb255c79a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-2.C @@ -0,0 +1,8 @@ +// PR c++/53184 +// { dg-options "-Wno-subobject-linkage" } + +typedef volatile struct { } Foo; + +#line 7 "foo.C" +struct Bar { Foo foo; }; +struct Bar2 : Foo { }; diff --git a/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-3.C b/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-3.C new file mode 100644 index 00000000000..e9acb633a1c --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-3.C @@ -0,0 +1,9 @@ +// PR c++/53184 + +namespace { struct Foo { }; } + +#line 6 "foo.C" +struct Bar { Foo foo; }; // { dg-warning "anonymous namespace" } +// { dg-bogus "no linkage" "" { target *-*-* } 6 } +struct Bar2 : Foo { }; // { dg-warning "anonymous namespace" } +// { dg-bogus "no linkage" "" { target *-*-* } 8 } diff --git a/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-4.C b/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-4.C new file mode 100644 index 00000000000..033bc473005 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wsubobject-linkage-4.C @@ -0,0 +1,8 @@ +// PR c++/53184 +// { dg-options "-Wno-subobject-linkage" } + +namespace { struct Foo { }; } + +#line 7 "foo.C" +struct Bar { Foo foo; }; +struct Bar2 : Foo { };