From b7b8b123503d927518f5055a96f8a4630053768a Mon Sep 17 00:00:00 2001
From: David Majnemer <david.majnemer@gmail.com>
Date: Fri, 18 Jul 2014 19:53:23 +0000
Subject: [PATCH] Address Richard's comments

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213403 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGExprCXX.cpp               | 22 +++++++++++++++-------
 test/CodeGenCXX/typeid-should-throw.cpp |  4 ++++
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 8cadd6c1eb2..768fab726b0 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -1616,14 +1616,13 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
 }
 
 static bool isGLValueFromPointerDeref(const Expr *E) {
-  E = E->IgnoreParenCasts();
+  E = E->IgnoreParens();
 
-  if (isa<ArraySubscriptExpr>(E))
-    return true;
-
-  if (const auto *UO = dyn_cast<UnaryOperator>(E))
-    if (UO->getOpcode() == UO_Deref)
-      return true;
+  if (const auto *CE = dyn_cast<CastExpr>(E)) {
+    if (!CE->getSubExpr()->isGLValue())
+      return false;
+    return isGLValueFromPointerDeref(CE->getSubExpr());
+  }
 
   if (const auto *BO = dyn_cast<BinaryOperator>(E))
     if (BO->getOpcode() == BO_Comma)
@@ -1638,6 +1637,15 @@ static bool isGLValueFromPointerDeref(const Expr *E) {
       return isGLValueFromPointerDeref(OVE->getSourceExpr()) ||
              isGLValueFromPointerDeref(BCO->getFalseExpr());
 
+  // C++11 [expr.sub]p1:
+  //   The expression E1[E2] is identical (by definition) to *((E1)+(E2))
+  if (isa<ArraySubscriptExpr>(E))
+    return true;
+
+  if (const auto *UO = dyn_cast<UnaryOperator>(E))
+    if (UO->getOpcode() == UO_Deref)
+      return true;
+
   return false;
 }
 
diff --git a/test/CodeGenCXX/typeid-should-throw.cpp b/test/CodeGenCXX/typeid-should-throw.cpp
index 66abf4c6631..08e304b13aa 100644
--- a/test/CodeGenCXX/typeid-should-throw.cpp
+++ b/test/CodeGenCXX/typeid-should-throw.cpp
@@ -52,3 +52,7 @@ void f9(A *x) { typeid(0[x]); }
 // CHECK-LABEL: define void @_Z2f9P1A
 // CHECK:       icmp eq {{.*}}, null
 // CHECK-NEXT:  br i1
+
+void f10(A *x) { typeid((const A &)(A)*x); }
+// CHECK-LABEL: define void @_Z3f10P1A
+// CHECK-NOT:   icmp eq {{.*}}, null
-- 
GitLab