From: Anders Carlsson Date: Fri, 24 Sep 2010 21:25:25 +0000 (+0000) Subject: Allow the use of C++0x deleted functions as an extension in C++98. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=37bf9d2bb74944c9d9a52522412bc077629977f1;p=clang Allow the use of C++0x deleted functions as an extension in C++98. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114762 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index 2a25645088..def722b45e 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -2039,6 +2039,7 @@ isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index c7585e1ee0..6894f79524 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -226,6 +226,10 @@ def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment def NonGCC : DiagGroup<"non-gcc", [SignCompare, Conversion, LiteralRange]>; +// A warning group for warnings about using C++0x features as extensions in +// earlier C++ versions. +def CXX0x : DiagGroup<"c++0x-extensions">; + // A warning group for warnings about GCC extensions. def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 427bae2095..1c4a226b85 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -374,7 +374,10 @@ def err_ctor_init_missing_comma : Error< // C++ declarations def err_friend_decl_defines_class : Error< "cannot define a type in a friend declaration">; - + +def warn_deleted_function_accepted_as_extension: ExtWarn< + "deleted function definition accepted as a C++0x extension">, InGroup; + // Language specific pragmas // - Generic warnings def warn_pragma_expected_lparen : Warning< diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index a00dc0ec11..e3699ab7d5 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1466,7 +1466,8 @@ def err_template_spec_decl_out_of_scope_global : Error< def ext_template_spec_decl_out_of_scope_global : ExtWarn< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 must " - "originally be declared in the global scope; accepted as a C++0x extension">; + "originally be declared in the global scope; accepted as a C++0x extension">, + InGroup; def err_template_spec_decl_out_of_scope : Error< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 must " @@ -1474,7 +1475,8 @@ def err_template_spec_decl_out_of_scope : Error< def ext_template_spec_decl_out_of_scope : ExtWarn< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 must " - "originally be declared in namespace %2; accepted as a C++0x extension">; + "originally be declared in namespace %2; accepted as a C++0x extension">, + InGroup; def err_template_spec_redecl_out_of_scope : Error< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 not in a " @@ -1618,7 +1620,8 @@ def note_previous_explicit_instantiation : Note< "previous explicit instantiation is here">; def ext_explicit_instantiation_after_specialization : Extension< "explicit instantiation of %0 that occurs after an explicit " - "specialization will be ignored (C++0x extension)">; + "specialization will be ignored (C++0x extension)">, + InGroup; def note_previous_template_specialization : Note< "previous template specialization is here">; def err_explicit_instantiation_enum : Error< @@ -2464,7 +2467,8 @@ def err_array_size_ambiguous_conversion : Error< "enumeration type">; def ext_array_size_conversion : Extension< "implicit conversion from array size expression of type %0 to " - "%select{integral|enumeration}1 type %2 is a C++0x extension">; + "%select{integral|enumeration}1 type %2 is a C++0x extension">, + InGroup; def err_default_init_const : Error< "default initialization of an object of const type %0" @@ -2878,7 +2882,7 @@ def err_in_class_initializer_bad_type : Error< "static data member of type %0 must be initialized out of line">; def ext_in_class_initializer_float_type : ExtWarn< "in-class initializer for static data member of type %0 " - "is a C++0x extension">; + "is a C++0x extension">, InGroup; def err_in_class_initializer_non_constant : Error< "in-class initializer is not a constant expression">; @@ -3042,7 +3046,7 @@ def warn_not_compound_assign : Warning< // C++0x explicit conversion operators def warn_explicit_conversion_functions : Warning< - "explicit conversion functions are a C++0x extension">; + "explicit conversion functions are a C++0x extension">, InGroup; def warn_printf_write_back : Warning< "use of '%%n' in format string discouraged (potentially insecure)">, diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 9015c278fc..46b671da19 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -514,7 +514,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Case("cxx_attributes", LangOpts.CPlusPlus0x) .Case("cxx_auto_type", LangOpts.CPlusPlus0x) .Case("cxx_decltype", LangOpts.CPlusPlus0x) - .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x) + .Case("cxx_deleted_functions", true) // Accepted as an extension. .Case("cxx_exceptions", LangOpts.Exceptions) .Case("cxx_rtti", LangOpts.RTTI) .Case("cxx_static_assert", LangOpts.CPlusPlus0x) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index bef9f9585d..5ed22e2753 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -589,8 +589,12 @@ Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D, // Parse declarator '=' initializer. if (Tok.is(tok::equal)) { ConsumeToken(); - if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) { + if (Tok.is(tok::kw_delete)) { SourceLocation DelLoc = ConsumeToken(); + + if (!getLang().CPlusPlus0x) + Diag(DelLoc, diag::warn_deleted_function_accepted_as_extension); + Actions.SetDeclDeleted(ThisDecl, DelLoc); } else { if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) { diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 56fee66fcd..092268c821 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1443,7 +1443,9 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // '=' 'delete' if (Tok.is(tok::equal)) { ConsumeToken(); - if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) { + if (Tok.is(tok::kw_delete)) { + if (!getLang().CPlusPlus0x) + Diag(Tok, diag::warn_deleted_function_accepted_as_extension); ConsumeToken(); Deleted = true; } else { diff --git a/test/Lexer/has_feature_cxx0x.cpp b/test/Lexer/has_feature_cxx0x.cpp index cc2ae28c58..c6c7787276 100644 --- a/test/Lexer/has_feature_cxx0x.cpp +++ b/test/Lexer/has_feature_cxx0x.cpp @@ -70,7 +70,7 @@ int no_static_assert(); // CHECK-0X: has_static_assert // CHECK-NO-0X: no_static_assert - +// We accept this as an extension. #if __has_feature(cxx_deleted_functions) int deleted_functions(); #else @@ -78,7 +78,7 @@ int no_deleted_functions(); #endif // CHECK-0X: deleted_functions -// CHECK-NO-0X: no_deleted_functions +// CHECK-NO-0X: deleted_functions #if __has_feature(cxx_rvalue_references) diff --git a/test/SemaCXX/deleted-function-extension.cpp b/test/SemaCXX/deleted-function-extension.cpp new file mode 100644 index 0000000000..fdf5ac8bd5 --- /dev/null +++ b/test/SemaCXX/deleted-function-extension.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s + +struct A { + A(const A&) = delete; // expected-warning {{deleted function definition accepted as a C++0x extension}} + A& operator=(const A&) = delete; // expected-warning {{deleted function definition accepted as a C++0x extension}} +}; + +void f() = delete; // expected-warning {{deleted function definition accepted as a C++0x extension}}