[PATCH] D16216: Fix infinite loop when ::new or ::delete are found in member initializer list
Denis Zobnin via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 15 02:45:12 PST 2016
d.zobnin.bugzilla created this revision.
d.zobnin.bugzilla added reviewers: kcc, rsmith.
d.zobnin.bugzilla added a subscriber: cfe-commits.
Fix for a case found by fuzzing PR23057 (comment #33 https://llvm.org/bugs/show_bug.cgi?id=23057#c33). Diagnose and consume unexpected ::new and ::delete tokens to prevent infinite loop in parsing a member initializer list.
http://reviews.llvm.org/D16216
Files:
include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseDeclCXX.cpp
test/Parser/cxx-invalid-function-decl.cpp
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: 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: 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 at -1{{unexpected '::new' in member initializer list}}
+ // expected-error at -2{{only constructors take base initializers}}
+
+template <class T>
+struct Base1 {
+ T x1;
+ Base1(T a1) : x1(a1) {}
+};
+
+template <class T>
+struct Base2 {
+ T x2;
+ Base2(T a2) : x2(a2) {}
+};
+
+struct S : public Base1<int>, public Base2<float> {
+ int x;
+ S() : ::Base1<int>(0) ::new, ::Base2<float>(1.0) ::delete x(2) {} // expected-error3{{missing ',' between base or member initializers}}
+ // expected-error at -1{{unexpected '::new' in member initializer list}}
+ // expected-error at -2{{unexpected '::delete' in member initializer list}}
+};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16216.44971.patch
Type: text/x-patch
Size: 2984 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160115/bf20c54a/attachment.bin>
More information about the cfe-commits
mailing list