mirror of git://gcc.gnu.org/git/gcc.git
re PR c++/13092 (Accepts invalid pointer-to-member conversion)
PR c++/13092 * init.c (build_offset_ref): Build SCOPE_REF with non-null TREE_TYPE for non-dependent names. * typeck.c (build_x_unary_op): Handle non-dependent SCOPE_REF. * pt.c (type_dependent_expression_p): Handle SCOPE_REF with unknown_type_node as its TREE_TYPE. * cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK. * error.c (dump_decl) <SCOPE_REF case>: Use pp_expression. (dump_expr) <SCOPE_REF case>: Likewise. * g++.dg/template/non-dependent7.C: New test. * g++.dg/template/non-dependent8.C: Likewise. * g++.dg/template/non-dependent9.C: Likewise. * g++.dg/template/non-dependent10.C: Likewise. From-SVN: r84889
This commit is contained in:
parent
605570470c
commit
3601f00362
|
@ -1,3 +1,15 @@
|
||||||
|
2004-07-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||||
|
|
||||||
|
PR c++/13092
|
||||||
|
* init.c (build_offset_ref): Build SCOPE_REF with non-null
|
||||||
|
TREE_TYPE for non-dependent names.
|
||||||
|
* typeck.c (build_x_unary_op): Handle non-dependent SCOPE_REF.
|
||||||
|
* pt.c (type_dependent_expression_p): Handle SCOPE_REF with
|
||||||
|
unknown_type_node as its TREE_TYPE.
|
||||||
|
* cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK.
|
||||||
|
* error.c (dump_decl) <SCOPE_REF case>: Use pp_expression.
|
||||||
|
(dump_expr) <SCOPE_REF case>: Likewise.
|
||||||
|
|
||||||
2004-07-17 Jason Merrill <jason@redhat.com>
|
2004-07-17 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
PR c++/16115
|
PR c++/16115
|
||||||
|
|
|
@ -180,6 +180,10 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
|
||||||
pp_cxx_template_id (pp, t);
|
pp_cxx_template_id (pp, t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BASELINK:
|
||||||
|
pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
|
||||||
|
break;
|
||||||
|
|
||||||
case RECORD_TYPE:
|
case RECORD_TYPE:
|
||||||
case UNION_TYPE:
|
case UNION_TYPE:
|
||||||
case ENUMERAL_TYPE:
|
case ENUMERAL_TYPE:
|
||||||
|
|
|
@ -764,9 +764,7 @@ dump_decl (tree t, int flags)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCOPE_REF:
|
case SCOPE_REF:
|
||||||
dump_decl (TREE_OPERAND (t, 0), flags & ~TFF_DECL_SPECIFIERS);
|
pp_expression (cxx_pp, t);
|
||||||
pp_colon_colon (cxx_pp);
|
|
||||||
dump_decl (TREE_OPERAND (t, 1), flags);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARRAY_REF:
|
case ARRAY_REF:
|
||||||
|
@ -1708,9 +1706,7 @@ dump_expr (tree t, int flags)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCOPE_REF:
|
case SCOPE_REF:
|
||||||
dump_type (TREE_OPERAND (t, 0), flags);
|
pp_expression (cxx_pp, t);
|
||||||
pp_cxx_colon_colon (cxx_pp);
|
|
||||||
dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAST_EXPR:
|
case CAST_EXPR:
|
||||||
|
|
|
@ -1334,7 +1334,7 @@ build_offset_ref (tree type, tree name, bool address_p)
|
||||||
if (TREE_CODE (name) == TEMPLATE_DECL)
|
if (TREE_CODE (name) == TEMPLATE_DECL)
|
||||||
return name;
|
return name;
|
||||||
|
|
||||||
if (processing_template_decl || uses_template_parms (type))
|
if (dependent_type_p (type) || type_dependent_expression_p (name))
|
||||||
return build_min_nt (SCOPE_REF, type, name);
|
return build_min_nt (SCOPE_REF, type, name);
|
||||||
|
|
||||||
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
|
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
|
||||||
|
@ -1398,6 +1398,7 @@ build_offset_ref (tree type, tree name, bool address_p)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set up BASEBINFO for member lookup. */
|
||||||
decl = maybe_dummy_object (type, &basebinfo);
|
decl = maybe_dummy_object (type, &basebinfo);
|
||||||
|
|
||||||
if (BASELINK_P (name) || DECL_P (name))
|
if (BASELINK_P (name) || DECL_P (name))
|
||||||
|
@ -1416,6 +1417,14 @@ build_offset_ref (tree type, tree name, bool address_p)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (processing_template_decl)
|
||||||
|
{
|
||||||
|
if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
|
||||||
|
return build_min (SCOPE_REF, TREE_TYPE (member), type, orig_name);
|
||||||
|
else
|
||||||
|
return build_min (SCOPE_REF, TREE_TYPE (member), type, name);
|
||||||
|
}
|
||||||
|
|
||||||
if (TREE_CODE (member) == TYPE_DECL)
|
if (TREE_CODE (member) == TYPE_DECL)
|
||||||
{
|
{
|
||||||
TREE_USED (member) = 1;
|
TREE_USED (member) = 1;
|
||||||
|
|
|
@ -11866,6 +11866,9 @@ type_dependent_expression_p (tree expression)
|
||||||
if (TREE_CODE (expression) == IDENTIFIER_NODE)
|
if (TREE_CODE (expression) == IDENTIFIER_NODE)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
/* SCOPE_REF with non-null TREE_TYPE is always non-dependent. */
|
||||||
|
if (TREE_CODE (expression) == SCOPE_REF)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (TREE_CODE (expression) == BASELINK)
|
if (TREE_CODE (expression) == BASELINK)
|
||||||
expression = BASELINK_FUNCTIONS (expression);
|
expression = BASELINK_FUNCTIONS (expression);
|
||||||
|
|
|
@ -3530,6 +3530,24 @@ build_x_unary_op (enum tree_code code, tree xarg)
|
||||||
{
|
{
|
||||||
if (type_dependent_expression_p (xarg))
|
if (type_dependent_expression_p (xarg))
|
||||||
return build_min_nt (code, xarg, NULL_TREE);
|
return build_min_nt (code, xarg, NULL_TREE);
|
||||||
|
|
||||||
|
/* For non-dependent pointer-to-member, the SCOPE_REF will be
|
||||||
|
processed during template substitution. Just compute the
|
||||||
|
right type here and build an ADDR_EXPR around it for
|
||||||
|
diagnostics. */
|
||||||
|
if (code == ADDR_EXPR && TREE_CODE (xarg) == SCOPE_REF)
|
||||||
|
{
|
||||||
|
tree type;
|
||||||
|
if (TREE_TYPE (xarg) == unknown_type_node)
|
||||||
|
type = unknown_type_node;
|
||||||
|
else if (TREE_CODE (TREE_TYPE (xarg)) == FUNCTION_TYPE)
|
||||||
|
type = build_pointer_type (TREE_TYPE (xarg));
|
||||||
|
else
|
||||||
|
type = build_ptrmem_type (TREE_OPERAND (xarg, 0),
|
||||||
|
TREE_TYPE (xarg));
|
||||||
|
return build_min (code, type, xarg, NULL_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
xarg = build_non_dependent_expr (xarg);
|
xarg = build_non_dependent_expr (xarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
2004-07-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||||
|
|
||||||
|
PR c++/13092
|
||||||
|
* g++.dg/template/non-dependent7.C: New test.
|
||||||
|
* g++.dg/template/non-dependent8.C: Likewise.
|
||||||
|
* g++.dg/template/non-dependent9.C: Likewise.
|
||||||
|
* g++.dg/template/non-dependent10.C: Likewise.
|
||||||
|
|
||||||
2004-07-17 Mark Mitchell <mark@codesourcery.com>
|
2004-07-17 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
PR c++/16337
|
PR c++/16337
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
|
||||||
|
// Origin: Giovanni Bajo <giovannibajo@libero.it>
|
||||||
|
|
||||||
|
// Two-phase name lookup for address of member:
|
||||||
|
// Detecting overloading function error during parsing
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int f(char);
|
||||||
|
int f(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int (S::*p)()>
|
||||||
|
struct X
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
X<&S::f> x; // { dg-error "convert|no type" }
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
|
||||||
|
// Origin: Giovanni Bajo <giovannibajo@libero.it>
|
||||||
|
|
||||||
|
// PR c++/13092: ICE taking address of member which is non-dependent
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int S::*p>
|
||||||
|
struct X
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
X<&S::i> x;
|
||||||
|
};
|
||||||
|
|
||||||
|
template struct Foo<void>;
|
|
@ -0,0 +1,21 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
|
||||||
|
// Origin: Giovanni Bajo <giovannibajo@libero.it>
|
||||||
|
|
||||||
|
// Two-phase name lookup for address of member:
|
||||||
|
// Detecting error during parsing
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
char i;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int S::*p>
|
||||||
|
struct X
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
X<&S::i> x; // { dg-error "convert|no type" }
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
|
||||||
|
// Origin: Giovanni Bajo <giovannibajo@libero.it>
|
||||||
|
|
||||||
|
// Two-phase name lookup for address of member:
|
||||||
|
// Overloading function
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int f();
|
||||||
|
int f(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int (S::*p)()>
|
||||||
|
struct X
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
X<&S::f> x;
|
||||||
|
};
|
Loading…
Reference in New Issue