]> granicus.if.org Git - clang/commitdiff
DR1346: a parenthesized braced-init-list cannot be used as the initializer when
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 12 Mar 2014 17:42:45 +0000 (17:42 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 12 Mar 2014 17:42:45 +0000 (17:42 +0000)
performing auto type deduction.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaLambda.cpp
test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
test/CXX/drs/dr13xx.cpp [new file with mode: 0644]
test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
www/cxx_dr_status.html

index 4f93429a8406a1d63a9b154de2db9bfafc4dcd6b..49d1d676faf83397f3ddd230a5de97f65a32c698 100644 (file)
@@ -1538,12 +1538,15 @@ def err_auto_var_requires_init : Error<
   "declaration of variable %0 with type %1 requires an initializer">;
 def err_auto_new_requires_ctor_arg : Error<
   "new expression for type %0 requires a constructor argument">;
-def err_auto_new_requires_parens : Error<
+def err_auto_new_list_init : Error<
   "new expression for type %0 cannot use list-initialization">;
 def err_auto_var_init_no_expression : Error<
   "initializer for variable %0 with type %1 is empty">;
 def err_auto_var_init_multiple_expressions : Error<
   "initializer for variable %0 with type %1 contains multiple expressions">;
+def err_auto_var_init_paren_braces : Error<
+  "cannot deduce type for variable %0 with type %1 from "
+  "parenthesized initializer list">;
 def err_auto_new_ctor_multiple_expressions : Error<
   "new expression for type %0 contains multiple constructor arguments">;
 def err_auto_missing_trailing_return : Error<
@@ -5239,6 +5242,9 @@ let CategoryName = "Lambda Issue" in {
     "initializer missing for lambda capture %0">;
   def err_init_capture_multiple_expressions : Error<
     "initializer for lambda capture %0 contains multiple expressions">;
+  def err_init_capture_paren_braces : Error<
+    "cannot deduce type for lambda capture %0 from "
+    "parenthesized initializer list">;
   def err_init_capture_deduction_failure : Error<
     "cannot deduce type for lambda capture %0 from initializer of type %2">;
   def err_init_capture_deduction_failure_from_init_list : Error<
index 6419c7f584fb46113cb30a9a2f7828a5f57a62bb..521fc3f2cbc4b35c030e9ebd5ff8873c602be312 100644 (file)
@@ -8057,6 +8057,11 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
         return;
       } else {
         DeduceInit = CXXDirectInit->getExpr(0);
+        if (isa<InitListExpr>(DeduceInit))
+          Diag(CXXDirectInit->getLocStart(),
+               diag::err_auto_var_init_paren_braces)
+            << VDecl->getDeclName() << VDecl->getType()
+            << VDecl->getSourceRange();
       }
     }
 
index 3fa5de1a77fb26b5ce11888b938e6ce68173bcdd..8b9c0e2cc7d55304c76e7be24a0707cafe39eef9 100644 (file)
@@ -1188,14 +1188,15 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
   else if (Initializer && isa<ImplicitValueInitExpr>(Initializer))
     HaveCompleteInit = true;
 
-  // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
+  // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (TypeMayContainAuto && AllocType->isUndeducedType()) {
     if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
       return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
                        << AllocType << TypeRange);
-    if (initStyle == CXXNewExpr::ListInit)
+    if (initStyle == CXXNewExpr::ListInit ||
+        (NumInits == 1 && isa<InitListExpr>(Inits[0])))
       return ExprError(Diag(Inits[0]->getLocStart(),
-                            diag::err_auto_new_requires_parens)
+                            diag::err_auto_new_list_init)
                        << AllocType << TypeRange);
     if (NumInits > 1) {
       Expr *FirstBad = Inits[1];
index 158324cb82e0a71a64e62ae7dfa19b9674d17d07..cd62ba4b92dc68f29fcbce74dc7c7bee8dd622c4 100644 (file)
@@ -736,6 +736,9 @@ QualType Sema::performLambdaInitCaptureInitialization(SourceLocation Loc,
       return QualType();
     } else {
       DeduceInit = CXXDirectInit->getExpr(0);
+      if (isa<InitListExpr>(DeduceInit))
+        Diag(CXXDirectInit->getLocStart(), diag::err_init_capture_paren_braces)
+          << DeclarationName(Id) << Loc;
     }
   }
 
index 84f9f9b829834305f4dc6e81e1deacbc5a8aaf39..46c874f605cbf27d6c64f23fdd2a4612c003ca42 100644 (file)
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-c++1y-extensions
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions
 
 template<typename T>
@@ -41,3 +42,25 @@ struct S {
 };
 const int S::b;
 const auto S::c = 0;
+
+namespace std { template<typename T> struct initializer_list { initializer_list(); }; }
+
+// In an initializer of the form ( expression-list ), the expression-list
+// shall be a single assigment-expression.
+auto parens1(1);
+auto parens2(2, 3); // expected-error {{initializer for variable 'parens2' with type 'auto' contains multiple expressions}}
+#if __cplusplus >= 201103L
+auto parens3({4, 5, 6}); // expected-error {{cannot deduce type for variable 'parens3' with type 'auto' from parenthesized initializer list}}
+auto parens4 = [p4(1)] {};
+auto parens5 = [p5(2, 3)] {}; // expected-error {{initializer for lambda capture 'p5' contains multiple expressions}}
+auto parens6 = [p6({4, 5, 6})] {}; // expected-error {{cannot deduce type for lambda capture 'p6' from parenthesized initializer list}}
+#endif
+
+#if __cplusplus >= 201402L
+namespace std_example {
+  // The other half of this example is in p3.cpp
+  auto f() -> int;
+  auto g() { return 0.0; }
+  auto h();
+}
+#endif
diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp
new file mode 100644 (file)
index 0000000..5827291
--- /dev/null
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr1346 { // dr1346: 3.5
+  auto a(1); // expected-error 0-1{{extension}}
+  auto b(1, 2); // expected-error {{multiple expressions}} expected-error 0-1{{extension}}
+#if __cplusplus >= 201103L
+  auto c({}); // expected-error {{parenthesized initializer list}} expected-error {{cannot deduce}}
+  auto d({1}); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}}
+  auto e({1, 2}); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}}
+#endif
+  template<typename...Ts> void f(Ts ...ts) { // expected-error 0-1{{extension}}
+    auto x(ts...); // expected-error {{empty}} expected-error 0-1{{extension}}
+  }
+  template void f(); // expected-note {{instantiation}}
+
+#if __cplusplus >= 201103L
+  void init_capture() {
+    [a(1)] {} (); // expected-error 0-1{{extension}}
+    [b(1, 2)] {} (); // expected-error {{multiple expressions}} expected-error 0-1{{extension}}
+#if __cplusplus >= 201103L
+    [c({})] {} (); // expected-error {{parenthesized initializer list}} expected-error {{cannot deduce}} expected-error 0-1{{extension}}
+    [d({1})] {} (); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}} expected-error 0-1{{extension}}
+    [e({1, 2})] {} (); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}} expected-error 0-1{{extension}}
+#endif
+  }
+#endif
+}
index 2e99b525b443118a1106c60a323ac7dc664f7ccc..7305bd1f53e29bc8c3bb2175e1bab6bdedf8fcc2 100644 (file)
@@ -13,6 +13,8 @@ void f() {
   new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}}
   new (const auto)(); // expected-error{{new expression for type 'const auto' requires a constructor argument}}
   new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+  new auto {1,2,3}; // expected-error{{new expression for type 'auto' cannot use list-initialization}}
+  new auto ({1,2,3}); // expected-error{{new expression for type 'auto' cannot use list-initialization}}
 }
 
 void p2example() {
index c4420b94144ca373c24a6515a77cda2e6c60b23e..c431f774c55b675d34c9b8ddc4ee91d2a4b5a7aa 100644 (file)
@@ -7891,7 +7891,7 @@ and <I>POD class</I></td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1346">1346</a></td>
     <td>CD3</td>
     <td><I>expression-list</I> initializers and the <TT>auto</TT> specifier</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr id="1347">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1347">1347</a></td>