Skip to content

Commit

Permalink
Add missing -Wc++11-compat / -Wc++14-compat warnings for:
Browse files Browse the repository at this point in the history
 * 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
  • Loading branch information
zygoloid committed Aug 30, 2018
1 parent 8cee2e9 commit dbbd7fa
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 17 deletions.
13 changes: 12 additions & 1 deletion include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand All @@ -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<
Expand Down Expand Up @@ -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">,
Expand Down
4 changes: 4 additions & 0 deletions lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
36 changes: 25 additions & 11 deletions lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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.
}
}

Expand Down
26 changes: 22 additions & 4 deletions test/SemaCXX/cxx0x-compat.cpp → test/SemaCXX/cxx11-compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion test/SemaCXX/cxx98-compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit dbbd7fa

Please sign in to comment.