expression-traits.cpp revision 552622067dc45013d240f73952fece703f5e63bd
1552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// RUN: %clang_cc1 -fsyntax-only -verify -fcxx-exceptions %s 2552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 3552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// 4552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// Tests for "expression traits" intrinsics such as __is_lvalue_expr. 5552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// 6552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// For the time being, these tests are written against the 2003 C++ 7552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// standard (ISO/IEC 14882:2003 -- see draft at 8552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2001/n1316/). 9552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// 10552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// C++0x has its own, more-refined, idea of lvalues and rvalues. 11552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// If/when we need to support those, we'll need to track both 12552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// standard documents. 13552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 14552622067dc45013d240f73952fece703f5e63bdJohn Wiegley#if !__has_feature(cxx_static_assert) 15552622067dc45013d240f73952fece703f5e63bdJohn Wiegley# define CONCAT_(X_, Y_) CONCAT1_(X_, Y_) 16552622067dc45013d240f73952fece703f5e63bdJohn Wiegley# define CONCAT1_(X_, Y_) X_ ## Y_ 17552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 18552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// This emulation can be used multiple times on one line (and thus in 19552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// a macro), except at class scope 20552622067dc45013d240f73952fece703f5e63bdJohn Wiegley# define static_assert(b_, m_) \ 21552622067dc45013d240f73952fece703f5e63bdJohn Wiegley typedef int CONCAT_(sa_, __LINE__)[b_ ? 1 : -1] 22552622067dc45013d240f73952fece703f5e63bdJohn Wiegley#endif 23552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 24552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// Tests are broken down according to section of the C++03 standard 25552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// (ISO/IEC 14882:2003(E)) 26552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 27552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// Assertion macros encoding the following two paragraphs 28552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// 29552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// basic.lval/1 Every expression is either an lvalue or an rvalue. 30552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// 31552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// expr.prim/5 A parenthesized expression is a primary expression whose type 32552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// and value are identical to those of the enclosed expression. The 33552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// presence of parentheses does not affect whether the expression is 34552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// an lvalue. 35552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// 36552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// Note: these asserts cannot be made at class scope in C++03. Put 37552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// them in a member function instead. 38552622067dc45013d240f73952fece703f5e63bdJohn Wiegley#define ASSERT_LVALUE(expr) \ 39552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(__is_lvalue_expr(expr), "should be an lvalue"); \ 40552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(__is_lvalue_expr((expr)), \ 41552622067dc45013d240f73952fece703f5e63bdJohn Wiegley "the presence of parentheses should have" \ 42552622067dc45013d240f73952fece703f5e63bdJohn Wiegley " no effect on lvalueness (expr.prim/5)"); \ 43552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(!__is_rvalue_expr(expr), "should be an lvalue"); \ 44552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(!__is_rvalue_expr((expr)), \ 45552622067dc45013d240f73952fece703f5e63bdJohn Wiegley "the presence of parentheses should have" \ 46552622067dc45013d240f73952fece703f5e63bdJohn Wiegley " no effect on lvalueness (expr.prim/5)") 47552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 48552622067dc45013d240f73952fece703f5e63bdJohn Wiegley#define ASSERT_RVALUE(expr); \ 49552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(__is_rvalue_expr(expr), "should be an rvalue"); \ 50552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(__is_rvalue_expr((expr)), \ 51552622067dc45013d240f73952fece703f5e63bdJohn Wiegley "the presence of parentheses should have" \ 52552622067dc45013d240f73952fece703f5e63bdJohn Wiegley " no effect on lvalueness (expr.prim/5)"); \ 53552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(!__is_lvalue_expr(expr), "should be an rvalue"); \ 54552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(!__is_lvalue_expr((expr)), \ 55552622067dc45013d240f73952fece703f5e63bdJohn Wiegley "the presence of parentheses should have" \ 56552622067dc45013d240f73952fece703f5e63bdJohn Wiegley " no effect on lvalueness (expr.prim/5)") 57552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 58552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyenum Enum { Enumerator }; 59552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 60552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyint ReturnInt(); 61552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid ReturnVoid(); 62552622067dc45013d240f73952fece703f5e63bdJohn WiegleyEnum ReturnEnum(); 63552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 64552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid basic_lval_5() 65552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 66552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // basic.lval/5: The result of calling a function that does not return 67552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // a reference is an rvalue. 68552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(ReturnInt()); 69552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(ReturnVoid()); 70552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(ReturnEnum()); 71552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 72552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 73552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyint& ReturnIntReference(); 74552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyextern Enum& ReturnEnumReference(); 75552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 76552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid basic_lval_6() 77552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 78552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // basic.lval/6: An expression which holds a temporary object resulting 79552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // from a cast to a nonreference type is an rvalue (this includes 80552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // the explicit creation of an object using functional notation 81552622067dc45013d240f73952fece703f5e63bdJohn Wiegley struct IntClass 82552622067dc45013d240f73952fece703f5e63bdJohn Wiegley { 83552622067dc45013d240f73952fece703f5e63bdJohn Wiegley explicit IntClass(int = 0); 84552622067dc45013d240f73952fece703f5e63bdJohn Wiegley IntClass(char const*); 85552622067dc45013d240f73952fece703f5e63bdJohn Wiegley operator int() const; 86552622067dc45013d240f73952fece703f5e63bdJohn Wiegley }; 87552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 88552622067dc45013d240f73952fece703f5e63bdJohn Wiegley struct ConvertibleToIntClass 89552622067dc45013d240f73952fece703f5e63bdJohn Wiegley { 90552622067dc45013d240f73952fece703f5e63bdJohn Wiegley operator IntClass() const; 91552622067dc45013d240f73952fece703f5e63bdJohn Wiegley }; 92552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 93552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ConvertibleToIntClass b; 94552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 95552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // Make sure even trivial conversions are not detected as lvalues 96552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int intLvalue = 0; 97552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE((int)intLvalue); 98552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE((short)intLvalue); 99552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE((long)intLvalue); 100552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 101552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // Same tests with function-call notation 102552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(int(intLvalue)); 103552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(short(intLvalue)); 104552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(long(intLvalue)); 105552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 106552622067dc45013d240f73952fece703f5e63bdJohn Wiegley char charLValue = 'x'; 107552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE((signed char)charLValue); 108552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE((unsigned char)charLValue); 109552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 110552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(static_cast<int>(IntClass())); 111552622067dc45013d240f73952fece703f5e63bdJohn Wiegley IntClass intClassLValue; 112552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(static_cast<int>(intClassLValue)); 113552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(static_cast<IntClass>(ConvertibleToIntClass())); 114552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ConvertibleToIntClass convertibleToIntClassLValue; 115552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(static_cast<IntClass>(convertibleToIntClassLValue)); 116552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 117552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 118552622067dc45013d240f73952fece703f5e63bdJohn Wiegley typedef signed char signed_char; 119552622067dc45013d240f73952fece703f5e63bdJohn Wiegley typedef unsigned char unsigned_char; 120552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(signed_char(charLValue)); 121552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(unsigned_char(charLValue)); 122552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 123552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(int(IntClass())); 124552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(int(intClassLValue)); 125552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(IntClass(ConvertibleToIntClass())); 126552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(IntClass(convertibleToIntClassLValue)); 127552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 128552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 129552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid conv_ptr_1() 130552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 131552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // conv.ptr/1: A null pointer constant is an integral constant 132552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expression (5.19) rvalue of integer type that evaluates to 133552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // zero. 134552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(0); 135552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 136552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 137552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_6() 138552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 139552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr/6: If an expression initially has the type “reference to T” 140552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // (8.3.2, 8.5.3), ... the expression is an lvalue. 141552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int x = 0; 142552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int& referenceToInt = x; 143552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(referenceToInt); 144552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(ReturnIntReference()); 145552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 146552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 147552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_prim_2() 148552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 149552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // 5.1/2 A string literal is an lvalue; all other 150552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // literals are rvalues. 151552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE("foo"); 152552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(1); 153552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(1.2); 154552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(10UL); 155552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 156552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 157552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_prim_3() 158552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 159552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // 5.1/3: The keyword "this" names a pointer to the object for 160552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // which a nonstatic member function (9.3.2) is invoked. ...The 161552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expression is an rvalue. 162552622067dc45013d240f73952fece703f5e63bdJohn Wiegley struct ThisTest 163552622067dc45013d240f73952fece703f5e63bdJohn Wiegley { 164552622067dc45013d240f73952fece703f5e63bdJohn Wiegley void f() { ASSERT_RVALUE(this); } 165552622067dc45013d240f73952fece703f5e63bdJohn Wiegley }; 166552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 167552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 168552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyextern int variable; 169552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid Function(); 170552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 171552622067dc45013d240f73952fece703f5e63bdJohn Wiegleystruct BaseClass 172552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 173552622067dc45013d240f73952fece703f5e63bdJohn Wiegley virtual ~BaseClass(); 174552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 175552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int BaseNonstaticMemberFunction(); 176552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static int BaseStaticMemberFunction(); 177552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int baseDataMember; 178552622067dc45013d240f73952fece703f5e63bdJohn Wiegley}; 179552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 180552622067dc45013d240f73952fece703f5e63bdJohn Wiegleystruct Class : BaseClass 181552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 182552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static void function(); 183552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static int variable; 184552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 185552622067dc45013d240f73952fece703f5e63bdJohn Wiegley template <class T> 186552622067dc45013d240f73952fece703f5e63bdJohn Wiegley struct NestedClassTemplate {}; 187552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 188552622067dc45013d240f73952fece703f5e63bdJohn Wiegley template <class T> 189552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static int& NestedFuncTemplate() { return variable; } // expected-note{{candidate function}} 190552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 191552622067dc45013d240f73952fece703f5e63bdJohn Wiegley template <class T> 192552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int& NestedMemfunTemplate() { return variable; } // expected-note{{candidate function}} 193552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 194552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int operator*() const; 195552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 196552622067dc45013d240f73952fece703f5e63bdJohn Wiegley template <class T> 197552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int operator+(T) const; // expected-note{{candidate function}} 198552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 199552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int NonstaticMemberFunction(); 200552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static int StaticMemberFunction(); 201552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int dataMember; 202552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 203552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int& referenceDataMember; 204552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static int& staticReferenceDataMember; 205552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static int staticNonreferenceDataMember; 206552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 207552622067dc45013d240f73952fece703f5e63bdJohn Wiegley enum Enum { Enumerator }; 208552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 209552622067dc45013d240f73952fece703f5e63bdJohn Wiegley operator long() const; 210552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 211552622067dc45013d240f73952fece703f5e63bdJohn Wiegley Class(); 212552622067dc45013d240f73952fece703f5e63bdJohn Wiegley Class(int,int); 213552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 214552622067dc45013d240f73952fece703f5e63bdJohn Wiegley void expr_prim_4() 215552622067dc45013d240f73952fece703f5e63bdJohn Wiegley { 216552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // 5.1/4: The operator :: followed by an identifier, a 217552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // qualified-id, or an operator-function-id is a primary- 218552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expression. ...The result is an lvalue if the entity is 219552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // a function or variable. 220552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(::Function); // identifier: function 221552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(::variable); // identifier: variable 222552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 223552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // the only qualified-id form that can start without "::" (and thus 224552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // be legal after "::" ) is 225552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // 226552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // ::<sub>opt</sub> nested-name-specifier template<sub>opt</sub> unqualified-id 227552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(::Class::function); // qualified-id: function 228552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(::Class::variable); // qualified-id: variable 229552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 230552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // The standard doesn't give a clear answer about whether these 231552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // should really be lvalues or rvalues without some surrounding 232552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // context that forces them to be interpreted as naming a 233552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // particular function template specialization (that situation 234552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // doesn't come up in legal pure C++ programs). This language 235552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // extension simply rejects them as requiring additional context 236552622067dc45013d240f73952fece703f5e63bdJohn Wiegley __is_lvalue_expr(::Class::NestedFuncTemplate); // qualified-id: template \ 237552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expected-error{{cannot resolve overloaded function 'NestedFuncTemplate' from context}} 238552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 239552622067dc45013d240f73952fece703f5e63bdJohn Wiegley __is_lvalue_expr(::Class::NestedMemfunTemplate); // qualified-id: template \ 240552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expected-error{{cannot resolve overloaded function 'NestedMemfunTemplate' from context}} 241552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 242552622067dc45013d240f73952fece703f5e63bdJohn Wiegley __is_lvalue_expr(::Class::operator+); // operator-function-id: template \ 243552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expected-error{{cannot resolve overloaded function 'operator+' from context}} 244552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 245552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(::Class::operator*); // operator-function-id: member function 246552622067dc45013d240f73952fece703f5e63bdJohn Wiegley } 247552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 248552622067dc45013d240f73952fece703f5e63bdJohn Wiegley void expr_prim_7() 249552622067dc45013d240f73952fece703f5e63bdJohn Wiegley { 250552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.prim/7 An identifier is an id-expression provided it has been 251552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // suitably declared (clause 7). [Note: ... ] The type of the 252552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expression is the type of the identifier. The result is the 253552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // entity denoted by the identifier. The result is an lvalue if 254552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // the entity is a function, variable, or data member... (cont'd) 255552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Function); // identifier: function 256552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(StaticMemberFunction); // identifier: function 257552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(variable); // identifier: variable 258552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(dataMember); // identifier: data member 259552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(NonstaticMemberFunction); // identifier: member function 260552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 261552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // (cont'd)...A nested-name-specifier that names a class, 262552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // optionally followed by the keyword template (14.2), and then 263552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // followed by the name of a member of either that class (9.2) or 264552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // one of its base classes... is a qualified-id... The result is 265552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // the member. The type of the result is the type of the 266552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // member. The result is an lvalue if the member is a static 267552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // member function or a data member. 268552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Class::dataMember); 269552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Class::StaticMemberFunction); 270552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(Class::NonstaticMemberFunction); // identifier: member function 271552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 272552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Class::baseDataMember); 273552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Class::BaseStaticMemberFunction); 274552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(Class::BaseNonstaticMemberFunction); // identifier: member function 275552622067dc45013d240f73952fece703f5e63bdJohn Wiegley } 276552622067dc45013d240f73952fece703f5e63bdJohn Wiegley}; 277552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 278552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_call_10() 279552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 280552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.call/10: A function call is an lvalue if and only if the 281552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // result type is a reference. This statement is partially 282552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // redundant with basic.lval/5 283552622067dc45013d240f73952fece703f5e63bdJohn Wiegley basic_lval_5(); 284552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 285552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(ReturnIntReference()); 286552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(ReturnEnumReference()); 287552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 288552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 289552622067dc45013d240f73952fece703f5e63bdJohn Wiegleynamespace Namespace 290552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 291552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int x; 292552622067dc45013d240f73952fece703f5e63bdJohn Wiegley void function(); 293552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 294552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 295552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_prim_8() 296552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 297552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.prim/8 A nested-name-specifier that names a namespace 298552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // (7.3), followed by the name of a member of that namespace (or 299552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // the name of a member of a namespace made visible by a 300552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // using-directive ) is a qualified-id; 3.4.3.2 describes name 301552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // lookup for namespace members that appear in qualified-ids. The 302552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // result is the member. The type of the result is the type of the 303552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // member. The result is an lvalue if the member is a function or 304552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // a variable. 305552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Namespace::x); 306552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Namespace::function); 307552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 308552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 309552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_sub_1(int* pointer) 310552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 311552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.sub/1 A postfix expression followed by an expression in 312552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // square brackets is a postfix expression. One of the expressions 313552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // shall have the type “pointer to T” and the other shall have 314552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // enumeration or integral type. The result is an lvalue of type 315552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // “T.” 316552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(pointer[1]); 317552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 318552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // The expression E1[E2] is identical (by definition) to *((E1)+(E2)). 319552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(*(pointer+1)); 320552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 321552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 322552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_type_conv_1() 323552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 324552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.type.conv/1 A simple-type-specifier (7.1.5) followed by a 325552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // parenthesized expression-list constructs a value of the specified 326552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // type given the expression list. ... If the expression list 327552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // specifies more than a single value, the type shall be a class with 328552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // a suitably declared constructor (8.5, 12.1), and the expression 329552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, 330552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // x2, ...); for some invented temporary variable t, with the result 331552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // being the value of t as an rvalue. 332552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(Class(2,2)); 333552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 334552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 335552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_type_conv_2() 336552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 337552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.type.conv/2 The expression T(), where T is a 338552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // simple-type-specifier (7.1.5.2) for a non-array complete object 339552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // type or the (possibly cv-qualified) void type, creates an 340552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // rvalue of the specified type, 341552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(int()); 342552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(Class()); 343552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(void()); 344552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 345552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 346552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 347552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_ref_4() 348552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 349552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // Applies to expressions of the form E1.E2 350552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 351552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // If E2 is declared to have type “reference to T”, then E1.E2 is 352552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // an lvalue;.... Otherwise, one of the following rules applies. 353552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Class().staticReferenceDataMember); 354552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Class().referenceDataMember); 355552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 356552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // — If E2 is a static data member, and the type of E2 is T, then 357552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // E1.E2 is an lvalue; ... 358552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Class().staticNonreferenceDataMember); 359552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Class().staticReferenceDataMember); 360552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 361552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 362552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // — If E2 is a non-static data member, ... If E1 is an lvalue, 363552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // then E1.E2 is an lvalue... 364552622067dc45013d240f73952fece703f5e63bdJohn Wiegley Class lvalue; 365552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(lvalue.dataMember); 366552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(Class().dataMember); 367552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 368552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // — If E1.E2 refers to a static member function, ... then E1.E2 369552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // is an lvalue 370552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(Class().StaticMemberFunction); 371552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 372552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // — Otherwise, if E1.E2 refers to a non-static member function, 373552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // then E1.E2 is not an lvalue. 374552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(Class().NonstaticMemberFunction); 375552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 376552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // — If E2 is a member enumerator, and the type of E2 is T, the 377552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expression E1.E2 is not an lvalue. The type of E1.E2 is T. 378552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(Class().Enumerator); 379552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(lvalue.Enumerator); 380552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 381552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 382552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 383552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_post_incr_1(int x) 384552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 385552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.post.incr/1 The value obtained by applying a postfix ++ is 386552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // the value that the operand had before applying the 387552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // operator... The result is an rvalue. 388552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(x++); 389552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 390552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 391552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_dynamic_cast_2() 392552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 393552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.dynamic.cast/2: If T is a pointer type, v shall be an 394552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // rvalue of a pointer to complete class type, and the result is 395552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // an rvalue of type T. 396552622067dc45013d240f73952fece703f5e63bdJohn Wiegley Class instance; 397552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(dynamic_cast<Class*>(&instance)); 398552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 399552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // If T is a reference type, v shall be an 400552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // lvalue of a complete class type, and the result is an lvalue of 401552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // the type referred to by T. 402552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(dynamic_cast<Class&>(instance)); 403552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 404552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 405552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_dynamic_cast_5() 406552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 407552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.dynamic.cast/5: If T is “reference to cv1 B” and v has type 408552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // “cv2 D” such that B is a base class of D, the result is an 409552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // lvalue for the unique B sub-object of the D object referred 410552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // to by v. 411552622067dc45013d240f73952fece703f5e63bdJohn Wiegley typedef BaseClass B; 412552622067dc45013d240f73952fece703f5e63bdJohn Wiegley typedef Class D; 413552622067dc45013d240f73952fece703f5e63bdJohn Wiegley D object; 414552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(dynamic_cast<B&>(object)); 415552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 416552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 417552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// expr.dynamic.cast/8: The run-time check logically executes as follows: 418552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// 419552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// — If, in the most derived object pointed (referred) to by v, v 420552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// points (refers) to a public base class subobject of a T object, and 421552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// if only one object of type T is derived from the sub-object pointed 422552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// (referred) to by v, the result is a pointer (an lvalue referring) 423552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// to that T object. 424552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// 425552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// — Otherwise, if v points (refers) to a public base class sub-object 426552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// of the most derived object, and the type of the most derived object 427552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// has a base class, of type T, that is unambiguous and public, the 428552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// result is a pointer (an lvalue referring) to the T sub-object of 429552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// the most derived object. 430552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// 431552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// The mention of "lvalue" in the text above appears to be a 432552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// defect that is being corrected by the response to UK65 (see 433552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2841.html). 434552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 435552622067dc45013d240f73952fece703f5e63bdJohn Wiegley#if 0 436552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_typeid_1() 437552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 438552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.typeid/1: The result of a typeid expression is an lvalue... 439552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(typeid(1)); 440552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 441552622067dc45013d240f73952fece703f5e63bdJohn Wiegley#endif 442552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 443552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_static_cast_1(int x) 444552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 445552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.static.cast/1: The result of the expression 446552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // static_cast<T>(v) is the result of converting the expression v 447552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // to type T. If T is a reference type, the result is an lvalue; 448552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // otherwise, the result is an rvalue. 449552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(static_cast<int&>(x)); 450552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(static_cast<int>(x)); 451552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 452552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 453552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_reinterpret_cast_1() 454552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 455552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.reinterpret.cast/1: The result of the expression 456552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // reinterpret_cast<T>(v) is the result of converting the 457552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expression v to type T. If T is a reference type, the result is 458552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // an lvalue; otherwise, the result is an rvalue 459552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(reinterpret_cast<int*>(0)); 460552622067dc45013d240f73952fece703f5e63bdJohn Wiegley char const v = 0; 461552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(reinterpret_cast<char const&>(v)); 462552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 463552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 464552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_unary_op_1(int* pointer, struct incomplete* pointerToIncompleteType) 465552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 466552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.unary.op/1: The unary * operator performs indirection: the 467552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expression to which it is applied shall be a pointer to an 468552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // object type, or a pointer to a function type and the result is 469552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // an lvalue referring to the object or function to which the 470552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expression points. 471552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(*pointer); 472552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(*Function); 473552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 474552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // [Note: a pointer to an incomplete type 475552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // (other than cv void ) can be dereferenced. ] 476552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(*pointerToIncompleteType); 477552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 478552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 479552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_pre_incr_1(int operand) 480552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 481552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.pre.incr/1: The operand of prefix ++ ... shall be a 482552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // modifiable lvalue.... The value is the new value of the 483552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // operand; it is an lvalue. 484552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(++operand); 485552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 486552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 487552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_cast_1(int x) 488552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 489552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.cast/1: The result of the expression (T) cast-expression 490552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // is of type T. The result is an lvalue if T is a reference type, 491552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // otherwise the result is an rvalue. 492552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE((void(&)())expr_cast_1); 493552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE((int&)x); 494552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE((void(*)())expr_cast_1); 495552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE((int)x); 496552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 497552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 498552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_mptr_oper() 499552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 500552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.mptr.oper/6: The result of a .* expression is an lvalue 501552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // only if its first operand is an lvalue and its second operand 502552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // is a pointer to data member... (cont'd) 503552622067dc45013d240f73952fece703f5e63bdJohn Wiegley typedef Class MakeRValue; 504552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(MakeRValue().*(&Class::dataMember)); 505552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(MakeRValue().*(&Class::NonstaticMemberFunction)); 506552622067dc45013d240f73952fece703f5e63bdJohn Wiegley Class lvalue; 507552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(lvalue.*(&Class::dataMember)); 508552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(lvalue.*(&Class::NonstaticMemberFunction)); 509552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 510552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // (cont'd)...The result of an ->* expression is an lvalue only 511552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // if its second operand is a pointer to data member. If the 512552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // second operand is the null pointer to member value (4.11), the 513552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // behavior is undefined. 514552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE((&lvalue)->*(&Class::dataMember)); 515552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE((&lvalue)->*(&Class::NonstaticMemberFunction)); 516552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 517552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 518552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_cond(bool cond) 519552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 520552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // 5.16 Conditional operator [expr.cond] 521552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // 522552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // 2 If either the second or the third operand has type (possibly 523552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // cv-qualified) void, then the lvalue-to-rvalue (4.1), 524552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // array-to-pointer (4.2), and function-to-pointer (4.3) standard 525552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // conversions are performed on the second and third operands, and one 526552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // of the following shall hold: 527552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // 528552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // — The second or the third operand (but not both) is a 529552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // throw-expression (15.1); the result is of the type of the other and 530552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // is an rvalue. 531552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 532552622067dc45013d240f73952fece703f5e63bdJohn Wiegley Class classLvalue; 533552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? throw 1 : (void)0); 534552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? (void)0 : throw 1); 535552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? throw 1 : classLvalue); 536552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? classLvalue : throw 1); 537552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 538552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // — Both the second and the third operands have type void; the result 539552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // is of type void and is an rvalue. [Note: this includes the case 540552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // where both operands are throw-expressions. ] 541552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? (void)1 : (void)0); 542552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? throw 1 : throw 0); 543552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 544552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.cond/4: If the second and third operands are lvalues and 545552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // have the same type, the result is of that type and is an 546552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // lvalue. 547552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(cond ? classLvalue : classLvalue); 548552622067dc45013d240f73952fece703f5e63bdJohn Wiegley int intLvalue = 0; 549552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(cond ? intLvalue : intLvalue); 550552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 551552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.cond/5:Otherwise, the result is an rvalue. 552552622067dc45013d240f73952fece703f5e63bdJohn Wiegley typedef Class MakeRValue; 553552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? MakeRValue() : classLvalue); 554552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? classLvalue : MakeRValue()); 555552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? MakeRValue() : MakeRValue()); 556552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? classLvalue : intLvalue); 557552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(cond ? intLvalue : int()); 558552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 559552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 560552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_ass_1(int x) 561552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 562552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.ass/1: There are several assignment operators, all of 563552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // which group right-to-left. All require a modifiable lvalue as 564552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // their left operand, and the type of an assignment expression is 565552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // that of its left operand. The result of the assignment 566552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // operation is the value stored in the left operand after the 567552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // assignment has taken place; the result is an lvalue. 568552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(x = 1); 569552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(x += 1); 570552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(x -= 1); 571552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(x *= 1); 572552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(x /= 1); 573552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(x %= 1); 574552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(x ^= 1); 575552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(x &= 1); 576552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(x |= 1); 577552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 578552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 579552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_comma(int x) 580552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 581552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // expr.comma: A pair of expressions separated by a comma is 582552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // evaluated left-to-right and the value of the left expression is 583552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // discarded... result is an lvalue if its right operand is. 584552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 585552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // Can't use the ASSERT_XXXX macros without adding parens around 586552622067dc45013d240f73952fece703f5e63bdJohn Wiegley // the comma expression. 587552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(__is_lvalue_expr(x,x), "expected an lvalue"); 588552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(__is_rvalue_expr(x,1), "expected an rvalue"); 589552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(__is_lvalue_expr(1,x), "expected an lvalue"); 590552622067dc45013d240f73952fece703f5e63bdJohn Wiegley static_assert(__is_rvalue_expr(1,1), "expected an rvalue"); 591552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 592552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 593552622067dc45013d240f73952fece703f5e63bdJohn Wiegley#if 0 594552622067dc45013d240f73952fece703f5e63bdJohn Wiegleytemplate<typename T> void f(); 595552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 596552622067dc45013d240f73952fece703f5e63bdJohn Wiegley// FIXME These currently fail 597552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_fun_lvalue() 598552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 599552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(&f<int>); 600552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 601552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 602552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid expr_fun_rvalue() 603552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 604552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(f<int>); 605552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 606552622067dc45013d240f73952fece703f5e63bdJohn Wiegley#endif 607552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 608552622067dc45013d240f73952fece703f5e63bdJohn Wiegleytemplate <int NonTypeNonReferenceParameter, int& NonTypeReferenceParameter> 609552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid check_temp_param_6() 610552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 611552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_RVALUE(NonTypeNonReferenceParameter); 612552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ASSERT_LVALUE(NonTypeReferenceParameter); 613552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 614552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 615552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyint AnInt = 0; 616552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 617552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid temp_param_6() 618552622067dc45013d240f73952fece703f5e63bdJohn Wiegley{ 619552622067dc45013d240f73952fece703f5e63bdJohn Wiegley check_temp_param_6<3,AnInt>(); 620552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 621