]> granicus.if.org Git - clang/commitdiff
Add negative test cases and fix diagnostics for member pointer dereferencing.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 7 Feb 2009 00:41:42 +0000 (00:41 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 7 Feb 2009 00:41:42 +0000 (00:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63987 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.def
lib/Sema/SemaExpr.cpp
test/SemaCXX/member-pointer.cpp

index 298e0fe272704214055f5169679ebc1a8164af25..a18ed966f3b925e79f3ac98c7655507ecce428a4 100644 (file)
@@ -867,8 +867,8 @@ DIAG(err_bad_memptr_rhs, ERROR,
      "right hand operand to %0 must be a pointer to member of a complete class "
      "but is %1")
 DIAG(err_bad_memptr_lhs, ERROR,
-     "left hand operand to ->* must be a %select{|pointer to }0class "
-     "compatible with the right hand operand, but is %1")
+     "left hand operand to %0 must be a %select{|pointer to }1class "
+     "compatible with the right hand operand, but is %2")
 
 DIAG(err_invalid_use_of_function_type, ERROR,
      "a function type is not allowed here")
index 3de916fe3cd2f40b93cb7663d96572ba7fabc853..201a0f99e3367e0edc2072b615419c4de06cf2be 100644 (file)
@@ -2731,7 +2731,7 @@ inline QualType Sema::CheckPointerToMemberOperands(
       LType = Ptr->getPointeeType().getNonReferenceType();
     else {
       Diag(Loc, diag::err_bad_memptr_lhs)
-        << 1 << LType << lex->getSourceRange();
+        << OpSpelling << 1 << LType << lex->getSourceRange();
       return QualType();
     }
   }
@@ -2744,7 +2744,7 @@ inline QualType Sema::CheckPointerToMemberOperands(
     // or is that overkill?
     if (!IsDerivedFrom(LType, Class, Paths) ||
         Paths.isAmbiguous(Context.getCanonicalType(Class))) {
-      Diag(Loc, diag::err_bad_memptr_lhs)
+      Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling
         << (int)isIndirect << lex->getType() << lex->getSourceRange();
       return QualType();
     }
index 7d71b49fca9175815a84bf41273bea6f29bc3908..449ff9f73d8c855b8061ae2f01ba15270bd41d25 100644 (file)
@@ -80,6 +80,8 @@ void g() {
   void (HasMembers::*pmd)() = &HasMembers::d;
 }
 
+struct Incomplete;
+
 void h() {
   HasMembers hm, *phm = &hm;
 
@@ -93,6 +95,27 @@ void h() {
   void (HasMembers::*pf)() = &HasMembers::f;
   (hm.*pf)();
   (phm->*pf)();
+
+  (void)(hm->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct HasMembers'}}
+  (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct HasMembers *'}}
+  (void)(i.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}}
+  int *ptr;
+  (void)(ptr->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}}
+
+  int A::*pai = 0;
+  D d, *pd = &d;
+  (void)(d.*pai);
+  (void)(pd->*pai);
+  F f, *ptrf = &f;
+  (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct F'}}
+  (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct F *'}}
+
+  (void)(hm.*i); // expected-error {{right hand operand to .* must be a pointer to member of a complete class but is 'int'}}
+  (void)(phm->*i); // expected-error {{right hand operand to ->* must be a pointer to member of a complete class but is 'int'}}
+
+  Incomplete *inc;
+  int Incomplete::*pii = 0;
+  (void)inc->*pii; // expected-error {{right hand operand to ->* must be a pointer to member of a complete class but is 'int struct Incomplete::*'}}
 }
 
 struct OverloadsPtrMem