Commit 04e5eb5f by Paolo Carlini Committed by Paolo Carlini

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
parent 1a51f10c
2014-05-07 Paolo Carlini <paolo.carlini@oracle.com> 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 PR c++/61080
* pt.c (instantiate_decl): Avoid generating the body of a * pt.c (instantiate_decl): Avoid generating the body of a
deleted function. deleted function.
......
...@@ -5812,14 +5812,15 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5812,14 +5812,15 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{ {
if (VAR_P (expr)) if (VAR_P (expr))
{ {
if (complain & tf_error)
error ("%qD is not a valid template argument " error ("%qD is not a valid template argument "
"because %qD is a variable, not the address of " "because %qD is a variable, not the address of "
"a variable", "a variable", expr, expr);
expr, expr);
return NULL_TREE; return NULL_TREE;
} }
if (POINTER_TYPE_P (expr_type)) if (POINTER_TYPE_P (expr_type))
{ {
if (complain & tf_error)
error ("%qE is not a valid template argument for %qT " error ("%qE is not a valid template argument for %qT "
"because it is not the address of a variable", "because it is not the address of a variable",
expr, type); expr, type);
...@@ -5837,13 +5838,14 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5837,13 +5838,14 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
? TREE_OPERAND (expr, 0) : expr); ? TREE_OPERAND (expr, 0) : expr);
if (!VAR_P (decl)) if (!VAR_P (decl))
{ {
if (complain & tf_error)
error ("%qE is not a valid template argument of type %qT " error ("%qE is not a valid template argument of type %qT "
"because %qE is not a variable", "because %qE is not a variable", expr, type, decl);
expr, type, decl);
return NULL_TREE; return NULL_TREE;
} }
else if (cxx_dialect < cxx11 && !DECL_EXTERNAL_LINKAGE_P (decl)) else if (cxx_dialect < cxx11 && !DECL_EXTERNAL_LINKAGE_P (decl))
{ {
if (complain & tf_error)
error ("%qE is not a valid template argument of type %qT " error ("%qE is not a valid template argument of type %qT "
"because %qD does not have external linkage", "because %qD does not have external linkage",
expr, type, decl); expr, type, decl);
...@@ -5851,9 +5853,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5851,9 +5853,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
} }
else if (cxx_dialect >= cxx11 && decl_linkage (decl) == lk_none) else if (cxx_dialect >= cxx11 && decl_linkage (decl) == lk_none)
{ {
if (complain & tf_error)
error ("%qE is not a valid template argument of type %qT " error ("%qE is not a valid template argument of type %qT "
"because %qD has no linkage", "because %qD has no linkage", expr, type, decl);
expr, type, decl);
return NULL_TREE; return NULL_TREE;
} }
} }
...@@ -5881,6 +5883,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5881,6 +5883,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
if (!at_least_as_qualified_p (TREE_TYPE (type), expr_type)) if (!at_least_as_qualified_p (TREE_TYPE (type), expr_type))
{ {
if (complain & tf_error)
error ("%qE is not a valid template argument for type %qT " error ("%qE is not a valid template argument for type %qT "
"because of conflicts in cv-qualification", expr, type); "because of conflicts in cv-qualification", expr, type);
return NULL_TREE; return NULL_TREE;
...@@ -5888,6 +5891,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5888,6 +5891,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
if (!real_lvalue_p (expr)) if (!real_lvalue_p (expr))
{ {
if (complain & tf_error)
error ("%qE is not a valid template argument for type %qT " error ("%qE is not a valid template argument for type %qT "
"because it is not an lvalue", expr, type); "because it is not an lvalue", expr, type);
return NULL_TREE; return NULL_TREE;
...@@ -5905,6 +5909,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5905,6 +5909,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
expr = TREE_OPERAND (expr, 0); expr = TREE_OPERAND (expr, 0);
if (DECL_P (expr)) if (DECL_P (expr))
{ {
if (complain & tf_error)
error ("%q#D is not a valid template argument for type %qT " error ("%q#D is not a valid template argument for type %qT "
"because a reference variable does not have a constant " "because a reference variable does not have a constant "
"address", expr, type); "address", expr, type);
...@@ -5914,6 +5919,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5914,6 +5919,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
if (!DECL_P (expr)) if (!DECL_P (expr))
{ {
if (complain & tf_error)
error ("%qE is not a valid template argument for type %qT " error ("%qE is not a valid template argument for type %qT "
"because it is not an object with external linkage", "because it is not an object with external linkage",
expr, type); expr, type);
...@@ -5922,6 +5928,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5922,6 +5928,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
if (!DECL_EXTERNAL_LINKAGE_P (expr)) if (!DECL_EXTERNAL_LINKAGE_P (expr))
{ {
if (complain & tf_error)
error ("%qE is not a valid template argument for type %qT " error ("%qE is not a valid template argument for type %qT "
"because object %qD has not external linkage", "because object %qD has not external linkage",
expr, type, expr); expr, type, expr);
...@@ -5966,9 +5973,13 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5966,9 +5973,13 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{ {
if (TREE_CODE (expr) == ADDR_EXPR) if (TREE_CODE (expr) == ADDR_EXPR)
{ {
if (complain & tf_error)
{
error ("%qE is not a valid template argument for type %qT " error ("%qE is not a valid template argument for type %qT "
"because it is a pointer", expr, type); "because it is a pointer", expr, type);
inform (input_location, "try using %qE instead", TREE_OPERAND (expr, 0)); inform (input_location, "try using %qE instead",
TREE_OPERAND (expr, 0));
}
return NULL_TREE; return NULL_TREE;
} }
...@@ -6006,6 +6017,8 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -6006,6 +6017,8 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
provide a superior diagnostic. */ provide a superior diagnostic. */
if (!same_type_p (TREE_TYPE (expr), type)) if (!same_type_p (TREE_TYPE (expr), type))
{ {
if (complain & tf_error)
{
error ("%qE is not a valid template argument for type %qT " error ("%qE is not a valid template argument for type %qT "
"because it is of type %qT", expr, type, "because it is of type %qT", expr, type,
TREE_TYPE (expr)); TREE_TYPE (expr));
...@@ -6013,6 +6026,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -6013,6 +6026,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
if (can_convert_standard (type, TREE_TYPE (expr), complain)) if (can_convert_standard (type, TREE_TYPE (expr), complain))
inform (input_location, inform (input_location,
"standard conversions are not allowed in this context"); "standard conversions are not allowed in this context");
}
return NULL_TREE; return NULL_TREE;
} }
} }
...@@ -6035,6 +6049,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -6035,6 +6049,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{ {
if (expr != nullptr_node) if (expr != nullptr_node)
{ {
if (complain & tf_error)
error ("%qE is not a valid template argument for type %qT " error ("%qE is not a valid template argument for type %qT "
"because it is of type %qT", expr, type, TREE_TYPE (expr)); "because it is of type %qT", expr, type, TREE_TYPE (expr));
return NULL_TREE; return NULL_TREE;
......
2014-05-07 Paolo Carlini <paolo.carlini@oracle.com> 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 PR c++/61080
* g++.dg/cpp0x/deleted7.C: New. * g++.dg/cpp0x/deleted7.C: New.
......
// 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, "");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment