Commit b6ab6892 by Giovanni Bajo

DR 49, 100

	DR 49, 100
	* cp-tree.h (TYPE_REF_OBJ_P): New macro.
	(TYPE_PTR_P, TYPE_PTROB_P, TYPE_PTROBV_P, TYPE_PTRFN_P,
	TYPE_REFFN_P): Document.
	(fold_decl_constant_value): New prototype.
	* pt.c (convert_nontype_argument_function): Rewrite and extract
	parts into...
	(fold_decl_constant_value, convert_nontype_argument_function): New.
	(lookup_template_class): Add comment about useless double call.
	* mangle.c (write_expression): Strip conversions before lowering
	pointer to members.
	* cvt.c (ocp_convert): Check LOOKUP_COMPLAIN for a pedwarn. Disallow
	enum to enum conversion.

	* g++.dg/template/nontype7.C: New test.
	* g++.dg/template/nontype8.C: Likewise.
	* g++.dg/template/nontype9.C: Likewise.
	* g++.dg/template/nontype10.C: Likewise.
	* g++.dg/tc1/dr49.C: Likewise.
	* g++.dg/template/ptrmem8.C: Relax dg-error checks.
	* g++.old-deja/g++.other/null1.C: Remove a buggy error check

From-SVN: r90059
parent eba7452b
2004-11-04 Giovanni Bajo <giovannibajo@gcc.gnu.org>
DR 49, 100
* cp-tree.h (TYPE_REF_OBJ_P): New macro.
(TYPE_PTR_P, TYPE_PTROB_P, TYPE_PTROBV_P, TYPE_PTRFN_P,
TYPE_REFFN_P): Document.
(fold_decl_constant_value): New prototype.
* pt.c (convert_nontype_argument_function): Rewrite and extract
parts into...
(fold_decl_constant_value, convert_nontype_argument_function): New.
(lookup_template_class): Add comment about useless double call.
* mangle.c (write_expression): Strip conversions before lowering
pointer to members.
* cvt.c (ocp_convert): Check LOOKUP_COMPLAIN for a pedwarn. Disallow
enum to enum conversion.
2004-11-02 Mark Mitchell <mark@codesourcery.com>
PR c++/18124
......
......@@ -2398,18 +2398,29 @@ struct lang_decl GTY(())
/* Returns true if NODE is a pointer-to-data-member. */
#define TYPE_PTRMEM_P(NODE) \
(TREE_CODE (NODE) == OFFSET_TYPE)
/* Returns true if NODE is a pointer. */
#define TYPE_PTR_P(NODE) \
(TREE_CODE (NODE) == POINTER_TYPE)
/* Returns true if NODE is a pointer to an object. */
#define TYPE_PTROB_P(NODE) \
(TYPE_PTR_P (NODE) \
&& TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE \
&& TREE_CODE (TREE_TYPE (NODE)) != METHOD_TYPE \
&& TREE_CODE (TREE_TYPE (NODE)) != VOID_TYPE)
/* Returns true if NODE is a reference to an object. */
#define TYPE_REF_OBJ_P(NODE) \
(TREE_CODE (NODE) == REFERENCE_TYPE \
&& TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE \
&& TREE_CODE (TREE_TYPE (NODE)) != METHOD_TYPE \
&& TREE_CODE (TREE_TYPE (NODE)) != VOID_TYPE)
/* Returns true if NODE is a pointer to an object, or a pointer to void. */
#define TYPE_PTROBV_P(NODE) \
(TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE)
/* Returns true if NODE is a pointer to function. */
#define TYPE_PTRFN_P(NODE) \
(TREE_CODE (NODE) == POINTER_TYPE \
&& TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
/* Returns true if NODE is a reference to function. */
#define TYPE_REFFN_P(NODE) \
(TREE_CODE (NODE) == REFERENCE_TYPE \
&& TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
......@@ -3976,6 +3987,7 @@ extern tree build_non_dependent_expr (tree);
extern tree build_non_dependent_args (tree);
extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree);
extern tree fold_decl_constant_value (tree);
/* in repo.c */
extern void init_repo (void);
......
......@@ -662,10 +662,13 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
/* enum = enum, enum = int, enum = float, (enum)pointer are all
errors. */
if (TREE_CODE (type) == ENUMERAL_TYPE
&& ((ARITHMETIC_TYPE_P (intype) && ! (convtype & CONV_STATIC))
|| (TREE_CODE (intype) == POINTER_TYPE)))
&& (((INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
|| TREE_CODE (intype) == REAL_TYPE)
&& ! (convtype & CONV_STATIC))
|| TREE_CODE (intype) == POINTER_TYPE))
{
pedwarn ("conversion from %q#T to %q#T", intype, type);
if (flags & LOOKUP_COMPLAIN)
pedwarn ("conversion from %q#T to %q#T", intype, type);
if (flag_pedantic_errors)
return error_mark_node;
......
......@@ -1969,6 +1969,16 @@ write_expression (tree expr)
code = TREE_CODE (expr);
/* Skip NOP_EXPRs. They can occur when (say) a pointer argument
is converted (via qualification conversions) to another
type. */
while (TREE_CODE (expr) == NOP_EXPR
|| TREE_CODE (expr) == NON_LVALUE_EXPR)
{
expr = TREE_OPERAND (expr, 0);
code = TREE_CODE (expr);
}
/* Handle pointers-to-members by making them look like expression
nodes. */
if (code == PTRMEM_CST)
......@@ -1980,16 +1990,6 @@ write_expression (tree expr)
code = TREE_CODE (expr);
}
/* Skip NOP_EXPRs. They can occur when (say) a pointer argument
is converted (via qualification conversions) to another
type. */
while (TREE_CODE (expr) == NOP_EXPR
|| TREE_CODE (expr) == NON_LVALUE_EXPR)
{
expr = TREE_OPERAND (expr, 0);
code = TREE_CODE (expr);
}
/* Handle template parameters. */
if (code == TEMPLATE_TYPE_PARM
|| code == TEMPLATE_TEMPLATE_PARM
......
2004-11-04 Giovanni Bajo <giovannibajo@gcc.gnu.org>
* g++.dg/template/nontype7.C: New test.
* g++.dg/template/nontype8.C: Likewise.
* g++.dg/template/nontype9.C: Likewise.
* g++.dg/template/nontype10.C: Likewise.
* g++.dg/tc1/dr49.C: Likewise.
* g++.dg/template/ptrmem8.C: Relax dg-error checks.
* g++.old-deja/g++.other/null1.C: Remove a buggy error check
2004-11-04 Ben Elliston <bje@au.ibm.com>
* g++.dg/rtti/tinfo1.C: Remove xfails.
......
// { dg-do compile }
// Contributed by: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
// DR 49: Non-constant pointers are invalid template arguments.
template<int *a> struct R { /* ... */ };
template<int b[5]> struct S { /* ... */ };
int p;
template struct R<&p>; // OK
template struct S<&p>; // OK due to parameter adjustment
int *ptr;
template struct R<ptr>; // { dg-error "constant" }
template struct S<ptr>; // { dg-error "constant" }
int v[5];
template struct R<v>; // OK due to implicit argument conversion
template struct S<v>; // OK due to both adjustment and conversion
// { dg-do compile }
// Contributed by: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
#include <cstddef>
template <int T> struct A {};
template <void* T> struct B {};
A<NULL> a;
B<NULL> b; // { dg-error "" }
// { dg-do compile }
// Origin: C++ standard, [temp.arg.nontype]/2
template<class T, char* p> struct X {
X();
X(const char* q) { /* ... */ }
};
char p[] = "Vivisectionist";
X<int,"Studebaker"> x1; // { dg-error "string literal" }
X<int, p> x2;
// { dg-bogus "" "additional errors" { xfail *-*-* } 11 }
// { dg-do compile }
// Origin: C++ standard, [temp.arg.nontype]/3
template<int* p> class X { };
int a[10];
struct S { int m; static int s; } s;
X<&a[2]> x3; // { dg-error "" } address of array element
X<&s.m> x4; // { dg-error "" } address of non-static member
X<&s.s> x5; // { dg-error "" } &S::s must be used
X<&S::s> x6; // OK: address of static member
// { dg-do compile }
// Contributed by: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
int i;
template <void (&FN)()>
struct g {
void foo(void) {
FN ();
}
};
void h ()
{
i = 7;
}
template struct g<h>;
......@@ -15,6 +15,6 @@ template <int (D::*fun)() const> int Get();
int main ()
{
Get<&B::I>(); // { dg-error "no matching function" }
Get<&D::I>(); // { dg-error "no matching function" }
Get<&B::I>(); // { dg-error "" }
Get<&D::I>(); // { dg-error "" }
}
......@@ -38,7 +38,7 @@ int main()
z = NULL; // { dg-warning "" } converting NULL to non-pointer type
k(NULL); // { dg-warning "" } converting NULL to int
g(NULL); // { dg-warning "" } converting NULL to int
h<NULL>(); // { dg-warning "" } NULL bound to integer template parameter
h<NULL>(); // No warning: NULL bound to integer template parameter
l(NULL); // { dg-warning "" } converting NULL to int
NULL && NULL; // No warning: converting NULL to bool is OK
}
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