From 44f1206f4304161eb6ea96c9fd000c1e42f932e2 Mon Sep 17 00:00:00 2001
From: Serge Pavlov <sepavloff@gmail.com>
Date: Wed, 15 Jan 2014 01:53:39 +0000
Subject: [PATCH] Fixed error recovery if sizeof is used without parenthesis

Changes made in r192200 fixed PR16992, which requested fixit suggesting
parenthesis if sizeof is followed by type-id. However expression in form
T() followed by ')' was incorrectly considered as a type-id if 'T' is
typedef name. This change fixes this case.

Differential Revision: http://llvm-reviews.chandlerc.com/D2440


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199284 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Parse/Parser.h | 11 +++++++++++
 lib/Parse/ParseExpr.cpp      |  3 +--
 test/SemaCXX/expressions.cpp |  7 +++++++
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 9d0d1b60590..aa7aca30af1 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -1788,6 +1788,7 @@ private:
   /// disambiguation will occur.
   enum TentativeCXXTypeIdContext {
     TypeIdInParens,
+    TypeIdUnambiguous,
     TypeIdAsTemplateArgument
   };
 
@@ -1806,6 +1807,16 @@ private:
     return isTypeIdInParens(isAmbiguous);
   }
 
+  /// \brief Checks if the current tokens form type-id or expression.
+  /// It is similar to isTypeIdInParens but does not suppose that type-id
+  /// is in parenthesis.
+  bool isTypeIdUnambiguously() {
+    bool IsAmbiguous;
+    if (getLangOpts().CPlusPlus)
+      return isCXXTypeId(TypeIdUnambiguous, IsAmbiguous);
+    return isTypeSpecifierQualifier();
+  }
+
   /// isCXXDeclarationStatement - C++-specialized function that disambiguates
   /// between a declaration or an expression statement, when parsing function
   /// bodies. Returns true for declaration, false for expression.
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index d94155ba6c6..f7b0afe60d8 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1492,8 +1492,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
     // pathenthesis around type name.
     if (OpTok.is(tok::kw_sizeof)  || OpTok.is(tok::kw___alignof) ||
         OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof)) {
-      bool isAmbiguousTypeId;
-      if (isTypeIdInParens(isAmbiguousTypeId)) {
+      if (isTypeIdUnambiguously()) {
         DeclSpec DS(AttrFactory);
         ParseSpecifierQualifierList(DS);
         Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
index 2635fb8d176..25a9c841725 100644
--- a/test/SemaCXX/expressions.cpp
+++ b/test/SemaCXX/expressions.cpp
@@ -118,3 +118,10 @@ void test3() {
   (void)s1.foo();
   (void)s2.foo();
 }
+
+namespace pr16992 {
+  typedef int T;
+  unsigned getsz() {
+    return (sizeof T());
+  }
+}
-- 
GitLab