diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 33a66a467d..171995d1e1 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -55,7 +55,17 @@ def ExtraTokens : DiagGroup<"extra-tokens">; def FormatExtraArgs : DiagGroup<"format-extra-args">; def FormatZeroLength : DiagGroup<"format-zero-length">; -def CXX98Compat : DiagGroup<"c++98-compat">; +def CXX98CompatBindToTemporaryCopy : + DiagGroup<"c++98-compat-bind-to-temporary-copy">; +def CXX98CompatLocalTypeTemplateArgs : + DiagGroup<"c++98-compat-local-type-template-args">; +def CXX98CompatUnnamedTypeTemplateArgs : + DiagGroup<"c++98-compat-unnamed-type-template-args">; + +def CXX98Compat : DiagGroup<"c++98-compat", + [CXX98CompatBindToTemporaryCopy, + CXX98CompatLocalTypeTemplateArgs, + CXX98CompatUnnamedTypeTemplateArgs]>; // Warnings for C++11 features which are Extensions in C++98 mode. def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", [CXX98Compat]>; @@ -81,7 +91,8 @@ def : DiagGroup<"inline">; def : DiagGroup<"int-to-pointer-cast">; def : DiagGroup<"invalid-pch">; def LiteralRange : DiagGroup<"literal-range">; -def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args">; +def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args", + [CXX98CompatLocalTypeTemplateArgs]>; def MalformedWarningCheck : DiagGroup<"malformed-warning-check">; def Main : DiagGroup<"main">; def MissingBraces : DiagGroup<"missing-braces">; @@ -122,7 +133,8 @@ def PoundPragmaMessage : DiagGroup<"#pragma messages">, def : DiagGroup<"pointer-to-int-cast">; def : DiagGroup<"redundant-decls">; def ReturnType : DiagGroup<"return-type">; -def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy">; +def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy", + [CXX98CompatBindToTemporaryCopy]>; def SelfAssignment : DiagGroup<"self-assign">; def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">; def Sentinel : DiagGroup<"sentinel">; @@ -170,7 +182,8 @@ def Uninitialized : DiagGroup<"uninitialized">; def UninitializedMaybe : DiagGroup<"conditional-uninitialized">; def UnknownPragmas : DiagGroup<"unknown-pragmas">; def UnknownAttributes : DiagGroup<"attributes">; -def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args">; +def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args", + [CXX98CompatUnnamedTypeTemplateArgs]>; def UnusedArgument : DiagGroup<"unused-argument">; def UnusedComparison : DiagGroup<"unused-comparison">; def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index d8b35390fe..bf7f1b4827 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1113,7 +1113,7 @@ def warn_cxx98_compat_temp_copy : Warning< "of type %2 when binding a reference to a temporary would %select{invoke " "an inaccessible constructor|find no viable constructor|find ambiguous " "constructors|invoke a deleted constructor}0 in C++98">, - InGroup, DefaultIgnore; + InGroup, DefaultIgnore; // C++11 decltype def err_cannot_determine_declared_type_of_overloaded_function : Error< @@ -2157,10 +2157,10 @@ def ext_template_arg_unnamed_type : ExtWarn< "template argument uses unnamed type">, InGroup; def warn_cxx98_compat_template_arg_local_type : Warning< "local type %0 as template argument is incompatible with C++98">, - InGroup, DefaultIgnore; + InGroup, DefaultIgnore; def warn_cxx98_compat_template_arg_unnamed_type : Warning< "unnamed type as template argument is incompatible with C++98">, - InGroup, DefaultIgnore; + InGroup, DefaultIgnore; def note_template_unnamed_type_here : Note< "unnamed type used in template argument was declared here">; def err_template_arg_overload_type : Error< diff --git a/test/SemaCXX/cxx98-compat-flags.cpp b/test/SemaCXX/cxx98-compat-flags.cpp new file mode 100644 index 0000000000..fcc048a36d --- /dev/null +++ b/test/SemaCXX/cxx98-compat-flags.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Werror %s + +template int TemplateFn(T) { return 0; } +void LocalTemplateArg() { + struct S {}; + TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}} +} +struct {} obj_of_unnamed_type; // expected-note {{here}} +int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning {{unnamed type as template argument is incompatible with C++98}} + +namespace CopyCtorIssues { + struct Private { + Private(); + private: + Private(const Private&); // expected-note {{declared private here}} + }; + struct NoViable { + NoViable(); + NoViable(NoViable&); // expected-note {{not viable}} + }; + struct Ambiguous { + Ambiguous(); + Ambiguous(const Ambiguous &, int = 0); // expected-note {{candidate}} + Ambiguous(const Ambiguous &, double = 0); // expected-note {{candidate}} + }; + struct Deleted { // expected-note {{here}} + // Copy ctor implicitly defined as deleted because Private's copy ctor is + // inaccessible. + Private p; + }; + + const Private &a = Private(); // expected-warning {{copying variable of type 'CopyCtorIssues::Private' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}} + const NoViable &b = NoViable(); // expected-warning {{copying variable of type 'CopyCtorIssues::NoViable' when binding a reference to a temporary would find no viable constructor in C++98}} + const Ambiguous &c = Ambiguous(); // expected-warning {{copying variable of type 'CopyCtorIssues::Ambiguous' when binding a reference to a temporary would find ambiguous constructors in C++98}} + const Deleted &d = Deleted(); // expected-warning {{copying variable of type 'CopyCtorIssues::Deleted' when binding a reference to a temporary would invoke a deleted constructor in C++98}} +}