[cfe-commits] r124865 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/CXX/expr/expr.mptr.oper/p5.cpp

Douglas Gregor dgregor at apple.com
Fri Feb 4 04:57:49 PST 2011


Author: dgregor
Date: Fri Feb  4 06:57:49 2011
New Revision: 124865

URL: http://llvm.org/viewvc/llvm-project?rev=124865&view=rev
Log:
When calling a bound pointer to member function, check the
cv-qualifiers on the object against the cv-qualifiers on the member
function. Fixes PR8315.

Added:
    cfe/trunk/test/CXX/expr/expr.mptr.oper/p5.cpp   (with props)
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=124865&r1=124864&r2=124865&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Feb  4 06:57:49 2011
@@ -1585,6 +1585,8 @@
   "address non-type template argument cannot be surrounded by parentheses">;
 def err_pointer_to_member_type : Error<
   "invalid use of pointer to member type after %select{.*|->*}0">;
+def err_pointer_to_member_call_drops_quals : Error<
+  "call to pointer to member function of type %0 drops '%1' qualifier%s2">;
 def err_pointer_to_member_oper_value_classify: Error<
   "pointer-to-member function type %0 can only be called on an "
   "%select{rvalue|lvalue}1">;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=124865&r1=124864&r2=124865&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Feb  4 06:57:49 2011
@@ -4328,6 +4328,26 @@
           QualType ResultTy = FPT->getCallResultType(Context);
           ExprValueKind VK = Expr::getValueKindForType(FPT->getResultType());
 
+          // Check that the object type isn't more qualified than the
+          // member function we're calling.
+          Qualifiers FuncQuals = Qualifiers::fromCVRMask(FPT->getTypeQuals());
+          Qualifiers ObjectQuals 
+            = BO->getOpcode() == BO_PtrMemD
+                ? BO->getLHS()->getType().getQualifiers()
+                : BO->getLHS()->getType()->getAs<PointerType>()
+                                            ->getPointeeType().getQualifiers();
+
+          Qualifiers Difference = ObjectQuals - FuncQuals;
+          Difference.removeObjCGCAttr();
+          Difference.removeAddressSpace();
+          if (Difference) {
+            std::string QualsString = Difference.getAsString();
+            Diag(LParenLoc, diag::err_pointer_to_member_call_drops_quals)
+              << BO->getType().getUnqualifiedType()
+              << QualsString
+              << (QualsString.find(' ') == std::string::npos? 1 : 2);
+          }
+              
           CXXMemberCallExpr *TheCall
             = new (Context) CXXMemberCallExpr(Context, Fn, Args,
                                               NumArgs, ResultTy, VK,

Added: cfe/trunk/test/CXX/expr/expr.mptr.oper/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.mptr.oper/p5.cpp?rev=124865&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.mptr.oper/p5.cpp (added)
+++ cfe/trunk/test/CXX/expr/expr.mptr.oper/p5.cpp Fri Feb  4 06:57:49 2011
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X0 {
+  void f0();
+  void f1() const;
+  void f2() volatile;
+  void f3() const volatile;
+};
+
+void test_object_cvquals(void (X0::*pm)(),
+                         void (X0::*pmc)() const,
+                         void (X0::*pmv)() volatile,
+                         void (X0::*pmcv)() const volatile,
+                         X0 *p,
+                         const X0 *pc,
+                         volatile X0 *pv,
+                         const volatile X0 *pcv,
+                         X0 &o,
+                         const X0 &oc,
+                         volatile X0 &ov,
+                         const volatile X0 &ocv) {
+  (p->*pm)();
+  (p->*pmc)();
+  (p->*pmv)();
+  (p->*pmcv)();
+
+  (pc->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}}
+  (pc->*pmc)();
+  (pc->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+  (pc->*pmcv)();
+
+  (pv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}}
+  (pv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+  (pv->*pmv)();
+  (pv->*pmcv)();
+
+  (pcv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}}
+  (pcv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+  (pcv->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+  (pcv->*pmcv)();
+
+  (o.*pm)();
+  (o.*pmc)();
+  (o.*pmv)();
+  (o.*pmcv)();
+
+  (oc.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}}
+  (oc.*pmc)();
+  (oc.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+  (oc.*pmcv)();
+
+  (ov.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}}
+  (ov.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+  (ov.*pmv)();
+  (ov.*pmcv)();
+
+  (ocv.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}}
+  (ocv.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+  (ocv.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+  (ocv.*pmcv)();
+}

Propchange: cfe/trunk/test/CXX/expr/expr.mptr.oper/p5.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/expr/expr.mptr.oper/p5.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/expr/expr.mptr.oper/p5.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list