erikjv created this revision.

This is actually a failing assert. When doing object argument
initialization, it is valid to have e.g. 'this' as a base in a member
access expression (which is a prvalue). It's also possible to have a
scope specifier as part of the member expression, in which case a base
that is an actual lvalue gets wrapped in an ImplicitCastExpr, which in
turn is an rvalue.


https://reviews.llvm.org/D40640

Files:
  lib/Sema/SemaOverload.cpp
  test/CodeCompletion/member-access.cpp

Index: test/CodeCompletion/member-access.cpp
===================================================================
--- test/CodeCompletion/member-access.cpp
+++ test/CodeCompletion/member-access.cpp
@@ -42,10 +42,19 @@
   static void foo(bool);
 };
 
-struct Bar {
+struct Bar: Foo {
   void foo(bool param) {
     Foo::foo(  );// unresolved member expression with an implicit base
   }
+
+  void mooze(bool param) {
+    this->Foo::foo(  );// unresolved member expression with an explicit base
+  }
+
+  void mooze(bool param, int anotherParam) {
+    Bar *that = new Bar;
+    that->Foo::foo(  );// unresolved member expression with an explicit base wrapped in a ImplicitCastExpr
+  }
 };
 
   // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:29:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
@@ -66,6 +75,8 @@
 
 // Make sure this also doesn't crash
 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:47:14 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:51:21 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:56:21 %s
 
 
 template<typename T>
@@ -100,8 +111,8 @@
 // CHECK-CC2: overload1 : [#void#]overload1(<#const T &#>)
 // CHECK-CC2: overload1 : [#void#]overload1(<#const S &#>)
 
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:92:10 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:93:12 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:103:10 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:104:12 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
 }
 
 
@@ -118,8 +129,8 @@
 // CHECK-CC3: overload1 : [#void#]overload1(<#const int &#>)
 // CHECK-CC3: overload1 : [#void#]overload1(<#const double &#>)
 
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:110:10 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:111:12 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:121:10 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:122:12 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
 }
 
 template <typename T>
@@ -133,17 +144,17 @@
 // CHECK-CC4: BaseTemplate : BaseTemplate::
 // CHECK-CC4: baseTemplateField : [#int#]baseTemplateField
 // CHECK-CC4: baseTemplateFunction : [#int#]baseTemplateFunction()
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:132:8 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:143:8 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
     o2.baseTemplateField;
 // CHECK-CC5: BaseTemplate : BaseTemplate::
 // CHECK-CC5: baseTemplateField : [#T#]baseTemplateField
 // CHECK-CC5: baseTemplateFunction : [#T#]baseTemplateFunction()
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:137:8 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:148:8 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s
     this->o1;
 // CHECK-CC6: [#void#]function()
 // CHECK-CC6: o1 : [#BaseTemplate<int>#]o1
 // CHECK-CC6: o2 : [#BaseTemplate<T>#]o2
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:142:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:153:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s
   }
 
   static void staticFn(T &obj);
@@ -160,7 +171,7 @@
 // CHECK-CC7: o2 : [#BaseTemplate<T>#]o2
 // CHECK-CC7: staticFn : [#void#]staticFn(<#T &obj#>)
 // CHECK-CC7: Template : Template
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:156:16 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:167:16 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
   typename Template<T>::Nested m;
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:164:25 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:175:25 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
 }
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -5023,14 +5023,9 @@
   ImplicitConversionSequence ICS;
 
   // We need to have an object of class type.
-  if (const PointerType *PT = FromType->getAs<PointerType>()) {
+  if (const PointerType *PT = FromType->getAs<PointerType>())
     FromType = PT->getPointeeType();
 
-    // When we had a pointer, it's implicitly dereferenced, so we
-    // better have an lvalue.
-    assert(FromClassification.isLValue());
-  }
-
   assert(FromType->isRecordType());
 
   // C++0x [over.match.funcs]p4:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to