diff options
author | Douglas Gregor <doug.gregor@gmail.com> | 2008-08-07 15:38:59 +0000 |
---|---|---|
committer | Doug Gregor <dgregor@gcc.gnu.org> | 2008-08-07 15:38:59 +0000 |
commit | ed85a1f60b8a827af17129d2e76c332ecf13d7bd (patch) | |
tree | d0b0600d972dd2e78c8abdb979bb1a5f24f8b99e | |
parent | e297d9fe0df8e5b1fb5dee3700be0bf3c2894680 (diff) | |
download | gcc-ed85a1f60b8a827af17129d2e76c332ecf13d7bd.zip gcc-ed85a1f60b8a827af17129d2e76c332ecf13d7bd.tar.gz gcc-ed85a1f60b8a827af17129d2e76c332ecf13d7bd.tar.bz2 |
semantics.c (finish_decltype_type): Handle calls to function pointers and references to functions properly.
2008-08-07 Douglas Gregor <doug.gregor@gmail.com>
* semantics.c (finish_decltype_type): Handle calls to function
pointers and references to functions properly.
2008-08-07 Douglas Gregor <doug.gregor@gmail.com>
* g++.dg/cpp0x/decltype12.C: New.
From-SVN: r138843
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/decltype12.C | 38 |
4 files changed, 66 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7bf5f01..c4c4680 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2008-08-07 Douglas Gregor <doug.gregor@gmail.com> + + * semantics.c (finish_decltype_type): Handle calls to function + pointers and references to functions properly. + 2008-08-06 Douglas Gregor <doug.gregor@gmail.com> PR c++/36460 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 5ada422..9a8af7c 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4586,8 +4586,6 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) } else { - tree fndecl; - /* 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 @@ -4597,14 +4595,28 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) == REFERENCE_TYPE) expr = TREE_OPERAND (expr, 0); - if (TREE_CODE (expr) == CALL_EXPR - && (fndecl = get_callee_fndecl (expr)) - && (fndecl != error_mark_node)) - /* If e is a function call (5.2.2 [expr.call]) or an + 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. */ - type = TREE_TYPE (TREE_TYPE (fndecl)); + 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 + sorry ("unable to determine the declared type of expression %<%E%>", + expr); + } + } else { type = is_bitfield_expr_with_lowered_type (expr); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 417b6b7..bd034f0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-08-07 Douglas Gregor <doug.gregor@gmail.com> + + * g++.dg/cpp0x/decltype12.C: New. + 2008-08-07 H.J. Lu <hongjiu.lu@intel.com> PR target/36992 diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype12.C b/gcc/testsuite/g++.dg/cpp0x/decltype12.C new file mode 100644 index 0000000..77c794b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype12.C @@ -0,0 +1,38 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } +template<typename T, typename U> +struct is_same +{ + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> +{ + static const bool value = true; +}; + +int&& f(const int&) {} +int&& (*fp)(const int&) = f; +int&& (&fr)(const int&) = f; + +struct X { int&& f(const int&); }; + +int&& (X::*mfp)(const int&) = &X::f; + +void g(X& xr, X* xp) +{ + int i; + static_assert(is_same<decltype(f(i)), int&&>::value, "direct call"); + static_assert(is_same<decltype(fp(i)), int&&>::value, "pointer"); + static_assert(is_same<decltype((*fp)(i)), int&&>::value, + "dereferenced pointer"); + static_assert(is_same<decltype(fr(i)), int&&>::value, + "reference"); + static_assert(is_same<decltype(xr.f(i)), int&&>::value, + "member function call"); + static_assert(is_same<decltype((xr.*mfp)(i)), int&&>::value, + "member function pointer with .*"); + static_assert(is_same<decltype((xp->*mfp)(i)), int&&>::value, + "member function pointer with ->*"); +} |