<div dir="ltr">Hi Hans,<div><br></div><div>I'd really like to ship this change as part of Clang 3.6: there's an upcoming change to our behavior that will cause us to reject or differently interpret some code in C++11 and C++14 modes, and this patch adds a warning for the affected cases with a fix-it hint.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 10, 2015 at 6:41 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Tue Feb 10 20:41:33 2015<br>
New Revision: 228792<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=228792&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=228792&view=rev</a><br>
Log:<br>
Add a warning for direct-list-initialization of a variable with a deduced type<br>
(or of a lambda init-capture, which is sort-of such a variable). The semantics<br>
of such constructs will change when we implement N3922, so we intend to warn on<br>
this in Clang 3.6 then change the semantics in Clang 3.7.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Parse/ParseExprCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp<br>
    cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp<br>
    cfe/trunk/test/Parser/<a href="http://objcxx0x-lambda-expressions.mm" target="_blank">objcxx0x-lambda-expressions.mm</a><br>
    cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=228792&r1=228791&r2=228792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=228792&r1=228791&r2=228792&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Feb 10 20:41:33 2015<br>
@@ -750,3 +750,6 @@ def SerializedDiagnostics : DiagGroup<"s<br>
 // A warning group for warnings about code that clang accepts when<br>
 // compiling CUDA C/C++ but which is not compatible with the CUDA spec.<br>
 def CudaCompat : DiagGroup<"cuda-compat">;<br>
+<br>
+// A warning group for things that will change semantics in the future.<br>
+def FutureCompat : DiagGroup<"future-compat">;<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=228792&r1=228791&r2=228792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=228792&r1=228791&r2=228792&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Feb 10 20:41:33 2015<br>
@@ -804,6 +804,10 @@ def warn_cxx98_compat_lambda : Warning<<br>
 def err_lambda_missing_parens : Error<<br>
   "lambda requires '()' before %select{'mutable'|return type|"<br>
   "attribute specifier}0">;<br>
+def warn_init_capture_direct_list_init : Warning<<br>
+  "direct list initialization of a lambda init-capture will change meaning in "<br>
+  "a future version of Clang; insert an '=' to avoid a change in behavior">,<br>
+  InGroup<FutureCompat>;<br>
<br>
 // Availability attribute<br>
 def err_expected_version : Error<<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=228792&r1=228791&r2=228792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=228792&r1=228791&r2=228792&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb 10 20:41:33 2015<br>
@@ -1645,6 +1645,10 @@ def err_auto_var_init_multiple_expressio<br>
 def err_auto_var_init_paren_braces : Error<<br>
   "cannot deduce type for variable %0 with type %1 from "<br>
   "parenthesized initializer list">;<br>
+def warn_auto_var_direct_list_init : Warning<<br>
+  "direct list initialization of a variable with a deduced type will change "<br>
+  "meaning in a future version of Clang; insert an '=' to avoid a change in "<br>
+  "behavior">, InGroup<FutureCompat>;<br>
 def err_auto_new_ctor_multiple_expressions : Error<<br>
   "new expression for type %0 contains multiple constructor arguments">;<br>
 def err_auto_missing_trailing_return : Error<<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=228792&r1=228791&r2=228792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=228792&r1=228791&r2=228792&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Feb 10 20:41:33 2015<br>
@@ -894,11 +894,16 @@ Optional<unsigned> Parser::ParseLambdaIn<br>
         // to save the necessary state, and restore it later.<br>
         EnterExpressionEvaluationContext EC(Actions,<br>
                                             Sema::PotentiallyEvaluated);<br>
-        TryConsumeToken(tok::equal);<br>
+        bool HadEquals = TryConsumeToken(tok::equal);<br>
<br>
-        if (!SkippedInits)<br>
+        if (!SkippedInits) {<br>
+          // Warn on constructs that will change meaning when we implement N3922<br>
+          if (!HadEquals && Tok.is(tok::l_brace)) {<br>
+            Diag(Tok, diag::warn_init_capture_direct_list_init)<br>
+              << FixItHint::CreateInsertion(Tok.getLocation(), "=");<br>
+          }<br>
           Init = ParseInitializer();<br>
-        else if (Tok.is(tok::l_brace)) {<br>
+        } else if (Tok.is(tok::l_brace)) {<br>
           BalancedDelimiterTracker Braces(*this, tok::l_brace);<br>
           Braces.consumeOpen();<br>
           Braces.skipToEnd();<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=228792&r1=228791&r2=228792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=228792&r1=228791&r2=228792&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Feb 10 20:41:33 2015<br>
@@ -8716,6 +8716,14 @@ void Sema::AddInitializerToDecl(Decl *Re<br>
     CheckVariableDeclarationType(VDecl);<br>
     if (VDecl->isInvalidDecl())<br>
       return;<br>
+<br>
+    // If all looks well, warn if this is a case that will change meaning when<br>
+    // we implement N3922.<br>
+    if (DirectInit && !CXXDirectInit && isa<InitListExpr>(Init)) {<br>
+      Diag(Init->getLocStart(),<br>
+           diag::warn_auto_var_direct_list_init)<br>
+        << FixItHint::CreateInsertion(Init->getLocStart(), "=");<br>
+    }<br>
   }<br>
<br>
   // dllimport cannot be used on variable definitions.<br>
<br>
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp?rev=228792&r1=228791&r2=228792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp?rev=228792&r1=228791&r2=228792&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp (original)<br>
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp Tue Feb 10 20:41:33 2015<br>
@@ -48,7 +48,7 @@ auto bad_init_2 = [a(1, 2)] {}; // expec<br>
 auto bad_init_3 = [&a(void_fn())] {}; // expected-error {{cannot form a reference to 'void'}}<br>
 auto bad_init_4 = [a(void_fn())] {}; // expected-error {{has incomplete type 'void'}}<br>
 auto bad_init_5 = [a(overload_fn)] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer of type '<overloaded function}}<br>
-auto bad_init_6 = [a{overload_fn}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer list}}<br>
+auto bad_init_6 = [a{overload_fn}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer list}} expected-warning {{will change meaning in a future version of Clang}}<br>
<br>
 template<typename...T> void pack_1(T...t) { (void)[a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}}<br>
 template void pack_1<>(); // expected-note {{instantiation of}}<br>
@@ -61,7 +61,7 @@ auto a = [a(4), b = 5, &c = static_cast<<br>
   using T = decltype(c);<br>
   using T = const int &;<br>
 };<br>
-auto b = [a{0}] {}; // expected-error {{include <initializer_list>}}<br>
+auto b = [a{0}] {}; // expected-error {{include <initializer_list>}} expected-warning {{will change meaning in a future version of Clang}}<br>
<br>
 struct S { S(); S(S&&); };<br>
 template<typename T> struct remove_reference { typedef T type; };<br>
<br>
Modified: cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp?rev=228792&r1=228791&r2=228792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp?rev=228792&r1=228791&r2=228792&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp (original)<br>
+++ cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp Tue Feb 10 20:41:33 2015<br>
@@ -61,7 +61,7 @@ class C {<br>
   int z;<br>
   void init_capture() {<br>
     [n(0)] () mutable -> int { return ++n; }; // expected-warning{{extension}}<br>
-    [n{0}] { return; }; // expected-error {{<initializer_list>}} expected-warning{{extension}}<br>
+    [n{0}] { return; }; // expected-error {{<initializer_list>}} expected-warning{{extension}} expected-warning{{will change meaning in a future version}}<br>
     [n = 0] { return ++n; }; // expected-error {{captured by copy in a non-mutable}} expected-warning{{extension}}<br>
     [n = {0}] { return; }; // expected-error {{<initializer_list>}} expected-warning{{extension}}<br>
     [a([&b = z]{})](){}; // expected-warning 2{{extension}}<br>
<br>
Modified: cfe/trunk/test/Parser/<a href="http://objcxx0x-lambda-expressions.mm" target="_blank">objcxx0x-lambda-expressions.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm?rev=228792&r1=228791&r2=228792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx0x-lambda-expressions.mm?rev=228792&r1=228791&r2=228792&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/<a href="http://objcxx0x-lambda-expressions.mm" target="_blank">objcxx0x-lambda-expressions.mm</a> (original)<br>
+++ cfe/trunk/test/Parser/<a href="http://objcxx0x-lambda-expressions.mm" target="_blank">objcxx0x-lambda-expressions.mm</a> Tue Feb 10 20:41:33 2015<br>
@@ -21,7 +21,7 @@ class C {<br>
<br>
     [foo(bar)] () {};<br>
     [foo = bar] () {};<br>
-    [foo{bar}] () {}; // expected-error {{<initializer_list>}}<br>
+    [foo{bar}] () {}; // expected-error {{<initializer_list>}} expected-warning {{will change meaning}}<br>
     [foo = {bar}] () {}; // expected-error {{<initializer_list>}}<br>
<br>
     [foo(bar) baz] () {}; // expected-error {{called object type 'int' is not a function}}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=228792&r1=228791&r2=228792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=228792&r1=228791&r2=228792&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Tue Feb 10 20:41:33 2015<br>
@@ -117,6 +117,7 @@ void argument_deduction() {<br>
<br>
 void auto_deduction() {<br>
   auto l = {1, 2, 3, 4};<br>
+  auto l2 {1, 2, 3, 4}; // expected-warning {{will change meaning in a future version of Clang}}<br>
   static_assert(same_type<decltype(l), std::initializer_list<int>>::value, "");<br>
   auto bl = {1, 2.0}; // expected-error {{cannot deduce}}<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>