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>
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.
......
......@@ -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;
......
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.
......
// 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