[cfe-commits] r151137 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Sema/DeclSpec.h lib/Parse/ParseExprCXX.cpp test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp test/Parser/cxx-condition.cpp test/Parser/cxx0x-condition.cpp test/SemaCXX/cxx0x-initializer-scalars.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Tue Feb 21 22:49:10 PST 2012
Author: rsmith
Date: Wed Feb 22 00:49:09 2012
New Revision: 151137
URL: http://llvm.org/viewvc/llvm-project?rev=151137&view=rev
Log:
Accept braced-init-lists in conditions, and, in passing, dramatically improve
the diagnostic for using a parenthesized direct-initializer in a condition.
Added:
cfe/trunk/test/Parser/cxx0x-condition.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
cfe/trunk/test/Parser/cxx-condition.cpp
cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=151137&r1=151136&r2=151137&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Feb 22 00:49:09 2012
@@ -381,8 +381,10 @@
"function definition does not declare parameters">;
def err_expected_lparen_after_type : Error<
"expected '(' for function-style cast or type construction">;
-def err_expected_equal_after_declarator : Error<
- "expected '=' after declarator">;
+def err_expected_init_in_condition : Error<
+ "variable declaration in condition must have an initializer">;
+def err_expected_init_in_condition_lparen : Error<
+ "variable declaration in condition cannot have a parenthesized initializer">;
def warn_parens_disambiguated_as_function_decl : Warning<
"parentheses were disambiguated as a function declarator">,
InGroup<VexingParse>;
Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=151137&r1=151136&r2=151137&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Wed Feb 22 00:49:09 2012
@@ -1645,9 +1645,14 @@
case ForContext:
return true;
+ case ConditionContext:
+ // This may not be followed by a direct initializer, but it can't be a
+ // function declaration either, and we'd prefer to perform a tentative
+ // parse in order to produce the right diagnostic.
+ return true;
+
case KNRTypeListContext:
case MemberContext:
- case ConditionContext:
case PrototypeContext:
case ObjCParameterContext:
case ObjCResultContext:
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=151137&r1=151136&r2=151137&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Feb 22 00:49:09 2012
@@ -1271,6 +1271,8 @@
/// condition:
/// expression
/// type-specifier-seq declarator '=' assignment-expression
+/// [C++11] type-specifier-seq declarator '=' initializer-clause
+/// [C++11] type-specifier-seq declarator braced-init-list
/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
/// '=' assignment-expression
///
@@ -1342,17 +1344,34 @@
// '=' assignment-expression
// If a '==' or '+=' is found, suggest a fixit to '='.
- if (isTokenEqualOrEqualTypo()) {
+ bool CopyInitialization = isTokenEqualOrEqualTypo();
+ if (CopyInitialization)
ConsumeToken();
- ExprResult AssignExpr(ParseAssignmentExpression());
- if (!AssignExpr.isInvalid())
- Actions.AddInitializerToDecl(DeclOut, AssignExpr.take(), false,
- DS.getTypeSpecType() == DeclSpec::TST_auto);
+
+ ExprResult InitExpr = ExprError();
+ if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ Diag(Tok.getLocation(),
+ diag::warn_cxx98_compat_generalized_initializer_lists);
+ InitExpr = ParseBraceInitializer();
+ } else if (CopyInitialization) {
+ InitExpr = ParseAssignmentExpression();
+ } else if (Tok.is(tok::l_paren)) {
+ // This was probably an attempt to initialize the variable.
+ SourceLocation LParen = ConsumeParen(), RParen = LParen;
+ if (SkipUntil(tok::r_paren, true, /*DontConsume=*/true))
+ RParen = ConsumeParen();
+ Diag(DeclOut ? DeclOut->getLocation() : LParen,
+ diag::err_expected_init_in_condition_lparen)
+ << SourceRange(LParen, RParen);
} else {
- // FIXME: C++0x allows a braced-init-list
- Diag(Tok, diag::err_expected_equal_after_declarator);
+ Diag(DeclOut ? DeclOut->getLocation() : Tok.getLocation(),
+ diag::err_expected_init_in_condition);
}
-
+
+ if (!InitExpr.isInvalid())
+ Actions.AddInitializerToDecl(DeclOut, InitExpr.take(), !CopyInitialization,
+ DS.getTypeSpecType() == DeclSpec::TST_auto);
+
// FIXME: Build a reference to this declaration? Convert it to bool?
// (This is currently handled by Sema).
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp?rev=151137&r1=151136&r2=151137&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp Wed Feb 22 00:49:09 2012
@@ -13,9 +13,9 @@
auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}}
- if (auto b) {} // expected-error {{expected '='}}
- for (;auto b;) {} // expected-error {{expected '='}}
- while (auto b) {} // expected-error {{expected '='}}
+ if (auto b) {} // expected-error {{must have an initializer}}
+ for (;auto b;) {} // expected-error {{must have an initializer}}
+ while (auto b) {} // expected-error {{must have an initializer}}
if (auto b = true) { (void)b; }
}
Modified: cfe/trunk/test/Parser/cxx-condition.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-condition.cpp?rev=151137&r1=151136&r2=151137&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-condition.cpp (original)
+++ cfe/trunk/test/Parser/cxx-condition.cpp Wed Feb 22 00:49:09 2012
@@ -1,11 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct S { S(int); operator bool(); };
+
void f() {
int a;
while (a) ;
- while (int x) ; // expected-error {{expected '=' after declarator}}
+ while (int x) ; // expected-error {{variable declaration in condition must have an initializer}}
while (float x = 0) ;
if (const int x = a) ; // expected-warning{{empty body}} expected-note{{put the semicolon on a separate line to silence this warning}}
switch (int x = a+10) {}
for (; int x = ++a; ) ;
+
+ if (S a(42)) {} // expected-error {{variable declaration in condition cannot have a parenthesized initializer}}
}
Added: cfe/trunk/test/Parser/cxx0x-condition.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-condition.cpp?rev=151137&view=auto
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-condition.cpp (added)
+++ cfe/trunk/test/Parser/cxx0x-condition.cpp Wed Feb 22 00:49:09 2012
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+struct S { S(int); operator bool(); };
+
+void f() {
+ int a;
+ typedef int n;
+
+ while (a) ;
+ while (int x) ; // expected-error {{variable declaration in condition must have an initializer}}
+ while (float x = 0) ;
+ if (const int x = a) ; // expected-warning{{empty body}} expected-note{{put the semicolon on a separate line to silence this warning}}
+ switch (int x = a+10) {}
+ for (; int x = ++a; ) ;
+
+ if (S(a)) {} // ok
+ if (S(a) = 0) {} // ok
+ if (S(a) == 0) {} // ok
+
+ if (S(n)) {} // expected-error {{unexpected type name 'n': expected expression}}
+ if (S(n) = 0) {} // ok
+ if (S(n) == 0) {} // expected-error {{unexpected type name 'n': expected expression}}
+
+ if (S b(a)) {} // expected-error {{variable declaration in condition cannot have a parenthesized initializer}}
+
+ if (S b(n)) {} // expected-error {{a function type is not allowed here}} expected-error {{must have an initializer}}
+ if (S b(n) = 0) {} // expected-error {{a function type is not allowed here}}
+ if (S b(n) == 0) {} // expected-error {{a function type is not allowed here}} expected-error {{did you mean '='?}}
+
+ // FIXME: this is legal, and incorrectly rejected, because tentative parsing
+ // does not yet know about braced function-style casts.
+ if (S{a}) {} // unexpected-error{{unqualified-id}}
+
+ if (S a{a}) {} // ok
+ if (S a = {a}) {} // ok
+ if (S a == {a}) {} // expected-error {{did you mean '='?}}
+}
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp?rev=151137&r1=151136&r2=151137&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp Wed Feb 22 00:49:09 2012
@@ -15,6 +15,8 @@
// FIXME: Redundant warnings.
{ const short a{100000}; } // expected-error {{cannot be narrowed}} expected-note {{inserting an explicit cast}} expected-warning {{changes value}}
{ const short a = {100000}; } // expected-error {{cannot be narrowed}} expected-note {{inserting an explicit cast}} expected-warning {{changes value}}
+ { if (const int a{1}) static_assert(a == 1, ""); }
+ { if (const int a = {1}) static_assert(a == 1, ""); }
}
int direct_usage() {
More information about the cfe-commits
mailing list