r224906 - Don't crash on surprising tokens in default parameter template lists.

Nico Weber nicolasweber at gmx.de
Sun Dec 28 15:24:02 PST 2014


Author: nico
Date: Sun Dec 28 17:24:02 2014
New Revision: 224906

URL: http://llvm.org/viewvc/llvm-project?rev=224906&view=rev
Log:
Don't crash on surprising tokens in default parameter template lists.

Fixes this snippet from SLi's afl fuzzer output:

  class {
      i (x = <, enum

This parsed i as a function, x as a paramter, and the stuff after < as a
template list.  This then called TryConsumeDeclarationSpecifier() which
called TryAnnotateCXXScopeToken() without checking the preconditions of
this function.  Check them before calling, like all other callers of
TryAnnotateCXXScopeToken() do.

A more readable reproducer that causes the same crash is

  class {
      void i(int x = MyTemplateClass<int, union int>::foo());
  };

The reduced version used an eof token as surprising token, but kw_int works
just as well to repro and is easier to insert into a test file.

Modified:
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
    cfe/trunk/lib/Parse/ParseTentative.cpp
    cfe/trunk/test/Parser/cxx-member-initializers.cpp

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=224906&r1=224905&r2=224906&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Sun Dec 28 17:24:02 2014
@@ -1019,7 +1019,7 @@ bool Parser::ConsumeAndStoreInitializer(
         case CIK_DefaultArgument:
           bool InvalidAsDeclaration = false;
           Result = TryParseParameterDeclarationClause(
-              &InvalidAsDeclaration, /*VersusTemplateArgument*/true);
+              &InvalidAsDeclaration, /*VersusTemplateArgument=*/true);
           // If this is an expression or a declaration with a missing
           // 'typename', assume it's not a declaration.
           if (Result == TPResult::Ambiguous && InvalidAsDeclaration)

Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=224906&r1=224905&r2=224906&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Sun Dec 28 17:24:02 2014
@@ -195,7 +195,9 @@ Parser::TPResult Parser::TryConsumeDecla
       }
     }
 
-    if (TryAnnotateCXXScopeToken())
+    if ((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+         Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)) &&
+        TryAnnotateCXXScopeToken())
       return TPResult::Error;
     if (Tok.is(tok::annot_cxxscope))
       ConsumeToken();

Modified: cfe/trunk/test/Parser/cxx-member-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-member-initializers.cpp?rev=224906&r1=224905&r2=224906&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-member-initializers.cpp (original)
+++ cfe/trunk/test/Parser/cxx-member-initializers.cpp Sun Dec 28 17:24:02 2014
@@ -79,3 +79,29 @@ namespace PR16480 {
     Errs(X<2>) : decltype(X<0> // expected-note {{to match this '('}}
   }; // expected-error {{expected ')'}}
 }
+
+template <class U, class V> struct C {
+  int f() { return 4; }
+  class C1 {};
+};
+
+class D {};
+namespace N {
+struct E {
+  class F {};
+};
+}
+
+class G {
+  // These are all valid:
+  void f(int x = C<int, D>().f()) {}
+  void g(int x = C<int, ::D>().f()) {}
+  void h(int x = C<int, N::E>().f()) {}
+  void i(int x = C<int, ::N::E>().f()) {}
+  void j(int x = C<int, decltype(N::E())::F>().f()) {}
+  void k(int x = C<int, C<int, int>>().f()) {}
+  void l(int x = C<int, C<int, int>::C1>().f()) {}
+
+  // This isn't, but it shouldn't crash. The diagnostics don't matter much.
+  void m(int x = C<int, union int>().f()) {} // expected-error {{declaration of anonymous union must be a definition}}
+}; // expected-error {{expected a type}}





More information about the cfe-commits mailing list