From 5b013f5050681682a26c51539d629c27280725c3 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 28 Sep 2013 05:38:27 +0000 Subject: [PATCH] Add compat/extension warnings for init captures. llvm-svn: 191609 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++++ clang/lib/Sema/SemaLambda.cpp | 4 ++++ .../test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp | 2 +- .../test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp | 2 +- clang/test/PCH/cxx11-lambdas.mm | 4 ++-- clang/test/Parser/cxx0x-lambda-expressions.cpp | 12 ++++++------ clang/test/Parser/objcxx0x-lambda-expressions.mm | 2 +- clang/test/SemaCXX/cxx0x-compat.cpp | 9 +++++++++ 8 files changed, 29 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3746252833a9..2dd7ea7c01d1 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5069,6 +5069,11 @@ let CategoryName = "Lambda Issue" in { "here">; // C++1y lambda init-captures. + def warn_cxx11_compat_init_capture : Warning< + "initialized lambda captures are incompatible with C++ standards " + "before C++1y">, InGroup, DefaultIgnore; + def ext_init_capture : ExtWarn< + "initialized lambda captures are a C++1y extension">, InGroup; def err_init_capture_no_expression : Error< "initializer missing for lambda capture %0">; def err_init_capture_multiple_expressions : Error< diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index a87c903d3bce..fa46a282991c 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -703,6 +703,10 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, VarDecl *Var; if (C->Init.isUsable()) { + Diag(C->Loc, getLangOpts().CPlusPlus1y + ? diag::warn_cxx11_compat_init_capture + : diag::ext_init_capture); + if (C->Init.get()->containsUnexpandedParameterPack()) ContainsUnexpandedParameterPack = true; diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp index 083ca1bdd377..4ae34dec3e34 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wno-c++1y-extensions // RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify void print(); diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp index 408fb75f8093..b9b8cd76c011 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 %s -verify +// RUN: %clang_cc1 -std=c++11 %s -verify -Wno-c++1y-extensions class X0 { void explicit_capture() { diff --git a/clang/test/PCH/cxx11-lambdas.mm b/clang/test/PCH/cxx11-lambdas.mm index 807bf2306794..c4550517bb1e 100644 --- a/clang/test/PCH/cxx11-lambdas.mm +++ b/clang/test/PCH/cxx11-lambdas.mm @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -pedantic-errors -fblocks -std=c++11 -emit-pch %s -o %t-cxx11 -// RUN: %clang_cc1 -ast-print -pedantic-errors -fblocks -std=c++11 -include-pch %t-cxx11 %s | FileCheck -check-prefix=CHECK-PRINT %s +// RUN: %clang_cc1 -pedantic-errors -fblocks -std=c++1y -emit-pch %s -o %t-cxx11 +// RUN: %clang_cc1 -ast-print -pedantic-errors -fblocks -std=c++1y -include-pch %t-cxx11 %s | FileCheck -check-prefix=CHECK-PRINT %s #ifndef HEADER_INCLUDED diff --git a/clang/test/Parser/cxx0x-lambda-expressions.cpp b/clang/test/Parser/cxx0x-lambda-expressions.cpp index 426e530251ff..289d03c223b3 100644 --- a/clang/test/Parser/cxx0x-lambda-expressions.cpp +++ b/clang/test/Parser/cxx0x-lambda-expressions.cpp @@ -52,14 +52,14 @@ class C { // We support init-captures in C++11 as an extension. int z; void init_capture() { - [n(0)] () mutable -> int { return ++n; }; - [n{0}] { return; }; // expected-error {{}} - [n = 0] { return ++n; }; // expected-error {{captured by copy in a non-mutable}} - [n = {0}] { return; }; // expected-error {{}} - [a([&b = z]{})](){}; + [n(0)] () mutable -> int { return ++n; }; // expected-warning{{extension}} + [n{0}] { return; }; // expected-error {{}} expected-warning{{extension}} + [n = 0] { return ++n; }; // expected-error {{captured by copy in a non-mutable}} expected-warning{{extension}} + [n = {0}] { return; }; // expected-error {{}} expected-warning{{extension}} + [a([&b = z]{})](){}; // expected-warning 2{{extension}} int x = 4; - auto y = [&r = x, x = x + 1]() -> int { + auto y = [&r = x, x = x + 1]() -> int { // expected-warning 2{{extension}} r += 2; return x + 2; } (); diff --git a/clang/test/Parser/objcxx0x-lambda-expressions.mm b/clang/test/Parser/objcxx0x-lambda-expressions.mm index 905bd6b1e8b4..bef576a9d204 100644 --- a/clang/test/Parser/objcxx0x-lambda-expressions.mm +++ b/clang/test/Parser/objcxx0x-lambda-expressions.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -Wno-c++1y-extensions -std=c++11 %s class C { id get(int); diff --git a/clang/test/SemaCXX/cxx0x-compat.cpp b/clang/test/SemaCXX/cxx0x-compat.cpp index 123008aadd81..ffbd20fda373 100644 --- a/clang/test/SemaCXX/cxx0x-compat.cpp +++ b/clang/test/SemaCXX/cxx0x-compat.cpp @@ -1,4 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++11-compat -verify %s + +#if __cplusplus < 201103L namespace N { template void f(T) {} // expected-note 2{{here}} @@ -37,3 +40,9 @@ void h(size_t foo, size_t bar) { #define _x + 1 char c = 'x'_x; // expected-warning {{will be treated as a user-defined literal suffix}} + +#else + +auto init_capture = [a(0)] {}; // expected-warning {{initialized lambda captures are incompatible with C++ standards before C++1y}} + +#endif