Index: include/clang/Basic/DiagnosticParseKinds.td =================================================================== --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -161,6 +161,8 @@ def err_at_defs_cxx : Error<"@defs is not supported in Objective-C++">; def err_at_in_class : Error<"unexpected '@' in member specification">; def err_unexpected_semi : Error<"unexpected ';' before %0">; +def err_unexpected_in_member_initlist : Error< + "unexpected %select{'::new'|'::delete'}0 in member initializer list">; def err_expected_fn_body : Error< "expected function body after function declarator">; Index: lib/Parse/ParseDeclCXX.cpp =================================================================== --- lib/Parse/ParseDeclCXX.cpp +++ lib/Parse/ParseDeclCXX.cpp @@ -3237,6 +3237,20 @@ CXXScopeSpec SS; ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); ParsedType TemplateTypeTy; + // If ::new or ::delete was met, ParseOptionalCXXScopeSpecifier just left + // them untouched. Diagnose it now to prevent infinite loop on parsing such + // code: "f() : ::new". + if (Tok.is(tok::coloncolon)) { + tok::TokenKind NextKind = NextToken().getKind(); + if (NextKind == tok::kw_new || NextKind == tok::kw_delete) { + SourceRange Range(Tok.getLocation(), NextToken().getEndLoc()); + Diag(Tok.getLocation(), diag::err_unexpected_in_member_initlist) + << (NextKind == tok::kw_delete) << Range; + ConsumeToken(); // the '::' token. + ConsumeToken(); // 'new' or 'delete'. + return true; + } + } if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); if (TemplateId->Kind == TNK_Type_template || Index: test/Parser/cxx-invalid-function-decl.cpp =================================================================== --- test/Parser/cxx-invalid-function-decl.cpp +++ test/Parser/cxx-invalid-function-decl.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f() : X() ::new{}; // expected-error{{missing ',' between base or member initializers}} + // expected-error@-1{{unexpected '::new' in member initializer list}} + // expected-error@-2{{only constructors take base initializers}} + +template +struct Base1 { + T x1; + Base1(T a1) : x1(a1) {} +}; + +template +struct Base2 { + T x2; + Base2(T a2) : x2(a2) {} +}; + +struct S : public Base1, public Base2 { + int x; + S() : ::Base1(0) ::new, ::Base2(1.0) ::delete x(2) {} // expected-error3{{missing ',' between base or member initializers}} + // expected-error@-1{{unexpected '::new' in member initializer list}} + // expected-error@-2{{unexpected '::delete' in member initializer list}} +};