expression-traits.cpp revision c2fe81898b1b3b948791ca4ababd3d495601f22a
1// RUN: %clang_cc1 -fsyntax-only -verify -fcxx-exceptions %s
2
3//
4// Tests for "expression traits" intrinsics such as __is_lvalue_expr.
5//
6// For the time being, these tests are written against the 2003 C++
7// standard (ISO/IEC 14882:2003 -- see draft at
8// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2001/n1316/).
9//
10// C++0x has its own, more-refined, idea of lvalues and rvalues.
11// If/when we need to support those, we'll need to track both
12// standard documents.
13
14#if !__has_feature(cxx_static_assert)
15# define CONCAT_(X_, Y_) CONCAT1_(X_, Y_)
16# define CONCAT1_(X_, Y_) X_ ## Y_
17
18// This emulation can be used multiple times on one line (and thus in
19// a macro), except at class scope
20# define static_assert(b_, m_) \
21  typedef int CONCAT_(sa_, __LINE__)[b_ ? 1 : -1]
22#endif
23
24// Tests are broken down according to section of the C++03 standard
25// (ISO/IEC 14882:2003(E))
26
27// Assertion macros encoding the following two paragraphs
28//
29// basic.lval/1 Every expression is either an lvalue or an rvalue.
30//
31// expr.prim/5 A parenthesized expression is a primary expression whose type
32// and value are identical to those of the enclosed expression. The
33// presence of parentheses does not affect whether the expression is
34// an lvalue.
35//
36// Note: these asserts cannot be made at class scope in C++03.  Put
37// them in a member function instead.
38#define ASSERT_LVALUE(expr)                                             \
39    static_assert(__is_lvalue_expr(expr), "should be an lvalue");       \
40    static_assert(__is_lvalue_expr((expr)),                             \
41                  "the presence of parentheses should have"             \
42                  " no effect on lvalueness (expr.prim/5)");            \
43    static_assert(!__is_rvalue_expr(expr), "should be an lvalue");      \
44    static_assert(!__is_rvalue_expr((expr)),                            \
45                  "the presence of parentheses should have"             \
46                  " no effect on lvalueness (expr.prim/5)")
47
48#define ASSERT_RVALUE(expr);                                            \
49    static_assert(__is_rvalue_expr(expr), "should be an rvalue");       \
50    static_assert(__is_rvalue_expr((expr)),                             \
51                  "the presence of parentheses should have"             \
52                  " no effect on lvalueness (expr.prim/5)");            \
53    static_assert(!__is_lvalue_expr(expr), "should be an rvalue");      \
54    static_assert(!__is_lvalue_expr((expr)),                            \
55                  "the presence of parentheses should have"             \
56                  " no effect on lvalueness (expr.prim/5)")
57
58enum Enum { Enumerator };
59
60int ReturnInt();
61void ReturnVoid();
62Enum ReturnEnum();
63
64void basic_lval_5()
65{
66    // basic.lval/5: The result of calling a function that does not return
67    // a reference is an rvalue.
68    ASSERT_RVALUE(ReturnInt());
69    ASSERT_RVALUE(ReturnVoid());
70    ASSERT_RVALUE(ReturnEnum());
71}
72
73int& ReturnIntReference();
74extern Enum& ReturnEnumReference();
75
76void basic_lval_6()
77{
78    // basic.lval/6: An expression which holds a temporary object resulting
79    // from a cast to a nonreference type is an rvalue (this includes
80    // the explicit creation of an object using functional notation
81    struct IntClass
82    {
83        explicit IntClass(int = 0);
84        IntClass(char const*);
85        operator int() const;
86    };
87
88    struct ConvertibleToIntClass
89    {
90        operator IntClass() const;
91    };
92
93    ConvertibleToIntClass b;
94
95    // Make sure even trivial conversions are not detected as lvalues
96    int intLvalue = 0;
97    ASSERT_RVALUE((int)intLvalue);
98    ASSERT_RVALUE((short)intLvalue);
99    ASSERT_RVALUE((long)intLvalue);
100
101    // Same tests with function-call notation
102    ASSERT_RVALUE(int(intLvalue));
103    ASSERT_RVALUE(short(intLvalue));
104    ASSERT_RVALUE(long(intLvalue));
105
106    char charLValue = 'x';
107    ASSERT_RVALUE((signed char)charLValue);
108    ASSERT_RVALUE((unsigned char)charLValue);
109
110    ASSERT_RVALUE(static_cast<int>(IntClass()));
111    IntClass intClassLValue;
112    ASSERT_RVALUE(static_cast<int>(intClassLValue));
113    ASSERT_RVALUE(static_cast<IntClass>(ConvertibleToIntClass()));
114    ConvertibleToIntClass convertibleToIntClassLValue;
115    ASSERT_RVALUE(static_cast<IntClass>(convertibleToIntClassLValue));
116
117
118    typedef signed char signed_char;
119    typedef unsigned char unsigned_char;
120    ASSERT_RVALUE(signed_char(charLValue));
121    ASSERT_RVALUE(unsigned_char(charLValue));
122
123    ASSERT_RVALUE(int(IntClass()));
124    ASSERT_RVALUE(int(intClassLValue));
125    ASSERT_RVALUE(IntClass(ConvertibleToIntClass()));
126    ASSERT_RVALUE(IntClass(convertibleToIntClassLValue));
127}
128
129void conv_ptr_1()
130{
131    // conv.ptr/1: A null pointer constant is an integral constant
132    // expression (5.19) rvalue of integer type that evaluates to
133    // zero.
134    ASSERT_RVALUE(0);
135}
136
137void expr_6()
138{
139    // expr/6: If an expression initially has the type "reference to T"
140    // (8.3.2, 8.5.3), ... the expression is an lvalue.
141    int x = 0;
142    int& referenceToInt = x;
143    ASSERT_LVALUE(referenceToInt);
144    ASSERT_LVALUE(ReturnIntReference());
145}
146
147void expr_prim_2()
148{
149    // 5.1/2 A string literal is an lvalue; all other
150    // literals are rvalues.
151    ASSERT_LVALUE("foo");
152    ASSERT_RVALUE(1);
153    ASSERT_RVALUE(1.2);
154    ASSERT_RVALUE(10UL);
155}
156
157void expr_prim_3()
158{
159    // 5.1/3: The keyword "this" names a pointer to the object for
160    // which a nonstatic member function (9.3.2) is invoked. ...The
161    // expression is an rvalue.
162    struct ThisTest
163    {
164        void f() { ASSERT_RVALUE(this); }
165    };
166}
167
168extern int variable;
169void Function();
170
171struct BaseClass
172{
173    virtual ~BaseClass();
174
175    int BaseNonstaticMemberFunction();
176    static int BaseStaticMemberFunction();
177    int baseDataMember;
178};
179
180struct Class : BaseClass
181{
182    static void function();
183    static int variable;
184
185    template <class T>
186    struct NestedClassTemplate {};
187
188    template <class T>
189    static int& NestedFuncTemplate() { return variable; }  // expected-note{{possible target for call}}
190
191    template <class T>
192    int& NestedMemfunTemplate() { return variable; } // expected-note{{possible target for call}}
193
194    int operator*() const;
195
196    template <class T>
197    int operator+(T) const; // expected-note{{possible target for call}}
198
199    int NonstaticMemberFunction();
200    static int StaticMemberFunction();
201    int dataMember;
202
203    int& referenceDataMember;
204    static int& staticReferenceDataMember;
205    static int staticNonreferenceDataMember;
206
207    enum Enum { Enumerator };
208
209    operator long() const;
210
211    Class();
212    Class(int,int);
213
214    void expr_prim_4()
215    {
216        // 5.1/4: The operator :: followed by an identifier, a
217        // qualified-id, or an operator-function-id is a primary-
218        // expression. ...The result is an lvalue if the entity is
219        // a function or variable.
220        ASSERT_LVALUE(::Function);         // identifier: function
221        ASSERT_LVALUE(::variable);         // identifier: variable
222
223        // the only qualified-id form that can start without "::" (and thus
224        // be legal after "::" ) is
225        //
226        // ::<sub>opt</sub> nested-name-specifier template<sub>opt</sub> unqualified-id
227        ASSERT_LVALUE(::Class::function);  // qualified-id: function
228        ASSERT_LVALUE(::Class::variable);  // qualified-id: variable
229
230        // The standard doesn't give a clear answer about whether these
231        // should really be lvalues or rvalues without some surrounding
232        // context that forces them to be interpreted as naming a
233        // particular function template specialization (that situation
234        // doesn't come up in legal pure C++ programs). This language
235        // extension simply rejects them as requiring additional context
236        __is_lvalue_expr(::Class::NestedFuncTemplate);    // qualified-id: template \
237        // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
238
239        __is_lvalue_expr(::Class::NestedMemfunTemplate);  // qualified-id: template \
240        // expected-error{{reference to non-static member function must be called}}
241
242        __is_lvalue_expr(::Class::operator+);             // operator-function-id: template \
243        // expected-error{{reference to non-static member function must be called}}
244
245        //ASSERT_RVALUE(::Class::operator*);         // operator-function-id: member function
246    }
247
248    void expr_prim_7()
249    {
250        // expr.prim/7 An identifier is an id-expression provided it has been
251        // suitably declared (clause 7). [Note: ... ] The type of the
252        // expression is the type of the identifier. The result is the
253        // entity denoted by the identifier. The result is an lvalue if
254        // the entity is a function, variable, or data member... (cont'd)
255        ASSERT_LVALUE(Function);        // identifier: function
256        ASSERT_LVALUE(StaticMemberFunction);        // identifier: function
257        ASSERT_LVALUE(variable);        // identifier: variable
258        ASSERT_LVALUE(dataMember);      // identifier: data member
259        //ASSERT_RVALUE(NonstaticMemberFunction); // identifier: member function
260
261        // (cont'd)...A nested-name-specifier that names a class,
262        // optionally followed by the keyword template (14.2), and then
263        // followed by the name of a member of either that class (9.2) or
264        // one of its base classes... is a qualified-id... The result is
265        // the member. The type of the result is the type of the
266        // member. The result is an lvalue if the member is a static
267        // member function or a data member.
268        ASSERT_LVALUE(Class::dataMember);
269        ASSERT_LVALUE(Class::StaticMemberFunction);
270        //ASSERT_RVALUE(Class::NonstaticMemberFunction); // identifier: member function
271
272        ASSERT_LVALUE(Class::baseDataMember);
273        ASSERT_LVALUE(Class::BaseStaticMemberFunction);
274        //ASSERT_RVALUE(Class::BaseNonstaticMemberFunction); // identifier: member function
275    }
276};
277
278void expr_call_10()
279{
280    // expr.call/10: A function call is an lvalue if and only if the
281    // result type is a reference.  This statement is partially
282    // redundant with basic.lval/5
283    basic_lval_5();
284
285    ASSERT_LVALUE(ReturnIntReference());
286    ASSERT_LVALUE(ReturnEnumReference());
287}
288
289namespace Namespace
290{
291  int x;
292  void function();
293}
294
295void expr_prim_8()
296{
297    // expr.prim/8 A nested-name-specifier that names a namespace
298    // (7.3), followed by the name of a member of that namespace (or
299    // the name of a member of a namespace made visible by a
300    // using-directive ) is a qualified-id; 3.4.3.2 describes name
301    // lookup for namespace members that appear in qualified-ids. The
302    // result is the member. The type of the result is the type of the
303    // member. The result is an lvalue if the member is a function or
304    // a variable.
305    ASSERT_LVALUE(Namespace::x);
306    ASSERT_LVALUE(Namespace::function);
307}
308
309void expr_sub_1(int* pointer)
310{
311    // expr.sub/1 A postfix expression followed by an expression in
312    // square brackets is a postfix expression. One of the expressions
313    // shall have the type "pointer to T" and the other shall have
314    // enumeration or integral type. The result is an lvalue of type
315    // "T."
316    ASSERT_LVALUE(pointer[1]);
317
318    // The expression E1[E2] is identical (by definition) to *((E1)+(E2)).
319    ASSERT_LVALUE(*(pointer+1));
320}
321
322void expr_type_conv_1()
323{
324    // expr.type.conv/1 A simple-type-specifier (7.1.5) followed by a
325    // parenthesized expression-list constructs a value of the specified
326    // type given the expression list. ... If the expression list
327    // specifies more than a single value, the type shall be a class with
328    // a suitably declared constructor (8.5, 12.1), and the expression
329    // T(x1, x2, ...) is equivalent in effect to the declaration T t(x1,
330    // x2, ...); for some invented temporary variable t, with the result
331    // being the value of t as an rvalue.
332    ASSERT_RVALUE(Class(2,2));
333}
334
335void expr_type_conv_2()
336{
337    // expr.type.conv/2 The expression T(), where T is a
338    // simple-type-specifier (7.1.5.2) for a non-array complete object
339    // type or the (possibly cv-qualified) void type, creates an
340    // rvalue of the specified type,
341    ASSERT_RVALUE(int());
342    ASSERT_RVALUE(Class());
343    ASSERT_RVALUE(void());
344}
345
346
347void expr_ref_4()
348{
349    // Applies to expressions of the form E1.E2
350
351    // If E2 is declared to have type "reference to T", then E1.E2 is
352    // an lvalue;.... Otherwise, one of the following rules applies.
353    ASSERT_LVALUE(Class().staticReferenceDataMember);
354    ASSERT_LVALUE(Class().referenceDataMember);
355
356    // - If E2 is a static data member, and the type of E2 is T, then
357    // E1.E2 is an lvalue; ...
358    ASSERT_LVALUE(Class().staticNonreferenceDataMember);
359    ASSERT_LVALUE(Class().staticReferenceDataMember);
360
361
362    // - If E2 is a non-static data member, ... If E1 is an lvalue,
363    // then E1.E2 is an lvalue...
364    Class lvalue;
365    ASSERT_LVALUE(lvalue.dataMember);
366    ASSERT_RVALUE(Class().dataMember);
367
368    // - If E1.E2 refers to a static member function, ... then E1.E2
369    // is an lvalue
370    ASSERT_LVALUE(Class().StaticMemberFunction);
371
372    // - Otherwise, if E1.E2 refers to a non-static member function,
373    // then E1.E2 is not an lvalue.
374    //ASSERT_RVALUE(Class().NonstaticMemberFunction);
375
376    // - If E2 is a member enumerator, and the type of E2 is T, the
377    // expression E1.E2 is not an lvalue. The type of E1.E2 is T.
378    ASSERT_RVALUE(Class().Enumerator);
379    ASSERT_RVALUE(lvalue.Enumerator);
380}
381
382
383void expr_post_incr_1(int x)
384{
385    // expr.post.incr/1 The value obtained by applying a postfix ++ is
386    // the value that the operand had before applying the
387    // operator... The result is an rvalue.
388    ASSERT_RVALUE(x++);
389}
390
391void expr_dynamic_cast_2()
392{
393    // expr.dynamic.cast/2: If T is a pointer type, v shall be an
394    // rvalue of a pointer to complete class type, and the result is
395    // an rvalue of type T.
396    Class instance;
397    ASSERT_RVALUE(dynamic_cast<Class*>(&instance));
398
399    // If T is a reference type, v shall be an
400    // lvalue of a complete class type, and the result is an lvalue of
401    // the type referred to by T.
402    ASSERT_LVALUE(dynamic_cast<Class&>(instance));
403}
404
405void expr_dynamic_cast_5()
406{
407    // expr.dynamic.cast/5: If T is "reference to cv1 B" and v has type
408    // "cv2 D" such that B is a base class of D, the result is an
409    // lvalue for the unique B sub-object of the D object referred
410    // to by v.
411    typedef BaseClass B;
412    typedef Class D;
413    D object;
414    ASSERT_LVALUE(dynamic_cast<B&>(object));
415}
416
417// expr.dynamic.cast/8: The run-time check logically executes as follows:
418//
419// - If, in the most derived object pointed (referred) to by v, v
420// points (refers) to a public base class subobject of a T object, and
421// if only one object of type T is derived from the sub-object pointed
422// (referred) to by v, the result is a pointer (an lvalue referring)
423// to that T object.
424//
425// - Otherwise, if v points (refers) to a public base class sub-object
426// of the most derived object, and the type of the most derived object
427// has a base class, of type T, that is unambiguous and public, the
428// result is a pointer (an lvalue referring) to the T sub-object of
429// the most derived object.
430//
431// The mention of "lvalue" in the text above appears to be a
432// defect that is being corrected by the response to UK65 (see
433// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2841.html).
434
435#if 0
436void expr_typeid_1()
437{
438    // expr.typeid/1: The result of a typeid expression is an lvalue...
439    ASSERT_LVALUE(typeid(1));
440}
441#endif
442
443void expr_static_cast_1(int x)
444{
445    // expr.static.cast/1: The result of the expression
446    // static_cast<T>(v) is the result of converting the expression v
447    // to type T. If T is a reference type, the result is an lvalue;
448    // otherwise, the result is an rvalue.
449    ASSERT_LVALUE(static_cast<int&>(x));
450    ASSERT_RVALUE(static_cast<int>(x));
451}
452
453void expr_reinterpret_cast_1()
454{
455    // expr.reinterpret.cast/1: The result of the expression
456    // reinterpret_cast<T>(v) is the result of converting the
457    // expression v to type T. If T is a reference type, the result is
458    // an lvalue; otherwise, the result is an rvalue
459    ASSERT_RVALUE(reinterpret_cast<int*>(0));
460    char const v = 0;
461    ASSERT_LVALUE(reinterpret_cast<char const&>(v));
462}
463
464void expr_unary_op_1(int* pointer, struct incomplete* pointerToIncompleteType)
465{
466    // expr.unary.op/1: The unary * operator performs indirection: the
467    // expression to which it is applied shall be a pointer to an
468    // object type, or a pointer to a function type and the result is
469    // an lvalue referring to the object or function to which the
470    // expression points.
471    ASSERT_LVALUE(*pointer);
472    ASSERT_LVALUE(*Function);
473
474    // [Note: a pointer to an incomplete type
475    // (other than cv void ) can be dereferenced. ]
476    ASSERT_LVALUE(*pointerToIncompleteType);
477}
478
479void expr_pre_incr_1(int operand)
480{
481    // expr.pre.incr/1: The operand of prefix ++ ... shall be a
482    // modifiable lvalue.... The value is the new value of the
483    // operand; it is an lvalue.
484    ASSERT_LVALUE(++operand);
485}
486
487void expr_cast_1(int x)
488{
489    // expr.cast/1: The result of the expression (T) cast-expression
490    // is of type T. The result is an lvalue if T is a reference type,
491    // otherwise the result is an rvalue.
492    ASSERT_LVALUE((void(&)())expr_cast_1);
493    ASSERT_LVALUE((int&)x);
494    ASSERT_RVALUE((void(*)())expr_cast_1);
495    ASSERT_RVALUE((int)x);
496}
497
498void expr_mptr_oper()
499{
500    // expr.mptr.oper/6: The result of a .* expression is an lvalue
501    // only if its first operand is an lvalue and its second operand
502    // is a pointer to data member... (cont'd)
503    typedef Class MakeRValue;
504    ASSERT_RVALUE(MakeRValue().*(&Class::dataMember));
505    //ASSERT_RVALUE(MakeRValue().*(&Class::NonstaticMemberFunction));
506    Class lvalue;
507    ASSERT_LVALUE(lvalue.*(&Class::dataMember));
508    //ASSERT_RVALUE(lvalue.*(&Class::NonstaticMemberFunction));
509
510    // (cont'd)...The result of an ->* expression is an lvalue only
511    // if its second operand is a pointer to data member. If the
512    // second operand is the null pointer to member value (4.11), the
513    // behavior is undefined.
514    ASSERT_LVALUE((&lvalue)->*(&Class::dataMember));
515    //ASSERT_RVALUE((&lvalue)->*(&Class::NonstaticMemberFunction));
516}
517
518void expr_cond(bool cond)
519{
520    // 5.16 Conditional operator [expr.cond]
521    //
522    // 2 If either the second or the third operand has type (possibly
523    // cv-qualified) void, then the lvalue-to-rvalue (4.1),
524    // array-to-pointer (4.2), and function-to-pointer (4.3) standard
525    // conversions are performed on the second and third operands, and one
526    // of the following shall hold:
527    //
528    // - The second or the third operand (but not both) is a
529    // throw-expression (15.1); the result is of the type of the other and
530    // is an rvalue.
531
532    Class classLvalue;
533    ASSERT_RVALUE(cond ? throw 1 : (void)0);
534    ASSERT_RVALUE(cond ? (void)0 : throw 1);
535    ASSERT_RVALUE(cond ? throw 1 : classLvalue);
536    ASSERT_RVALUE(cond ? classLvalue : throw 1);
537
538    // - Both the second and the third operands have type void; the result
539    // is of type void and is an rvalue. [Note: this includes the case
540    // where both operands are throw-expressions. ]
541    ASSERT_RVALUE(cond ? (void)1 : (void)0);
542    ASSERT_RVALUE(cond ? throw 1 : throw 0);
543
544    // expr.cond/4: If the second and third operands are lvalues and
545    // have the same type, the result is of that type and is an
546    // lvalue.
547    ASSERT_LVALUE(cond ? classLvalue : classLvalue);
548    int intLvalue = 0;
549    ASSERT_LVALUE(cond ? intLvalue : intLvalue);
550
551    // expr.cond/5:Otherwise, the result is an rvalue.
552    typedef Class MakeRValue;
553    ASSERT_RVALUE(cond ? MakeRValue() : classLvalue);
554    ASSERT_RVALUE(cond ? classLvalue : MakeRValue());
555    ASSERT_RVALUE(cond ? MakeRValue() : MakeRValue());
556    ASSERT_RVALUE(cond ? classLvalue : intLvalue);
557    ASSERT_RVALUE(cond ? intLvalue : int());
558}
559
560void expr_ass_1(int x)
561{
562    // expr.ass/1: There are several assignment operators, all of
563    // which group right-to-left. All require a modifiable lvalue as
564    // their left operand, and the type of an assignment expression is
565    // that of its left operand. The result of the assignment
566    // operation is the value stored in the left operand after the
567    // assignment has taken place; the result is an lvalue.
568    ASSERT_LVALUE(x = 1);
569    ASSERT_LVALUE(x += 1);
570    ASSERT_LVALUE(x -= 1);
571    ASSERT_LVALUE(x *= 1);
572    ASSERT_LVALUE(x /= 1);
573    ASSERT_LVALUE(x %= 1);
574    ASSERT_LVALUE(x ^= 1);
575    ASSERT_LVALUE(x &= 1);
576    ASSERT_LVALUE(x |= 1);
577}
578
579void expr_comma(int x)
580{
581    // expr.comma: A pair of expressions separated by a comma is
582    // evaluated left-to-right and the value of the left expression is
583    // discarded... result is an lvalue if its right operand is.
584
585    // Can't use the ASSERT_XXXX macros without adding parens around
586    // the comma expression.
587    static_assert(__is_lvalue_expr(x,x), "expected an lvalue");
588    static_assert(__is_rvalue_expr(x,1), "expected an rvalue");
589    static_assert(__is_lvalue_expr(1,x), "expected an lvalue");
590    static_assert(__is_rvalue_expr(1,1), "expected an rvalue");
591}
592
593#if 0
594template<typename T> void f();
595
596// FIXME These currently fail
597void expr_fun_lvalue()
598{
599  ASSERT_LVALUE(&f<int>);
600}
601
602void expr_fun_rvalue()
603{
604  ASSERT_RVALUE(f<int>);
605}
606#endif
607
608template <int NonTypeNonReferenceParameter, int& NonTypeReferenceParameter>
609void check_temp_param_6()
610{
611    ASSERT_RVALUE(NonTypeNonReferenceParameter);
612    ASSERT_LVALUE(NonTypeReferenceParameter);
613}
614
615int AnInt = 0;
616
617void temp_param_6()
618{
619    check_temp_param_6<3,AnInt>();
620}
621