diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2014-05-07 19:31:24 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2014-05-07 19:31:24 +0000 |
commit | 04e5eb5f10dd261bedcaf5618a4147ffe3784a34 (patch) | |
tree | e6db5cde3bdf3d4148f41837ea87038d59a1fa6b | |
parent | 1a51f10c8157788eb15dcad754dd32acdae1114e (diff) | |
download | gcc-04e5eb5f10dd261bedcaf5618a4147ffe3784a34.zip gcc-04e5eb5f10dd261bedcaf5618a4147ffe3784a34.tar.gz gcc-04e5eb5f10dd261bedcaf5618a4147ffe3784a34.tar.bz2 |
re PR c++/61083 ([C++11] Ambiguous member pointer results in failure, even if used in SFINAE.)
/cp
2014-05-07 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/61083
* pt.c (convert_nontype_argument): Protect all the error calls
with complain & tf_error.
/testsuite
2014-05-07 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/61083
* g++.dg/cpp0x/sfinae50.C: New.
From-SVN: r210184
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 97 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/sfinae50.C | 41 |
4 files changed, 108 insertions, 41 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 938fbf5..8a7f18c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2014-05-07 Paolo Carlini <paolo.carlini@oracle.com> + PR c++/61083 + * pt.c (convert_nontype_argument): Protect all the error calls + with complain & tf_error. + +2014-05-07 Paolo Carlini <paolo.carlini@oracle.com> + PR c++/61080 * pt.c (instantiate_decl): Avoid generating the body of a deleted function. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f23eec3..d30349c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5812,17 +5812,18 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (VAR_P (expr)) { - error ("%qD is not a valid template argument " - "because %qD is a variable, not the address of " - "a variable", - expr, expr); + if (complain & tf_error) + error ("%qD is not a valid template argument " + "because %qD is a variable, not the address of " + "a variable", expr, expr); return NULL_TREE; } if (POINTER_TYPE_P (expr_type)) { - error ("%qE is not a valid template argument for %qT " - "because it is not the address of a variable", - expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for %qT " + "because it is not the address of a variable", + expr, type); return NULL_TREE; } /* Other values, like integer constants, might be valid @@ -5837,23 +5838,24 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ? TREE_OPERAND (expr, 0) : expr); if (!VAR_P (decl)) { - error ("%qE is not a valid template argument of type %qT " - "because %qE is not a variable", - expr, type, decl); + if (complain & tf_error) + error ("%qE is not a valid template argument of type %qT " + "because %qE is not a variable", expr, type, decl); return NULL_TREE; } else if (cxx_dialect < cxx11 && !DECL_EXTERNAL_LINKAGE_P (decl)) { - error ("%qE is not a valid template argument of type %qT " - "because %qD does not have external linkage", - expr, type, decl); + if (complain & tf_error) + error ("%qE is not a valid template argument of type %qT " + "because %qD does not have external linkage", + expr, type, decl); return NULL_TREE; } else if (cxx_dialect >= cxx11 && decl_linkage (decl) == lk_none) { - error ("%qE is not a valid template argument of type %qT " - "because %qD has no linkage", - expr, type, decl); + if (complain & tf_error) + error ("%qE is not a valid template argument of type %qT " + "because %qD has no linkage", expr, type, decl); return NULL_TREE; } } @@ -5881,15 +5883,17 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) if (!at_least_as_qualified_p (TREE_TYPE (type), expr_type)) { - error ("%qE is not a valid template argument for type %qT " - "because of conflicts in cv-qualification", expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because of conflicts in cv-qualification", expr, type); return NULL_TREE; } if (!real_lvalue_p (expr)) { - error ("%qE is not a valid template argument for type %qT " - "because it is not an lvalue", expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is not an lvalue", expr, type); return NULL_TREE; } @@ -5905,26 +5909,29 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) expr = TREE_OPERAND (expr, 0); if (DECL_P (expr)) { - error ("%q#D is not a valid template argument for type %qT " - "because a reference variable does not have a constant " - "address", expr, type); + if (complain & tf_error) + error ("%q#D is not a valid template argument for type %qT " + "because a reference variable does not have a constant " + "address", expr, type); return NULL_TREE; } } if (!DECL_P (expr)) { - error ("%qE is not a valid template argument for type %qT " - "because it is not an object with external linkage", - expr, type); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is not an object with external linkage", + expr, type); return NULL_TREE; } if (!DECL_EXTERNAL_LINKAGE_P (expr)) { - error ("%qE is not a valid template argument for type %qT " - "because object %qD has not external linkage", - expr, type, expr); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because object %qD has not external linkage", + expr, type, expr); return NULL_TREE; } @@ -5966,9 +5973,13 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (TREE_CODE (expr) == ADDR_EXPR) { - error ("%qE is not a valid template argument for type %qT " - "because it is a pointer", expr, type); - inform (input_location, "try using %qE instead", TREE_OPERAND (expr, 0)); + if (complain & tf_error) + { + error ("%qE is not a valid template argument for type %qT " + "because it is a pointer", expr, type); + inform (input_location, "try using %qE instead", + TREE_OPERAND (expr, 0)); + } return NULL_TREE; } @@ -6006,13 +6017,16 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) provide a superior diagnostic. */ if (!same_type_p (TREE_TYPE (expr), type)) { - error ("%qE is not a valid template argument for type %qT " - "because it is of type %qT", expr, type, - TREE_TYPE (expr)); - /* If we are just one standard conversion off, explain. */ - if (can_convert_standard (type, TREE_TYPE (expr), complain)) - inform (input_location, - "standard conversions are not allowed in this context"); + if (complain & tf_error) + { + error ("%qE is not a valid template argument for type %qT " + "because it is of type %qT", expr, type, + TREE_TYPE (expr)); + /* If we are just one standard conversion off, explain. */ + if (can_convert_standard (type, TREE_TYPE (expr), complain)) + inform (input_location, + "standard conversions are not allowed in this context"); + } return NULL_TREE; } } @@ -6035,8 +6049,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (expr != nullptr_node) { - error ("%qE is not a valid template argument for type %qT " - "because it is of type %qT", expr, type, TREE_TYPE (expr)); + if (complain & tf_error) + error ("%qE is not a valid template argument for type %qT " + "because it is of type %qT", expr, type, TREE_TYPE (expr)); return NULL_TREE; } return expr; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 97ce690..5b4ef30 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2014-05-07 Paolo Carlini <paolo.carlini@oracle.com> + PR c++/61083 + * g++.dg/cpp0x/sfinae50.C: New. + +2014-05-07 Paolo Carlini <paolo.carlini@oracle.com> + PR c++/61080 * g++.dg/cpp0x/deleted7.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae50.C b/gcc/testsuite/g++.dg/cpp0x/sfinae50.C new file mode 100644 index 0000000..e8d90ca --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae50.C @@ -0,0 +1,41 @@ +// PR c++/61083 +// { dg-do compile { target c++11 } } + +template<typename T> T declval(); + +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; +}; + +struct true_type {}; +struct false_type {}; + +template <typename T> +struct is_foo { +private: + template<typename U, U> struct helper {}; + + template <typename Z> static auto + test(Z z) -> decltype(helper<void (Z::*)() const, &Z::foo>(), true_type()); + + template <typename> static auto test(...) -> false_type; + +public: + enum { value = is_same<decltype(test<T>(declval<T>())), true_type>::value }; +}; + +struct A { + int foo(); + void foo() const; +}; + +struct A1 : public A {}; + +static_assert (is_foo<A>::value == 1, ""); +static_assert (is_foo<A1>::value == 0, ""); |