]> granicus.if.org Git - clang/commitdiff
Perform lvalue-to-rvalue conversions on both operands of ->*
authorJohn McCall <rjmccall@apple.com>
Thu, 30 Jun 2011 17:15:34 +0000 (17:15 +0000)
committerJohn McCall <rjmccall@apple.com>
Thu, 30 Jun 2011 17:15:34 +0000 (17:15 +0000)
and the RHS of .*.  Noticed by Enea Zaffanella!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134170 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExprCXX.cpp
test/SemaCXX/member-pointer.cpp

index 100681df5e6394e4d46d315b25d852bf86c826d3..8dc9ceef9f86304ad41ae764e507b4f08bcd338b 100644 (file)
@@ -3168,6 +3168,20 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &lex, ExprResult &rex,
                                             ExprValueKind &VK,
                                             SourceLocation Loc,
                                             bool isIndirect) {
+  assert(!lex.get()->getType()->isPlaceholderType() &&
+         !rex.get()->getType()->isPlaceholderType() &&
+         "placeholders should have been weeded out by now");
+
+  // The LHS undergoes lvalue conversions if this is ->*.
+  if (isIndirect) {
+    lex = DefaultLvalueConversion(lex.take());
+    if (lex.isInvalid()) return QualType();
+  }
+
+  // The RHS always undergoes lvalue conversions.
+  rex = DefaultLvalueConversion(rex.take());
+  if (rex.isInvalid()) return QualType();
+
   const char *OpSpelling = isIndirect ? "->*" : ".*";
   // C++ 5.5p2
   //   The binary operator .* [p3: ->*] binds its second operand, which shall
index de3b211acf50076f509e857a1c82eaa4c37933c0..cf6481015a823eb157b0403ea90c7106869a2cb9 100644 (file)
@@ -296,3 +296,19 @@ namespace PR9973 {
     mem_fn(&test::nullary_v)(t); // expected-note{{in instantiation of}}
   }
 }
+
+namespace test8 {
+  struct A { int foo; };
+  int test1() {
+    // Verify that we perform (and check) an lvalue conversion on the operands here.
+    return (*((A**) 0)) // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
+             ->**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
+  }
+
+  int test2() {
+    // Verify that we perform (and check) an lvalue conversion on the operands here.
+    // TODO: the .* should itself warn about being a dereference of null.
+    return (*((A*) 0))
+             .**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
+  }
+}