From 208e9a2757ae9146e538fffe399c18ee4259a84a Mon Sep 17 00:00:00 2001
From: Olivier Goffart <ogoffart@woboq.com>
Date: Sat, 18 May 2013 11:24:12 +0200
Subject: [PATCH] moc: recover bad template parsing.

When encountering code such as:
  X<a<b>
moc does not have the mean to know if 'a' is a type or a variable, so the
type parser currently assume that '<' always open a template parameter.
(instead of being the operator<)

The type parser do not care about the actual type, it just need to strip
the string out. The problem is that then the whole rest of the file will
be considered as the type.

With this patch, we also stop the parsing at semicolon.  The type will
be wrong, but this allow the parser to recover and it will continue to
look for more classes after this.

(In other words, moc will no longer break if it encounter such construct
in a header. But it will still not parse such types correctly if used
within a Q_OBJECT class)

Task-number: QTBUG-31218

Change-Id: I1fef6bc58493d7c00df72401c9ad55463b24eaa7
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
---
 src/tools/moc/moc.cpp            | 5 +++++
 tests/auto/tools/moc/tst_moc.cpp | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 1ebb82ffadc..f3bfcc31440 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -1449,6 +1449,11 @@ bool Moc::until(Token target) {
             --index;
             break;
         }
+
+        if (braceCount <= 0 && t == SEMIC) {
+            // Abort on semicolon. Allow recovering bad template parsing (QTBUG-31218)
+            break;
+        }
     }
 
     if(target == COMMA && angleCount != 0 && possible != -1) {
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index e0179b393b3..923275d9284 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -79,6 +79,9 @@
 
 QT_USE_NAMESPACE
 
+template <bool b> struct QTBUG_31218 {};
+struct QTBUG_31218_Derived : QTBUG_31218<-1<0> {};
+
 struct MyStruct {};
 struct MyStruct2 {};
 
-- 
GitLab