[cfe-commits] r124294 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprCXX.cpp test/CXX/expr/expr.mptr.oper/p6-0x.cpp
Douglas Gregor
dgregor at apple.com
Wed Jan 26 08:40:18 PST 2011
Author: dgregor
Date: Wed Jan 26 10:40:18 2011
New Revision: 124294
URL: http://llvm.org/viewvc/llvm-project?rev=124294&view=rev
Log:
Reference qualifiers for *this: implement C++0x [expr.mptr.oper]p6,
the restrictions on .* and ->* for ref-qualified pointer-to-member
functions.
Added:
cfe/trunk/test/CXX/expr/expr.mptr.oper/p6-0x.cpp (with props)
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExprCXX.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=124294&r1=124293&r2=124294&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jan 26 10:40:18 2011
@@ -1581,6 +1581,9 @@
"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_oper_value_classify: Error<
+ "pointer-to-member function type %0 can only be called on an "
+ "%select{rvalue|lvalue}1">;
// C++ template specialization
def err_template_spec_unknown_kind : Error<
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=124294&r1=124293&r2=124294&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Jan 26 10:40:18 2011
@@ -2557,6 +2557,32 @@
QualType Result = MemPtr->getPointeeType();
Result = Context.getCVRQualifiedType(Result, LType.getCVRQualifiers());
+ // C++0x [expr.mptr.oper]p6:
+ // In a .* expression whose object expression is an rvalue, the program is
+ // ill-formed if the second operand is a pointer to member function with
+ // ref-qualifier &. In a ->* expression or in a .* expression whose object
+ // expression is an lvalue, the program is ill-formed if the second operand
+ // is a pointer to member function with ref-qualifier &&.
+ if (const FunctionProtoType *Proto = Result->getAs<FunctionProtoType>()) {
+ switch (Proto->getRefQualifier()) {
+ case RQ_None:
+ // Do nothing
+ break;
+
+ case RQ_LValue:
+ if (!isIndirect && !lex->Classify(Context).isLValue())
+ Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
+ << RType << 1 << lex->getSourceRange();
+ break;
+
+ case RQ_RValue:
+ if (isIndirect || !lex->Classify(Context).isRValue())
+ Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
+ << RType << 0 << lex->getSourceRange();
+ break;
+ }
+ }
+
// C++ [expr.mptr.oper]p6:
// The result of a .* expression whose second operand is a pointer
// to a data member is of the same value category as its
Added: cfe/trunk/test/CXX/expr/expr.mptr.oper/p6-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.mptr.oper/p6-0x.cpp?rev=124294&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.mptr.oper/p6-0x.cpp (added)
+++ cfe/trunk/test/CXX/expr/expr.mptr.oper/p6-0x.cpp Wed Jan 26 10:40:18 2011
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct X { };
+
+template<typename T> T& lvalue();
+template<typename T> T&& xvalue();
+template<typename T> T prvalue();
+
+// In a .* expression whose object expression is an rvalue, the
+// program is ill-formed if the second operand is a pointer to member
+// function with ref-qualifier &. In a ->* expression or in a .*
+// expression whose object expression is an lvalue, the program is
+// ill-formed if the second operand is a pointer to member function
+// with ref-qualifier &&.
+void test(X *xp, int (X::*pmf)(int), int (X::*l_pmf)(int) &,
+ int (X::*r_pmf)(int) &&) {
+ // No ref-qualifier.
+ (lvalue<X>().*pmf)(17);
+ (xvalue<X>().*pmf)(17);
+ (prvalue<X>().*pmf)(17);
+ (xp->*pmf)(17);
+
+ // Lvalue ref-qualifier.
+ (lvalue<X>().*l_pmf)(17);
+ (xvalue<X>().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}}
+ (prvalue<X>().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}}
+ (xp->*l_pmf)(17);
+
+ // Rvalue ref-qualifier.
+ (lvalue<X>().*r_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}}
+ (xvalue<X>().*r_pmf)(17);
+ (prvalue<X>().*r_pmf)(17);
+ (xp->*r_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}}
+}
Propchange: cfe/trunk/test/CXX/expr/expr.mptr.oper/p6-0x.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CXX/expr/expr.mptr.oper/p6-0x.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CXX/expr/expr.mptr.oper/p6-0x.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list