[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