]> granicus.if.org Git - clang/commitdiff
Add missing -Wc++11-compat / -Wc++14-compat warnings for:
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 30 Aug 2018 19:16:35 +0000 (19:16 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 30 Aug 2018 19:16:35 +0000 (19:16 +0000)
 * generic lambdas
 * return type deduction
 * class template argument deduction

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@341098 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaInit.cpp
lib/Sema/SemaType.cpp
test/SemaCXX/cxx11-compat.cpp [moved from test/SemaCXX/cxx0x-compat.cpp with 68% similarity]
test/SemaCXX/cxx98-compat.cpp

index 2f1bd94614dcb421777d0f64b0bae5fb1d250192..3bee16c2d4d43ba0946fa0db66fc29862dbf9c54 100644 (file)
@@ -2143,8 +2143,11 @@ def note_deduction_guide_template_access : Note<
   "member template declared %0 here">;
 def note_deduction_guide_access : Note<
   "deduction guide declared %0 by intervening access specifier">;
+def warn_cxx14_compat_class_template_argument_deduction : Warning<
+  "class template argument deduction is incompatible with C++ standards "
+  "before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore;
 
-// C++1y deduced return types
+// C++14 deduced return types
 def err_auto_fn_deduction_failure : Error<
   "cannot deduce return type %0 from returned value of type %1">;
 def err_auto_fn_different_deductions : Error<
@@ -2160,6 +2163,9 @@ def err_auto_fn_return_init_list : Error<
   "cannot deduce return type from initializer list">;
 def err_auto_fn_virtual : Error<
   "function with deduced return type cannot be virtual">;
+def warn_cxx11_compat_deduced_return_type : Warning<
+  "return type deduction is incompatible with C++ standards before C++14">,
+  InGroup<CXXPre14Compat>, DefaultIgnore;
 
 // C++11 override control
 def override_keyword_only_allowed_on_virtual_member_functions : Error<
@@ -6576,6 +6582,11 @@ let CategoryName = "Lambda Issue" in {
   def err_init_capture_deduction_failure_from_init_list : Error<
     "cannot deduce type for lambda capture %0 from initializer list">;
 
+  // C++14 generic lambdas.
+  def warn_cxx11_compat_generic_lambda : Warning<
+    "generic lambdas are incompatible with C++11">,
+    InGroup<CXXPre14Compat>, DefaultIgnore;
+
   // C++17 '*this' captures.
   def warn_cxx14_compat_star_this_lambda_capture : Warning<
     "by value capture of '*this' is incompatible with C++ standards before C++17">,
index b95ad1054d74dffa351b7673d9d0a10c82b98617..634554e09645156ce07db9c57a93520894a5260a 100644 (file)
@@ -9062,6 +9062,10 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
     return QualType();
   }
 
+  Diag(TSInfo->getTypeLoc().getBeginLoc(),
+       diag::warn_cxx14_compat_class_template_argument_deduction)
+      << TSInfo->getTypeLoc().getSourceRange();
+
   // Can't deduce from dependent arguments.
   if (Expr::hasAnyTypeDependentArguments(Inits))
     return Context.DependentTy;
index a2153a2de967948fa9a282e5769f64467fb6d8c2..2f4d1826165b4e6520bd7d9e6dca99d6c4d51c04 100644 (file)
@@ -2887,6 +2887,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
     // class template argument deduction)?
     bool IsCXXAutoType =
         (Auto && Auto->getKeyword() != AutoTypeKeyword::GNUAutoType);
+    bool IsDeducedReturnType = false;
 
     switch (D.getContext()) {
     case DeclaratorContext::LambdaExprContext:
@@ -2978,10 +2979,12 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
     case DeclaratorContext::TrailingReturnVarContext:
       if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType)
         Error = 13; // Function return type
+      IsDeducedReturnType = true;
       break;
     case DeclaratorContext::ConversionIdContext:
       if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType)
         Error = 14; // conversion-type-id
+      IsDeducedReturnType = true;
       break;
     case DeclaratorContext::FunctionalCastContext:
       if (isa<DeducedTemplateSpecializationType>(Deduced))
@@ -3066,10 +3069,14 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
                D.getContext() != DeclaratorContext::LambdaExprContext) {
       // If there was a trailing return type, we already got
       // warn_cxx98_compat_trailing_return_type in the parser.
-      // If this was a lambda, we already warned on that too.
       SemaRef.Diag(AutoRange.getBegin(),
-                   diag::warn_cxx98_compat_auto_type_specifier)
-        << AutoRange;
+                   D.getContext() ==
+                           DeclaratorContext::LambdaExprParameterContext
+                       ? diag::warn_cxx11_compat_generic_lambda
+                       : IsDeducedReturnType
+                             ? diag::warn_cxx11_compat_deduced_return_type
+                             : diag::warn_cxx98_compat_auto_type_specifier)
+          << AutoRange;
     }
   }
 
@@ -4445,14 +4452,18 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
         // trailing-return-type is only required if we're declaring a function,
         // and not, for instance, a pointer to a function.
         if (D.getDeclSpec().hasAutoTypeSpec() &&
-            !FTI.hasTrailingReturnType() && chunkIndex == 0 &&
-            !S.getLangOpts().CPlusPlus14) {
-          S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
-                 D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto
-                     ? diag::err_auto_missing_trailing_return
-                     : diag::err_deduced_return_type);
-          T = Context.IntTy;
-          D.setInvalidType(true);
+            !FTI.hasTrailingReturnType() && chunkIndex == 0) {
+          if (!S.getLangOpts().CPlusPlus14) {
+            S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
+                   D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto
+                       ? diag::err_auto_missing_trailing_return
+                       : diag::err_deduced_return_type);
+            T = Context.IntTy;
+            D.setInvalidType(true);
+          } else {
+            S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
+                   diag::warn_cxx11_compat_deduced_return_type);
+          }
         } else if (FTI.hasTrailingReturnType()) {
           // T must be exactly 'auto' at this point. See CWG issue 681.
           if (isa<ParenType>(T)) {
@@ -4482,6 +4493,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
             T = Context.IntTy;
             D.setInvalidType(true);
           }
+        } else {
+          // This function type is not the type of the entity being declared,
+          // so checking the 'auto' is not the responsibility of this chunk.
         }
       }
 
similarity index 68%
rename from test/SemaCXX/cxx0x-compat.cpp
rename to test/SemaCXX/cxx11-compat.cpp
index b9ccadd85c2d746e9ddac2e2b2135249a6b49ca7..07cd6b1fcf93bc65298ca28a48c8cc0860793657 100644 (file)
@@ -47,12 +47,30 @@ template<int ...N> int f() { // expected-warning {{C++11 extension}}
 
 #else
 
+decltype(auto) x = 0; // expected-warning {{'decltype(auto)' type specifier is incompatible}}
+
 auto init_capture = [a(0)] {}; // expected-warning {{initialized lambda captures are incompatible with C++ standards before C++14}}
-static_assert(true); // expected-warning {{incompatible with C++ standards before C++17}}
 
-template<int ...N> int f() { return (N + ...); } // expected-warning {{incompatible with C++ standards before C++17}}
+auto generic_lambda =
+  [](
+       auto // expected-warning {{generic lambdas are incompatible}}
+    *a) {};
+
+auto deduced_return_type(); // expected-warning {{incompatible with C++ standards before C++14}}
+auto *another_deduced_return_type(); // expected-warning {{incompatible with C++ standards before C++14}}
+decltype(auto) also_deduced_return_type(); // expected-warning {{return type deduction}} expected-warning {{'decltype(auto)' type specifier is incompatible}}
+int f();
+auto (*not_deduced_return_type)() = f;
+
+auto deduced_lambda_return_type = []() ->
+  auto // expected-warning {{return type deduction is incompatible}}
+{};
+
+auto trailing_non_deduced_return_type() -> int;
+auto trailing_deduced_return_type() -> auto; // expected-warning {{incompatible with C++ standards before C++14}}
 
-namespace [[]] NS_with_attr {} // expected-warning {{incompatible with C++ standards before C++17}}
-enum { e [[]] }; // expected-warning {{incompatible with C++ standards before C++17}}
+struct A {
+  operator auto(); // expected-warning {{return type deduction is incompatible}}
+};
 
 #endif
index f814a06f13be064ec4685e584c3ce44aa66a17fd..885ab110ab1fa0937f62abed561db7189dfdf84d 100644 (file)
@@ -103,7 +103,8 @@ struct RefQualifier {
 
 auto f() -> int; // expected-warning {{trailing return types are incompatible with C++98}}
 #ifdef CXX14COMPAT
-auto ff() { return 5; } // expected-warning {{'auto' type specifier is incompatible with C++98}}
+auto ff() { return 5; } // expected-warning {{'auto' type specifier is incompatible with C++98}} 
+// expected-warning@-1 {{return type deduction is incompatible with C++ standards before C++14}}
 #endif
 
 void RangeFor() {