Skip to content

Commit

Permalink
DR1346: a parenthesized braced-init-list cannot be used as the initia…
Browse files Browse the repository at this point in the history
…lizer when

performing auto type deduction.

llvm-svn: 203683
  • Loading branch information
zygoloid committed Mar 12, 2014
1 parent b5e41ea commit 66204ec
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 6 deletions.
8 changes: 7 additions & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down Expand Up @@ -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<
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}

Expand Down
7 changes: 4 additions & 3 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaLambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
25 changes: 24 additions & 1 deletion clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -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
29 changes: 29 additions & 0 deletions clang/test/CXX/drs/dr13xx.cpp
Original file line number Diff line number Diff line change
@@ -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
}
2 changes: 2 additions & 0 deletions clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -7891,7 +7891,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<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>
Expand Down

0 comments on commit 66204ec

Please sign in to comment.