[cfe-commits] r142419 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaCast.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaType.cpp test/SemaCXX/cxx98-compat-pedantic.cpp test/SemaCXX/cxx98-compat.cpp

Richard Smith richard-llvm at metafoo.co.uk
Tue Oct 18 13:49:44 PDT 2011


Author: rsmith
Date: Tue Oct 18 15:49:44 2011
New Revision: 142419

URL: http://llvm.org/viewvc/llvm-project?rev=142419&view=rev
Log:
-Wc++98-compat and -Wc++98-compat-pedantic warnings for Sema, part 1.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaCast.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp
    cfe/trunk/test/SemaCXX/cxx98-compat.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=142419&r1=142418&r2=142419&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct 18 15:49:44 2011
@@ -192,6 +192,9 @@
   "using declaration can not refer to namespace">;
 def err_using_decl_constructor : Error<
   "using declaration can not refer to a constructor">;
+def warn_cxx98_compat_using_decl_constructor : Warning<
+  "inherited constructors are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_using_decl_destructor : Error<
   "using declaration can not refer to a destructor">;
 def err_using_decl_template_id : Error<
@@ -623,6 +626,9 @@
   "non-class friend type %0 is a C++11 extension">, InGroup<CXX11>;
 def err_friend_is_member : Error<
   "friends cannot be members of the declaring class">;
+def warn_cxx98_compat_friend_is_member : Warning<
+  "friend declaration naming a member of the declaring class is incompatible "
+  "with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
 def ext_unelaborated_friend_type : ExtWarn<
   "specify '%select{struct|union|class|enum}0' to befriend %1; accepted "
   "as a C++11 extension">, InGroup<CXX11>;
@@ -1160,8 +1166,11 @@
   "an incomplete enumeration type has no underlying type yet">;
 
 // C++11 delegating constructors
-def err_delegation_0x_only : Error<
+def err_delegating_ctor : Error<
   "delegating constructors are permitted only in C++11">;
+def warn_cxx98_compat_delegating_ctor : Warning<
+  "delegating constructors are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_delegating_initializer_alone : Error<
   "an initializer for a delegating constructor must appear alone">;
 def warn_delegating_ctor_cycle : Warning<
@@ -2071,6 +2080,9 @@
 def ext_template_parameter_default_in_function_template : ExtWarn<
   "default template arguments for a function template are a C++11 extension">,
   InGroup<CXX11>;
+def warn_cxx98_compat_template_parameter_default_in_function_template : Warning<
+  "default template arguments for a function template are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_template_parameter_default_template_member : Error<
   "cannot add a default template argument to the definition of a member of a "
   "class template">;
@@ -2111,6 +2123,12 @@
   "template argument uses local type %0">, InGroup<LocalTypeTemplateArgs>;
 def ext_template_arg_unnamed_type : ExtWarn<
   "template argument uses unnamed type">, InGroup<UnnamedTypeTemplateArgs>;
+def warn_cxx98_compat_template_arg_local_type : Warning<
+  "local type %0 as template argument is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
+def warn_cxx98_compat_template_arg_unnamed_type : Warning<
+  "unnamed type as template argument is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def note_template_unnamed_type_here : Note<
   "unnamed type used in template argument was declared here">;
 def err_template_arg_overload_type : Error<
@@ -2178,6 +2196,9 @@
   "non-type template argument is not a pointer to member constant">;
 def ext_template_arg_extra_parens : ExtWarn<
   "address non-type template argument cannot be surrounded by parentheses">;
+def warn_cxx98_compat_template_arg_extra_parens : Warning<
+  "redundant parentheses surrounding address non-type template argument are "
+  "incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
 def err_pointer_to_member_type : Error<
   "invalid use of pointer to member type after %select{.*|->*}0">;
 def err_pointer_to_member_call_drops_quals : Error<
@@ -2203,11 +2224,6 @@
   "%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">;
-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++11 extension">,
-  InGroup<CXX11>;
 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 "
@@ -2217,6 +2233,11 @@
   "function|static data member|member class}0 specialization of %1 must "
   "originally be declared in namespace %2; accepted as a C++11 extension">,
   InGroup<CXX11>;
+def warn_cxx98_compat_template_spec_decl_out_of_scope : Warning<
+  "%select{class template|class template partial|function template|member "
+  "function|static data member|member class}0 specialization of %1 outside "
+  "namespace %2 is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 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 "
@@ -2384,6 +2405,10 @@
     "explicit instantiation of %0 that occurs after an explicit "
     "specialization will be ignored (C++11 extension)">,
     InGroup<CXX11>;
+def warn_cxx98_compat_explicit_instantiation_after_specialization : Warning<
+    "explicit instantiation of %0 that occurs after an explicit "
+    "specialization is incompatible with C++98">,
+    InGroup<CXX98CompatPedantic>, DefaultIgnore;
 def note_previous_template_specialization : Note<
     "previous template specialization is here">;
 def err_explicit_instantiation_enum : Error<
@@ -2464,6 +2489,9 @@
   InGroup<DiagGroup<"typename-missing">>;
 def ext_typename_outside_of_template : ExtWarn<
   "'typename' occurs outside of a template">, InGroup<CXX11>;
+def warn_cxx98_compat_typename_outside_of_template : Warning<
+  "use of 'typename' outside of a template is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_typename_refers_to_using_value_decl : Error<
   "typename specifier refers to a dependent using declaration for a value "
   "%0 in %1">;
@@ -2482,6 +2510,9 @@
   "missing 'template' keyword prior to dependent template name '%0%1'">;
 def ext_template_outside_of_template : ExtWarn<
   "'template' keyword outside of a template">, InGroup<CXX11>;
+def warn_cxx98_compat_template_outside_of_template : Warning<
+  "use of 'template' keyword outside of a template is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 def err_non_type_template_in_nested_name_specifier : Error<
   "qualified name refers into a specialization of function template '%0'">;
@@ -3623,6 +3654,9 @@
   "which is not a reference, pointer-to-object, or pointer-to-data-member">;
 def ext_cast_fn_obj : Extension<
   "cast between pointer-to-function and pointer-to-object is an extension">;
+def warn_cxx98_compat_cast_fn_obj : Warning<
+  "cast between pointer-to-function and pointer-to-object is incompatible with C++98">,
+  InGroup<CXX98CompatPedantic>, DefaultIgnore;
 def err_bad_reinterpret_cast_small_int : Error<
   "cast from pointer to smaller type %2 loses information">;
 def err_bad_cxx_cast_vector_to_scalar_different_size : Error<
@@ -3708,6 +3742,10 @@
   "implicit conversion from array size expression of type %0 to "
   "%select{integral|enumeration}1 type %2 is a C++11 extension">,
   InGroup<CXX11>;
+def warn_cxx98_compat_array_size_conversion : Warning<
+  "implicit conversion from array size expression of type %0 to "
+  "%select{integral|enumeration}1 type %2 is incompatible with C++98">,
+  InGroup<CXX98CompatPedantic>, DefaultIgnore;
 def err_address_space_qualified_new : Error<
   "'new' cannot allocate objects of type %0 in address space '%1'">;
 def err_address_space_qualified_delete : Error<
@@ -4083,6 +4121,10 @@
   "cannot pass object of %select{non-POD|non-trivial}0 type %1 through variadic"
   " %select{function|block|method|constructor}2; call will abort at runtime">,
   InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
+def warn_cxx98_compat_pass_non_pod_arg_to_vararg : Warning<
+  "passing object of trivial but non-POD type %0 through variadic"
+  " %select{function|block|method|constructor}1 is incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 def err_typecheck_call_invalid_ordered_compare : Error<
   "ordered compare requires two args of floating point type (%0 and %1)">;
@@ -4413,8 +4455,11 @@
   "use of unary operator that may be intended as compound assignment (%0=)">;
 
 // C++11 explicit conversion operators
-def warn_explicit_conversion_functions : Warning<
+def ext_explicit_conversion_functions : ExtWarn<
   "explicit conversion functions are a C++11 extension">, InGroup<CXX11>;
+def warn_cxx98_compat_explicit_conversion_functions : Warning<
+  "explicit conversion functions are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 // C++11 defaulted functions
 def err_defaulted_default_ctor_params : Error<

Modified: cfe/trunk/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=142419&r1=142418&r2=142419&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCast.cpp Tue Oct 18 15:49:44 2011
@@ -1712,15 +1712,19 @@
     // casting the return value of dlsym() and GetProcAddress().
     // FIXME: Conditionally-supported behavior should be configurable in the
     // TargetInfo or similar.
-    if (!Self.getLangOptions().CPlusPlus0x)
-      Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange;
+    Self.Diag(OpRange.getBegin(),
+              Self.getLangOptions().CPlusPlus0x ?
+                diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
+      << OpRange;
     return TC_Success;
   }
 
   if (DestType->isFunctionPointerType()) {
     // See above.
-    if (!Self.getLangOptions().CPlusPlus0x)
-      Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange;
+    Self.Diag(OpRange.getBegin(),
+              Self.getLangOptions().CPlusPlus0x ?
+                diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
+      << OpRange;
     return TC_Success;
   }
   

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=142419&r1=142418&r2=142419&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Oct 18 15:49:44 2011
@@ -2127,8 +2127,9 @@
                                  CXXRecordDecl *ClassDecl) {
   SourceLocation Loc = TInfo->getTypeLoc().getLocalSourceRange().getBegin();
   if (!LangOpts.CPlusPlus0x)
-    return Diag(Loc, diag::err_delegation_0x_only)
+    return Diag(Loc, diag::err_delegating_ctor)
       << TInfo->getTypeLoc().getLocalSourceRange();
+  Diag(Loc, diag::warn_cxx98_compat_delegating_ctor);
 
   // Initialize the object.
   InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
@@ -5342,9 +5343,11 @@
     R = Context.getFunctionType(ConvType, 0, 0, Proto->getExtProtoInfo());
 
   // C++0x explicit conversion operators.
-  if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x)
+  if (D.getDeclSpec().isExplicitSpecified())
     Diag(D.getDeclSpec().getExplicitSpecLoc(),
-         diag::warn_explicit_conversion_functions)
+         getLangOptions().CPlusPlus0x ?
+           diag::warn_cxx98_compat_explicit_conversion_functions :
+           diag::ext_explicit_conversion_functions)
       << SourceRange(D.getDeclSpec().getExplicitSpecLoc());
 }
 
@@ -5791,10 +5794,14 @@
   case UnqualifiedId::IK_ConstructorName:
   case UnqualifiedId::IK_ConstructorTemplateId:
     // C++0x inherited constructors.
+    Diag(Name.getSourceRange().getBegin(),
+         getLangOptions().CPlusPlus0x ?
+           diag::warn_cxx98_compat_using_decl_constructor :
+           diag::err_using_decl_constructor)
+      << SS.getRange();
+
     if (getLangOptions().CPlusPlus0x) break;
 
-    Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_constructor)
-      << SS.getRange();
     return 0;
       
   case UnqualifiedId::IK_DestructorName:
@@ -7432,7 +7439,7 @@
                             &HasConstCopyAssignment);
   }
 
-  // In C++0x, the above citation has "or virtual added"
+  // In C++11, the above citation has "or virtual" added
   if (LangOpts.CPlusPlus0x) {
     for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
                                          BaseEnd = ClassDecl->vbases_end();
@@ -9996,12 +10003,14 @@
 
     // C++ [class.friend]p1: A friend of a class is a function or
     //   class that is not a member of the class . . .
-    // C++0x changes this for both friend types and functions.
+    // C++11 changes this for both friend types and functions.
     // Most C++ 98 compilers do seem to give an error here, so
     // we do, too.
-    if (!Previous.empty() && DC->Equals(CurContext)
-        && !getLangOptions().CPlusPlus0x)
-      Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
+    if (!Previous.empty() && DC->Equals(CurContext))
+      Diag(DS.getFriendSpecLoc(),
+           getLangOptions().CPlusPlus0x ?
+             diag::warn_cxx98_compat_friend_is_member :
+             diag::err_friend_is_member);
 
     DCScope = getScopeForDeclContext(S, DC);
 
@@ -10045,8 +10054,11 @@
 
     // C++ [class.friend]p1: A friend of a class is a function or
     //   class that is not a member of the class . . .
-    if (DC->Equals(CurContext) && !getLangOptions().CPlusPlus0x)
-      Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
+    if (DC->Equals(CurContext))
+      Diag(DS.getFriendSpecLoc(),
+           getLangOptions().CPlusPlus0x ?
+             diag::warn_cxx98_compat_friend_is_member :
+             diag::err_friend_is_member);
     
     if (D.isFunctionDefinition()) {
       // C++ [class.friend]p6:

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=142419&r1=142418&r2=142419&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Oct 18 15:49:44 2011
@@ -562,8 +562,12 @@
       if (CXXRecordDecl *Record = E->getType()->getAsCXXRecordDecl()) {
         if (Record->hasTrivialCopyConstructor() &&
             Record->hasTrivialMoveConstructor() &&
-            Record->hasTrivialDestructor())
+            Record->hasTrivialDestructor()) {
+          DiagRuntimeBehavior(E->getLocStart(), 0,
+            PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg)
+              << E->getType() << CT);
           TrivialEnough = true;
+        }
       }
     }
 
@@ -2643,9 +2647,10 @@
     QualType Ty;
 
     // long long is a C99 feature.
-    if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x &&
-        Literal.isLongLong)
-      Diag(Tok.getLocation(), diag::ext_longlong);
+    if (!getLangOptions().C99 && Literal.isLongLong)
+      Diag(Tok.getLocation(),
+           getLangOptions().CPlusPlus0x ?
+             diag::warn_cxx98_compat_longlong : diag::ext_longlong);
 
     // Get the value in the widest-possible width.
     llvm::APInt ResultVal(Context.getTargetInfo().getIntMaxTWidth(), 0);

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=142419&r1=142418&r2=142419&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Oct 18 15:49:44 2011
@@ -963,17 +963,18 @@
 
     QualType SizeType = ArraySize->getType();
 
-    ExprResult ConvertedSize
-      = ConvertToIntegralOrEnumerationType(StartLoc, ArraySize,
-                                       PDiag(diag::err_array_size_not_integral),
-                                     PDiag(diag::err_array_size_incomplete_type)
-                                       << ArraySize->getSourceRange(),
-                               PDiag(diag::err_array_size_explicit_conversion),
-                                       PDiag(diag::note_array_size_conversion),
-                               PDiag(diag::err_array_size_ambiguous_conversion),
-                                       PDiag(diag::note_array_size_conversion),
-                          PDiag(getLangOptions().CPlusPlus0x? 0
-                                            : diag::ext_array_size_conversion));
+    ExprResult ConvertedSize = ConvertToIntegralOrEnumerationType(
+      StartLoc, ArraySize,
+      PDiag(diag::err_array_size_not_integral),
+      PDiag(diag::err_array_size_incomplete_type)
+        << ArraySize->getSourceRange(),
+      PDiag(diag::err_array_size_explicit_conversion),
+      PDiag(diag::note_array_size_conversion),
+      PDiag(diag::err_array_size_ambiguous_conversion),
+      PDiag(diag::note_array_size_conversion),
+      PDiag(getLangOptions().CPlusPlus0x ?
+              diag::warn_cxx98_compat_array_size_conversion :
+              diag::ext_array_size_conversion));
     if (ConvertedSize.isInvalid())
       return ExprError();
 

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=142419&r1=142418&r2=142419&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Oct 18 15:49:44 2011
@@ -1103,10 +1103,10 @@
     //   template-argument, that declaration shall be a definition and shall be
     //   the only declaration of the function template in the translation unit.
     // (C++98/03 doesn't have this wording; see DR226).
-    if (!S.getLangOptions().CPlusPlus0x)
-      S.Diag(ParamLoc,
-             diag::ext_template_parameter_default_in_function_template)
-        << DefArgRange;
+    S.Diag(ParamLoc, S.getLangOptions().CPlusPlus0x ?
+         diag::warn_cxx98_compat_template_parameter_default_in_function_template
+           : diag::ext_template_parameter_default_in_function_template)
+      << DefArgRange;
     return false;
 
   case Sema::TPC_ClassTemplateMember:
@@ -2268,9 +2268,11 @@
                                                   ParsedType ObjectType,
                                                   bool EnteringContext,
                                                   TemplateTy &Result) {
-  if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() &&
-      !getLangOptions().CPlusPlus0x)
-    Diag(TemplateKWLoc, diag::ext_template_outside_of_template)
+  if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent())
+    Diag(TemplateKWLoc,
+         getLangOptions().CPlusPlus0x ?
+           diag::warn_cxx98_compat_template_outside_of_template :
+           diag::ext_template_outside_of_template)
       << FixItHint::CreateRemoval(TemplateKWLoc);
 
   DeclContext *LookupCtx = 0;
@@ -3261,13 +3263,19 @@
 
 bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) {
   if (Tag->getDeclContext()->isFunctionOrMethod()) {
-    S.Diag(SR.getBegin(), diag::ext_template_arg_local_type)
+    S.Diag(SR.getBegin(),
+           S.getLangOptions().CPlusPlus0x ?
+             diag::warn_cxx98_compat_template_arg_local_type :
+             diag::ext_template_arg_local_type)
       << S.Context.getTypeDeclType(Tag) << SR;
     return true;
   }
 
   if (!Tag->getDeclName() && !Tag->getTypedefNameForAnonDecl()) {
-    S.Diag(SR.getBegin(), diag::ext_template_arg_unnamed_type) << SR;
+    S.Diag(SR.getBegin(),
+           S.getLangOptions().CPlusPlus0x ?
+             diag::warn_cxx98_compat_template_arg_unnamed_type :
+             diag::ext_template_arg_unnamed_type) << SR;
     S.Diag(Tag->getLocation(), diag::note_template_unnamed_type_here);
     return true;
   }
@@ -3317,9 +3325,14 @@
   //   compounded from any of these types shall not be used as a
   //   template-argument for a template type-parameter.
   //
-  // C++0x allows these, and even in C++03 we allow them as an extension with
+  // C++11 allows these, and even in C++03 we allow them as an extension with
   // a warning.
-  if (!LangOpts.CPlusPlus0x && Arg->hasUnnamedOrLocalType()) {
+  if (LangOpts.CPlusPlus0x ?
+     Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_unnamed_type,
+                              SR.getBegin()) != DiagnosticsEngine::Ignored ||
+      Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_local_type,
+                               SR.getBegin()) != DiagnosticsEngine::Ignored :
+      Arg->hasUnnamedOrLocalType()) {
     UnnamedLocalNoLinkageFinder Finder(*this, SR);
     (void)Finder.Visit(Context.getCanonicalType(Arg));
   }
@@ -3358,9 +3371,11 @@
   // See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
   bool ExtraParens = false;
   while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
-    if (!Invalid && !ExtraParens && !S.getLangOptions().CPlusPlus0x) {
+    if (!Invalid && !ExtraParens) {
       S.Diag(Arg->getSourceRange().getBegin(),
-             diag::ext_template_arg_extra_parens)
+             S.getLangOptions().CPlusPlus0x ?
+               diag::warn_cxx98_compat_template_arg_extra_parens :
+               diag::ext_template_arg_extra_parens)
         << Arg->getSourceRange();
       ExtraParens = true;
     }
@@ -3623,9 +3638,11 @@
   // See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
   bool ExtraParens = false;
   while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
-    if (!Invalid && !ExtraParens && !getLangOptions().CPlusPlus0x) {
+    if (!Invalid && !ExtraParens) {
       Diag(Arg->getSourceRange().getBegin(),
-           diag::ext_template_arg_extra_parens)
+           getLangOptions().CPlusPlus0x ?
+             diag::warn_cxx98_compat_template_arg_extra_parens :
+             diag::ext_template_arg_extra_parens)
         << Arg->getSourceRange();
       ExtraParens = true;
     }
@@ -4571,24 +4588,28 @@
     // C++0x [temp.expl.spec]p2:
     //   An explicit specialization shall be declared in a namespace enclosing
     //   the specialized template.
-    if (!DC->InEnclosingNamespaceSetOf(SpecializedContext) &&
-        !(S.getLangOptions().CPlusPlus0x && DC->Encloses(SpecializedContext))) {
-      bool IsCPlusPlus0xExtension
-        = !S.getLangOptions().CPlusPlus0x && DC->Encloses(SpecializedContext);
-      if (isa<TranslationUnitDecl>(SpecializedContext))
-        S.Diag(Loc, IsCPlusPlus0xExtension
-                      ? diag::ext_template_spec_decl_out_of_scope_global
-                      : diag::err_template_spec_decl_out_of_scope_global)
+    if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) {
+      bool IsCPlusPlus0xExtension = DC->Encloses(SpecializedContext);
+      if (isa<TranslationUnitDecl>(SpecializedContext)) {
+        assert(!IsCPlusPlus0xExtension &&
+               "DC encloses TU but isn't in enclosing namespace set");
+        S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
           << EntityKind << Specialized;
-      else if (isa<NamespaceDecl>(SpecializedContext))
-        S.Diag(Loc, IsCPlusPlus0xExtension
-                      ? diag::ext_template_spec_decl_out_of_scope
-                      : diag::err_template_spec_decl_out_of_scope)
-          << EntityKind << Specialized
-          << cast<NamedDecl>(SpecializedContext);
+      } else if (isa<NamespaceDecl>(SpecializedContext)) {
+        int Diag;
+        if (!IsCPlusPlus0xExtension)
+          Diag = diag::err_template_spec_decl_out_of_scope;
+        else if (!S.getLangOptions().CPlusPlus0x)
+          Diag = diag::ext_template_spec_decl_out_of_scope;
+        else
+          Diag = diag::warn_cxx98_compat_template_spec_decl_out_of_scope;
+        S.Diag(Loc, Diag)
+          << EntityKind << Specialized << cast<NamedDecl>(SpecializedContext);
+      }
 
       S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
-      ComplainedAboutScope = true;
+      ComplainedAboutScope =
+        !(IsCPlusPlus0xExtension && S.getLangOptions().CPlusPlus0x);
     }
   }
 
@@ -5333,12 +5354,12 @@
       // In C++98/03 mode, we only give an extension warning here, because it
       // is not harmful to try to explicitly instantiate something that
       // has been explicitly specialized.
-      if (!getLangOptions().CPlusPlus0x) {
-        Diag(NewLoc, diag::ext_explicit_instantiation_after_specialization)
-          << PrevDecl;
-        Diag(PrevDecl->getLocation(),
-             diag::note_previous_template_specialization);
-      }
+      Diag(NewLoc, getLangOptions().CPlusPlus0x ?
+           diag::warn_cxx98_compat_explicit_instantiation_after_specialization :
+           diag::ext_explicit_instantiation_after_specialization)
+        << PrevDecl;
+      Diag(PrevDecl->getLocation(),
+           diag::note_previous_template_specialization);
       HasNoEffect = true;
       return false;
 
@@ -6413,9 +6434,11 @@
   if (SS.isInvalid())
     return true;
   
-  if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
-      !getLangOptions().CPlusPlus0x)
-    Diag(TypenameLoc, diag::ext_typename_outside_of_template)
+  if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
+    Diag(TypenameLoc,
+         getLangOptions().CPlusPlus0x ?
+           diag::warn_cxx98_compat_typename_outside_of_template :
+           diag::ext_typename_outside_of_template)
       << FixItHint::CreateRemoval(TypenameLoc);
 
   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
@@ -6449,10 +6472,12 @@
                         SourceLocation LAngleLoc,
                         ASTTemplateArgsPtr TemplateArgsIn,
                         SourceLocation RAngleLoc) {
-  if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
-      !getLangOptions().CPlusPlus0x)
-    Diag(TypenameLoc, diag::ext_typename_outside_of_template)
-    << FixItHint::CreateRemoval(TypenameLoc);
+  if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
+    Diag(TypenameLoc,
+         getLangOptions().CPlusPlus0x ?
+           diag::warn_cxx98_compat_typename_outside_of_template :
+           diag::ext_typename_outside_of_template)
+      << FixItHint::CreateRemoval(TypenameLoc);
   
   // Translate the parser's template argument list in our AST format.
   TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=142419&r1=142418&r2=142419&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Oct 18 15:49:44 2011
@@ -689,9 +689,10 @@
         Result = Context.LongLongTy;
           
         // long long is a C99 feature.
-        if (!S.getLangOptions().C99 &&
-            !S.getLangOptions().CPlusPlus0x)
-          S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_longlong);
+        if (!S.getLangOptions().C99)
+          S.Diag(DS.getTypeSpecWidthLoc(),
+                 S.getLangOptions().CPlusPlus0x ?
+                   diag::warn_cxx98_compat_longlong : diag::ext_longlong);
         break;
       }
     } else {
@@ -703,9 +704,10 @@
         Result = Context.UnsignedLongLongTy;
           
         // long long is a C99 feature.
-        if (!S.getLangOptions().C99 &&
-            !S.getLangOptions().CPlusPlus0x)
-          S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_longlong);
+        if (!S.getLangOptions().C99)
+          S.Diag(DS.getTypeSpecWidthLoc(),
+                 S.getLangOptions().CPlusPlus0x ?
+                   diag::warn_cxx98_compat_longlong : diag::ext_longlong);
         break;
       }
     }

Modified: cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp?rev=142419&r1=142418&r2=142419&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp Tue Oct 18 15:49:44 2011
@@ -16,3 +16,16 @@
 enum Enum {
   Enum_value, // expected-warning {{commas at the end of enumerator lists are incompatible with C++98}}
 };
+
+template<typename T> struct InstantiationAfterSpecialization {};
+template<> struct InstantiationAfterSpecialization<int> {}; // expected-note {{here}}
+template struct InstantiationAfterSpecialization<int>; // expected-warning {{explicit instantiation of 'InstantiationAfterSpecialization<int>' that occurs after an explicit specialization is incompatible with C++98}}
+
+void *dlsym();
+void (*FnPtr)() = (void(*)())dlsym(); // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}}
+void *FnVoidPtr = (void*)&dlsym; // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}}
+
+struct ConvertToInt {
+  operator int();
+};
+int *ArraySizeConversion = new int[ConvertToInt()]; // expected-warning {{implicit conversion from array size expression of type 'ConvertToInt' to integral type 'int' is incompatible with C++98}}

Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=142419&r1=142418&r2=142419&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Tue Oct 18 15:49:44 2011
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s
 
 template<typename ...T>  // expected-warning {{variadic templates are incompatible with C++98}}
 class Variadic1 {};
@@ -85,7 +86,7 @@
 using AliasDecl = int; // expected-warning {{alias declarations are incompatible with C++98}}
 template<typename T> using AliasTemplate = T; // expected-warning {{alias declarations are incompatible with C++98}}
 
-inline namespace N { // expected-warning {{inline namespaces are incompatible with C++98}}
+inline namespace InlineNS { // expected-warning {{inline namespaces are incompatible with C++98}}
 }
 
 auto auto_deduction = 0; // expected-warning {{'auto' type specifier is incompatible with C++98}}
@@ -100,3 +101,62 @@
 bool no_except_expr = noexcept(1 + 1); // expected-warning {{noexcept expressions are incompatible with C++98}}
 void *null = nullptr; // expected-warning {{'nullptr' is incompatible with C++98}}
 static_assert(true, "!"); // expected-warning {{static_assert declarations are incompatible with C++98}}
+
+struct InhCtorBase {
+  InhCtorBase(int);
+};
+struct InhCtorDerived : InhCtorBase {
+  using InhCtorBase::InhCtorBase; // expected-warning {{inherited constructors are incompatible with C++98}}
+};
+
+struct FriendMember {
+  static void MemberFn();
+  friend void FriendMember::MemberFn(); // expected-warning {{friend declaration naming a member of the declaring class is incompatible with C++98}}
+};
+
+struct DelegCtor {
+  DelegCtor(int) : DelegCtor() {} // expected-warning {{delegating constructors are incompatible with C++98}}
+  DelegCtor();
+};
+
+template<int n = 0> void DefaultFuncTemplateArg(); // expected-warning {{default template arguments for a function template are incompatible with C++98}}
+
+template<typename T> 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 RedundantParensInAddressTemplateParam {
+  int n;
+  template<int*p> struct S {};
+  S<(&n)> s; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}}
+  S<(((&n)))> t; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}}
+}
+
+namespace TemplateSpecOutOfScopeNs {
+  template<typename T> struct S {}; // expected-note {{here}}
+}
+template<> struct TemplateSpecOutOfScopeNs::S<char> {}; // expected-warning {{class template specialization of 'S' outside namespace 'TemplateSpecOutOfScopeNs' is incompatible with C++98}}
+
+struct Typename {
+  template<typename T> struct Inner {};
+};
+typename ::Typename TypenameOutsideTemplate(); // expected-warning {{use of 'typename' outside of a template is incompatible with C++98}}
+Typename::template Inner<int> TemplateOutsideTemplate(); // expected-warning {{use of 'template' keyword outside of a template is incompatible with C++98}}
+
+struct TrivialButNonPOD {
+  int f(int);
+private:
+  int k;
+};
+void Ellipsis(int n, ...);
+void TrivialButNonPODThroughEllipsis() {
+  Ellipsis(1, TrivialButNonPOD()); // expected-warning {{passing object of trivial but non-POD type 'TrivialButNonPOD' through variadic function is incompatible with C++98}}
+}
+
+struct HasExplicitConversion {
+  explicit operator bool(); // expected-warning {{explicit conversion functions are incompatible with C++98}}
+};





More information about the cfe-commits mailing list