diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 958d740a5875d48ad74143367ebf2902af418085..d754b234f43672cf8d7786e430d1ab28caaa70fe 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -2988,15 +2988,30 @@ bool Parser::parseObjCMessageExpression(ExpressionAST *&node)
     if (LA() != T_LBRACKET)
         return false;
 
-    ObjCMessageExpressionAST *ast = new (_pool) ObjCMessageExpressionAST;
-    ast->lbracket_token = consumeToken();
+    unsigned start = cursor();
 
-    parseObjCMessageReceiver(ast->receiver_expression);
-    parseObjCMessageArguments(ast->selector, ast->argument_list);
+    unsigned lbracket_token = consumeToken();
+    ExpressionAST *receiver_expression = 0;
+    ObjCSelectorAST *selector = 0;
+    ObjCMessageArgumentListAST *argument_list = 0;
 
-    match(T_RBRACKET, &(ast->rbracket_token));
-    node = ast;
-    return true;
+    if (parseObjCMessageReceiver(receiver_expression) &&
+        parseObjCMessageArguments(selector, argument_list)) {
+
+        ObjCMessageExpressionAST *ast = new (_pool) ObjCMessageExpressionAST;
+        ast->lbracket_token = lbracket_token;
+        ast->receiver_expression = receiver_expression;
+        ast->selector = selector;
+        ast->argument_list = argument_list;
+
+        match(T_RBRACKET, &(ast->rbracket_token));
+        node = ast;
+
+        return true;
+    }
+
+    rewind(start);
+    return false;
 }
 
 bool Parser::parseObjCMessageReceiver(ExpressionAST *&node)
@@ -3051,15 +3066,20 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg
 
         selNode = selWithArgs;
         argNode = argAst;
+        return true;
     } else {
         rewind(start);
+        unsigned name_token = 0;
+        if (!parseObjCSelector(name_token))
+            return false;
         ObjCSelectorWithoutArgumentsAST *sel = new (_pool) ObjCSelectorWithoutArgumentsAST;
-        parseObjCSelector(sel->name_token);
+        sel->name_token = name_token;
         selNode = sel;
         argNode = 0;
+        return true;
     }
 
-    return true;
+    return false;
 }
 
 bool Parser::parseObjCSelectorArg(ObjCSelectorArgumentAST *&selNode, ObjCMessageArgumentAST *&argNode)
diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp
index cad9d51caccdeba3a448665e3938192ef2519ef5..45b6088c9f29756790ab1174e62ef788dbca2572 100644
--- a/tests/auto/cplusplus/ast/tst_ast.cpp
+++ b/tests/auto/cplusplus/ast/tst_ast.cpp
@@ -3,6 +3,7 @@
 #include <QtDebug>
 
 #include <Control.h>
+#include <Literals.h>
 #include <Parser.h>
 #include <AST.h>
 
@@ -15,19 +16,22 @@ class tst_AST: public QObject
     Control control;
 
 public:
+
     TranslationUnit *parse(const QByteArray &source,
-                           TranslationUnit::ParseMode mode)
+                           TranslationUnit::ParseMode mode,
+                           bool blockErrors = false)
     {
         StringLiteral *fileId = control.findOrInsertStringLiteral("<stdin>");
         TranslationUnit *unit = new TranslationUnit(&control, fileId);
         unit->setObjCEnabled(true);
         unit->setSource(source.constData(), source.length());
+        unit->blockErrors(blockErrors);
         unit->parse(mode);
         return unit;
     }
 
-    TranslationUnit *parseDeclaration(const QByteArray &source)
-    { return parse(source, TranslationUnit::ParseDeclaration); }
+    TranslationUnit *parseDeclaration(const QByteArray &source, bool blockErrors = false)
+    { return parse(source, TranslationUnit::ParseDeclaration, blockErrors); }
 
     TranslationUnit *parseExpression(const QByteArray &source)
     { return parse(source, TranslationUnit::ParseExpression); }
@@ -59,6 +63,12 @@ private slots:
     void objc_attributes_followed_by_at_keyword();
     void objc_protocol_forward_declaration_1();
     void objc_protocol_definition_1();
+
+    // expressions with (square) brackets
+    void normal_array_access();
+    void array_access_with_nested_expression();
+    void objc_msg_send_expression();
+    void objc_msg_send_expression_without_selector();
 };
 
 void tst_AST::gcc_attributes_1()
@@ -421,5 +431,198 @@ void tst_AST::objc_protocol_definition_1()
     AST *ast = unit->ast();
 }
 
+void tst_AST::normal_array_access()
+{
+    QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
+                                                          "int f() {\n"
+                                                          "  int a[15];\n"
+                                                          "  int b = 1;\n"
+                                                          "  return a[b];\n"
+                                                          "}"
+                                                          ));
+    AST *ast = unit->ast();
+    QVERIFY(ast);
+
+    FunctionDefinitionAST *func = ast->asFunctionDefinition();
+    QVERIFY(func);
+
+    StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements;
+    QVERIFY(bodyStatements && bodyStatements->next && bodyStatements->next->next && bodyStatements->next->next->statement);
+    ExpressionAST *expr = bodyStatements->next->next->statement->asReturnStatement()->expression;
+    QVERIFY(expr);
+
+    PostfixExpressionAST *postfixExpr = expr->asPostfixExpression();
+    QVERIFY(postfixExpr);
+
+    {
+        ExpressionAST *lhs = postfixExpr->base_expression;
+        QVERIFY(lhs);
+        SimpleNameAST *a = lhs->asSimpleName();
+        QVERIFY(a);
+        QCOMPARE(QLatin1String(unit->identifier(a->identifier_token)->chars()), QLatin1String("a"));
+    }
+
+    {
+        QVERIFY(postfixExpr->postfix_expressions && !postfixExpr->postfix_expressions->next);
+        ArrayAccessAST *rhs = postfixExpr->postfix_expressions->asArrayAccess();
+        QVERIFY(rhs && rhs->expression);
+        SimpleNameAST *b = rhs->expression->asSimpleName();
+        QVERIFY(b);
+        QCOMPARE(QLatin1String(unit->identifier(b->identifier_token)->chars()), QLatin1String("b"));
+    }
+}
+
+void tst_AST::array_access_with_nested_expression()
+{
+    QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
+                                                          "int f() {\n"
+                                                          "  int a[15];\n"
+                                                          "  int b = 1;\n"
+                                                          "  return (a)[b];\n"
+                                                          "}"
+                                                          ));
+    AST *ast = unit->ast();
+    QVERIFY(ast);
+
+    FunctionDefinitionAST *func = ast->asFunctionDefinition();
+    QVERIFY(func);
+
+    StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements;
+    QVERIFY(bodyStatements && bodyStatements->next && bodyStatements->next->next && bodyStatements->next->next->statement);
+    ExpressionAST *expr = bodyStatements->next->next->statement->asReturnStatement()->expression;
+    QVERIFY(expr);
+
+    CastExpressionAST *castExpr = expr->asCastExpression();
+    QVERIFY(!castExpr);
+
+    PostfixExpressionAST *postfixExpr = expr->asPostfixExpression();
+    QVERIFY(postfixExpr);
+
+    {
+        ExpressionAST *lhs = postfixExpr->base_expression;
+        QVERIFY(lhs);
+        NestedExpressionAST *nested_a = lhs->asNestedExpression();
+        QVERIFY(nested_a && nested_a->expression);
+        SimpleNameAST *a = nested_a->expression->asSimpleName();
+        QVERIFY(a);
+        QCOMPARE(QLatin1String(unit->identifier(a->identifier_token)->chars()), QLatin1String("a"));
+    }
+
+    {
+        QVERIFY(postfixExpr->postfix_expressions && !postfixExpr->postfix_expressions->next);
+        ArrayAccessAST *rhs = postfixExpr->postfix_expressions->asArrayAccess();
+        QVERIFY(rhs && rhs->expression);
+        SimpleNameAST *b = rhs->expression->asSimpleName();
+        QVERIFY(b);
+        QCOMPARE(QLatin1String(unit->identifier(b->identifier_token)->chars()), QLatin1String("b"));
+    }
+}
+
+void tst_AST::objc_msg_send_expression()
+{
+    QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
+                                                          "int f() {\n"
+                                                          "  NSObject *obj = [[[NSObject alloc] init] autorelease];\n"
+                                                          "  return [obj description];\n"
+                                                          "}"
+                                                          ));
+    AST *ast = unit->ast();
+    QVERIFY(ast);
+
+    FunctionDefinitionAST *func = ast->asFunctionDefinition();
+    QVERIFY(func);
+
+    StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements;
+    QVERIFY(bodyStatements && bodyStatements->next && !bodyStatements->next->next && bodyStatements->next->statement);
+
+    {// check the NSObject declaration
+        ExpressionOrDeclarationStatementAST *firstStatement = bodyStatements->statement->asExpressionOrDeclarationStatement();
+        QVERIFY(firstStatement && firstStatement->declaration && firstStatement->declaration->asDeclarationStatement());
+        DeclarationAST *objDecl = firstStatement->declaration->asDeclarationStatement()->declaration;
+        QVERIFY(objDecl);
+        SimpleDeclarationAST *simpleDecl = objDecl->asSimpleDeclaration();
+        QVERIFY(simpleDecl);
+
+        {// check the type (NSObject)
+            QVERIFY(simpleDecl->decl_specifier_seq && !simpleDecl->decl_specifier_seq->next);
+            NamedTypeSpecifierAST *namedType = simpleDecl->decl_specifier_seq->asNamedTypeSpecifier();
+            QVERIFY(namedType && namedType->name);
+            SimpleNameAST *typeName = namedType->name->asSimpleName();
+            QVERIFY(typeName);
+            QCOMPARE(QLatin1String(unit->identifier(typeName->identifier_token)->chars()), QLatin1String("NSObject"));
+        }
+
+        {// check the assignment
+            QVERIFY(simpleDecl->declarators && !simpleDecl->declarators->next);
+            DeclaratorAST *declarator = simpleDecl->declarators->declarator;
+            QVERIFY(declarator);
+            QVERIFY(!declarator->attributes);
+
+            QVERIFY(declarator->ptr_operators && !declarator->ptr_operators->next && declarator->ptr_operators->asPointer() && !declarator->ptr_operators->asPointer()->cv_qualifier_seq);
+
+            QVERIFY(declarator->core_declarator && declarator->core_declarator->asDeclaratorId());
+            NameAST *objNameId = declarator->core_declarator->asDeclaratorId()->name;
+            QVERIFY(objNameId && objNameId->asSimpleName());
+            QCOMPARE(QLatin1String(unit->identifier(objNameId->asSimpleName()->identifier_token)->chars()), QLatin1String("obj"));
+
+            QVERIFY(!declarator->postfix_declarators);
+            QVERIFY(!declarator->post_attributes);
+            ExpressionAST *initializer = declarator->initializer;
+            QVERIFY(initializer);
+
+            ObjCMessageExpressionAST *expr1 = initializer->asObjCMessageExpression();
+            QVERIFY(expr1 && expr1->receiver_expression && expr1->selector && !expr1->argument_list);
+
+            ObjCMessageExpressionAST *expr2 = expr1->receiver_expression->asObjCMessageExpression();
+            QVERIFY(expr2 && expr2->receiver_expression && expr2->selector && !expr2->argument_list);
+
+            ObjCMessageExpressionAST *expr3 = expr2->receiver_expression->asObjCMessageExpression();
+            QVERIFY(expr3 && expr3->receiver_expression && expr3->selector && !expr3->argument_list);
+        }
+    }
+
+    {// check the return statement
+        ExpressionAST *expr = bodyStatements->next->statement->asReturnStatement()->expression;
+        QVERIFY(expr);
+
+        ObjCMessageExpressionAST *msgExpr = expr->asObjCMessageExpression();
+        QVERIFY(msgExpr);
+
+        QVERIFY(msgExpr->receiver_expression);
+        SimpleNameAST *receiver = msgExpr->receiver_expression->asSimpleName();
+        QVERIFY(receiver);
+        QCOMPARE(QLatin1String(unit->identifier(receiver->identifier_token)->chars()), QLatin1String("obj"));
+
+        QVERIFY(msgExpr->argument_list == 0);
+
+        QVERIFY(msgExpr->selector);
+        ObjCSelectorWithoutArgumentsAST *sel = msgExpr->selector->asObjCSelectorWithoutArguments();
+        QVERIFY(sel);
+        QCOMPARE(QLatin1String(unit->identifier(sel->name_token)->chars()), QLatin1String("description"));
+    }
+}
+
+void tst_AST::objc_msg_send_expression_without_selector()
+{
+    // This test is to verify that no ObjCMessageExpressionAST element is created as the expression for the return statement.
+    QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
+                                                          "int f() {\n"
+                                                          "  NSObject *obj = [[[NSObject alloc] init] autorelease];\n"
+                                                          "  return [obj];\n"
+                                                          "}",
+                                                          true));
+    AST *ast = unit->ast();
+    QVERIFY(ast);
+
+    FunctionDefinitionAST *func = ast->asFunctionDefinition();
+    QVERIFY(func);
+
+    StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements;
+    QVERIFY(bodyStatements && bodyStatements->next);
+    QVERIFY(bodyStatements->next->statement);
+    QVERIFY(bodyStatements->next->statement->asReturnStatement());
+    QVERIFY(!bodyStatements->next->statement->asReturnStatement()->expression);
+}
+
 QTEST_APPLESS_MAIN(tst_AST)
 #include "tst_ast.moc"