diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index eb1b7f7463767460513fcefb6d3f66ef980e57fb..414b27fbbd4a50e40edf94e8628fb06627ef2fa1 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -4041,12 +4041,12 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&node)
         last->value->name_token = identifier_token;
         last->value->colon_token = consumeToken();
 
-        while (LA() != T_RPAREN) {
+        while (LA(1) == T_IDENTIFIER && LA(2) == T_COLON) {
             last->next = new (_pool) ObjCSelectorArgumentListAST;
             last = last->next;
             last->value = new (_pool) ObjCSelectorArgumentAST;
-            match(T_IDENTIFIER, &last->value->name_token);
-            match(T_COLON, &last->value->colon_token);
+            last->value->name_token = consumeToken();
+            last->value->colon_token = consumeToken();
         }
     } else {
         ObjCSelectorAST *args = new (_pool) ObjCSelectorAST;
@@ -4056,7 +4056,13 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&node)
         args->selector_argument_list->value->name_token = identifier_token;
     }
 
+    if (LA(1) == T_IDENTIFIER && LA(2) == T_RPAREN) {
+        const char *txt = tok(1).spell();
+        consumeToken();
+        error(cursor(), "missing ':' after '%s'", txt);
+    }
     match(T_RPAREN, &ast->rparen_token);
+
     node = ast;
     return true;
 }
diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp
index af819e871f98092ff753298b424e25296e2a521b..bc10347f54c2ca12af7d0ce23859370c2a354ac4 100644
--- a/tests/auto/cplusplus/ast/tst_ast.cpp
+++ b/tests/auto/cplusplus/ast/tst_ast.cpp
@@ -83,6 +83,8 @@ private slots:
     void objc_protocol_forward_declaration_1();
     void objc_protocol_definition_1();
     void objc_method_attributes_1();
+    void objc_selector_error_recovery_1();
+    void objc_selector_error_recovery_2();
 
     // expressions with (square) brackets
     void normal_array_access();
@@ -832,6 +834,45 @@ void tst_AST::objc_method_attributes_1()
     QCOMPARE(unit->spell(unavailableAttr->identifier_token), "unavailable");
 }
 
+/*
+  @selector(foo)
+  @selector(foo:)
+  @selector(foo:bar:)
+  ...
+ */
+void tst_AST::objc_selector_error_recovery_1()
+{
+    QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
+                                                          "void tst() {\n"
+                                                          "    @selector(foo:\n"
+                                                          "    int i = 1;\n"
+                                                          "}\n"
+                                                          ));
+    AST *ast = unit->ast();
+    QVERIFY(ast);
+    ObjCClassDeclarationAST *zoo = ast->asObjCClassDeclaration();
+    QVERIFY(zoo);
+    QVERIFY(zoo->interface_token); QVERIFY(! (zoo->implementation_token));
+    QVERIFY(zoo->class_name); QVERIFY(zoo->class_name->asSimpleName());
+    QCOMPARE(unit->spell(zoo->class_name->asSimpleName()->identifier_token), "Zoo");
+}
+
+void tst_AST::objc_selector_error_recovery_2()
+{
+    QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
+                                                          "void tst() {\n"
+                                                          "    @selector(foo:bar);\n"
+                                                          "}\n"
+                                                          ));
+    AST *ast = unit->ast();
+    QVERIFY(ast);
+    ObjCClassDeclarationAST *zoo = ast->asObjCClassDeclaration();
+    QVERIFY(zoo);
+    QVERIFY(zoo->interface_token); QVERIFY(! (zoo->implementation_token));
+    QVERIFY(zoo->class_name); QVERIFY(zoo->class_name->asSimpleName());
+    QCOMPARE(unit->spell(zoo->class_name->asSimpleName()->identifier_token), "Zoo");
+}
+
 void tst_AST::normal_array_access()
 {
     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"