diff options
author | Jason Merrill <jason@redhat.com> | 2011-03-17 12:20:16 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-03-17 12:20:16 -0400 |
commit | c1e41527443f54a454452b9b628ab215a73375b5 (patch) | |
tree | efff327edaa7e3722b06262633cad9b924af6ac8 /gcc | |
parent | 547206a4e530360a06679894c2a9f2168bf5f943 (diff) | |
download | gcc-c1e41527443f54a454452b9b628ab215a73375b5.zip gcc-c1e41527443f54a454452b9b628ab215a73375b5.tar.gz gcc-c1e41527443f54a454452b9b628ab215a73375b5.tar.bz2 |
Core 1212
Core 1212
* semantics.c (finish_decltype_type): Return T&& for xvalue.
* typeck.c (unlowered_expr_type): Preserve cv-quals.
From-SVN: r171104
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 114 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/decltype-1212.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/rv-return.C | 4 |
6 files changed, 55 insertions, 90 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 38ac06c..f710f7a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2011-03-17 Jason Merrill <jason@redhat.com> + Core 1212 + * semantics.c (finish_decltype_type): Return T&& for xvalue. + * typeck.c (unlowered_expr_type): Preserve cv-quals. + PR c++/48166 * decl.c (revert_static_member_fn): Strip function-cv-quals. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 7519d26..cafca56 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4787,7 +4787,6 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) && processing_template_decl && TREE_CODE (expr) == COMPONENT_REF)) { - treat_as_dependent: type = cxx_make_type (DECLTYPE_TYPE); DECLTYPE_TYPE_EXPR (type) = expr; DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type) @@ -4899,91 +4898,34 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) } else { - /* Expressions of reference type are sometimes wrapped in - INDIRECT_REFs. INDIRECT_REFs are just internal compiler - representation, not part of the language, so we have to look - through them. */ - if (TREE_CODE (expr) == INDIRECT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) - == REFERENCE_TYPE) - expr = TREE_OPERAND (expr, 0); - - if (TREE_CODE (expr) == CALL_EXPR) - { - /* If e is a function call (5.2.2 [expr.call]) or an - invocation of an overloaded operator (parentheses around e - are ignored), decltype(e) is defined as the return type of - that function. */ - tree fndecl = get_callee_fndecl (expr); - if (fndecl && fndecl != error_mark_node) - type = TREE_TYPE (TREE_TYPE (fndecl)); - else - { - tree target_type = TREE_TYPE (CALL_EXPR_FN (expr)); - if ((TREE_CODE (target_type) == REFERENCE_TYPE - || TREE_CODE (target_type) == POINTER_TYPE) - && (TREE_CODE (TREE_TYPE (target_type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (target_type)) == METHOD_TYPE)) - type = TREE_TYPE (TREE_TYPE (target_type)); - else if (processing_template_decl) - /* Within a template finish_call_expr doesn't resolve - CALL_EXPR_FN, so even though this decltype isn't really - dependent let's defer resolving it. */ - goto treat_as_dependent; - else - sorry ("unable to determine the declared type of expression %<%E%>", - expr); - } - } - else - { - type = is_bitfield_expr_with_lowered_type (expr); - if (type) - { - /* Bitfields are special, because their type encodes the - number of bits they store. If the expression referenced a - bitfield, TYPE now has the declared type of that - bitfield. */ - type = cp_build_qualified_type (type, - cp_type_quals (TREE_TYPE (expr))); - - if (real_lvalue_p (expr)) - type = build_reference_type (type); - } - /* Within a lambda-expression: - - Every occurrence of decltype((x)) where x is a possibly - parenthesized id-expression that names an entity of - automatic storage duration is treated as if x were - transformed into an access to a corresponding data member - of the closure type that would have been declared if x - were a use of the denoted entity. */ - else if (outer_automatic_var_p (expr) - && current_function_decl - && LAMBDA_FUNCTION_P (current_function_decl)) - type = capture_decltype (expr); - else - { - /* Otherwise, where T is the type of e, if e is an lvalue, - decltype(e) is defined as T&, otherwise decltype(e) is - defined as T. */ - type = TREE_TYPE (expr); - if (type == error_mark_node) - return error_mark_node; - else if (expr == current_class_ptr) - /* If the expression is just "this", we want the - cv-unqualified pointer for the "this" type. */ - type = TYPE_MAIN_VARIANT (type); - else if (real_lvalue_p (expr)) - { - if (TREE_CODE (type) != REFERENCE_TYPE - || TYPE_REF_IS_RVALUE (type)) - type = build_reference_type (non_reference (type)); - } - else - type = non_reference (type); - } - } + /* Within a lambda-expression: + + Every occurrence of decltype((x)) where x is a possibly + parenthesized id-expression that names an entity of + automatic storage duration is treated as if x were + transformed into an access to a corresponding data member + of the closure type that would have been declared if x + were a use of the denoted entity. */ + if (outer_automatic_var_p (expr) + && current_function_decl + && LAMBDA_FUNCTION_P (current_function_decl)) + type = capture_decltype (expr); + else if (error_operand_p (expr)) + type = error_mark_node; + else if (expr == current_class_ptr) + /* If the expression is just "this", we want the + cv-unqualified pointer for the "this" type. */ + type = TYPE_MAIN_VARIANT (TREE_TYPE (expr)); + else + { + /* Otherwise, where T is the type of e, if e is an lvalue, + decltype(e) is defined as T&; if an xvalue, T&&; otherwise, T. */ + cp_lvalue_kind clk = lvalue_kind (expr); + type = unlowered_expr_type (expr); + gcc_assert (TREE_CODE (type) != REFERENCE_TYPE); + if (clk != clk_none && !(clk & clk_class)) + type = cp_build_reference_type (type, (clk & clk_rvalueref)); + } } if (!type || type == unknown_type_node) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 03aa49e..955ff57 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1768,10 +1768,13 @@ tree unlowered_expr_type (const_tree exp) { tree type; + tree etype = TREE_TYPE (exp); type = is_bitfield_expr_with_lowered_type (exp); - if (!type) - type = TREE_TYPE (exp); + if (type) + type = cp_build_qualified_type (type, cp_type_quals (etype)); + else + type = etype; return type; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 47cdbc9..29d3823 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2011-03-17 Jason Merrill <jason@redhat.com> + * g++.dg/cpp0x/decltype-1212.C: New. + * g++.dg/cpp0x/rv-return.C: Adjust expected type. + +2011-03-17 Jason Merrill <jason@redhat.com> + * g++.dg/parse/memfnquals1.C: New. 2011-03-17 Richard Guenther <rguenther@suse.de> diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-1212.C b/gcc/testsuite/g++.dg/cpp0x/decltype-1212.C new file mode 100644 index 0000000..38393d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype-1212.C @@ -0,0 +1,11 @@ +// Core 1212 +// { dg-options -std=c++0x } + +template <class T, class U> struct assert_same_type; +template <class T> struct assert_same_type<T,T> {}; + +int main() +{ + int i; + assert_same_type<int&&,decltype(static_cast<int&&>(i))>(); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-return.C b/gcc/testsuite/g++.dg/cpp0x/rv-return.C index e52101f..3ab6598 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv-return.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv-return.C @@ -7,12 +7,12 @@ template<typename T> struct same_type<T, T> {}; int const f() { return 0; } int &&r = f(); // binding "int&&" to "int" should succeed -same_type<decltype(f()), int const> s1; +same_type<decltype(f()), int> s1; same_type<decltype(0,f()), int> s2; template <class T> T const g() { return 0; } int &&r2 = g<int>(); -same_type<decltype(g<int>()), int const> s3; +same_type<decltype(g<int>()), int> s3; same_type<decltype(0,g<int>()), int> s4; |