re PR c++/16338 (ICE when throwing a compound literal)
PR c++/16338 * cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): New macro. * call.c (null_ptr_cst_p): Handle variables with constant initializers. * pt.c (convert_nontype_argument): Use DECL_INTEGRAL_CONSTANT_VAR_P. * semantics.c (finish_id_expression): Likewise. PR c++~/16489 * decl.c (duplicate_decls): Reject duplicate namespace declarations. PR c++/16810 * typeck.c (build_ptrmemfunc): Loosen assertion. PR c++/16338 * g++.dg/init/null1.C: New test. * g++.dg/tc1/dr76.C: Adjust error marker. PR c++/16489 * g++.dg/parse/namespace10.C: New test. PR c++/16810 * g++.dg/inherit/ptrmem2.C: New test. From-SVN: r85421
This commit is contained in:
parent
112ccb83bb
commit
c30b4add62
12 changed files with 128 additions and 34 deletions
|
@ -1,3 +1,20 @@
|
|||
2004-08-01 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/16338
|
||||
* cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): New macro.
|
||||
* call.c (null_ptr_cst_p): Handle variables with constant
|
||||
initializers.
|
||||
* pt.c (convert_nontype_argument): Use
|
||||
DECL_INTEGRAL_CONSTANT_VAR_P.
|
||||
* semantics.c (finish_id_expression): Likewise.
|
||||
|
||||
PR c++~/16489
|
||||
* decl.c (duplicate_decls): Reject duplicate namespace
|
||||
declarations.
|
||||
|
||||
PR c++/16810
|
||||
* typeck.c (build_ptrmemfunc): Loosen assertion.
|
||||
|
||||
2004-08-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
* call.c (z_candidate::template_decl): Rename from template.
|
||||
|
|
|
@ -429,6 +429,9 @@ struct z_candidate {
|
|||
z_candidate *next;
|
||||
};
|
||||
|
||||
/* Returns true iff T is a null pointer constant in the sense of
|
||||
[conv.ptr]. */
|
||||
|
||||
bool
|
||||
null_ptr_cst_p (tree t)
|
||||
{
|
||||
|
@ -436,13 +439,14 @@ null_ptr_cst_p (tree t)
|
|||
|
||||
A null pointer constant is an integral constant expression
|
||||
(_expr.const_) rvalue of integer type that evaluates to zero. */
|
||||
if (DECL_INTEGRAL_CONSTANT_VAR_P (t))
|
||||
t = decl_constant_value (t);
|
||||
if (t == null_node
|
||||
|| (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Returns nonzero if PARMLIST consists of only default parms and/or
|
||||
ellipsis. */
|
||||
|
||||
|
|
|
@ -1821,6 +1821,23 @@ struct lang_decl GTY(())
|
|||
#define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \
|
||||
(TREE_LANG_FLAG_2 (VAR_DECL_CHECK (NODE)))
|
||||
|
||||
/* Nonzero for a VAR_DECL that can be used in an integral constant
|
||||
expression.
|
||||
|
||||
[expr.const]
|
||||
|
||||
An integral constant-expression can only involve ... const
|
||||
variables of static or enumeration types initialized with
|
||||
constant expressions ...
|
||||
|
||||
The standard does not require that the expression be non-volatile.
|
||||
G++ implements the proposed correction in DR 457. */
|
||||
#define DECL_INTEGRAL_CONSTANT_VAR_P(NODE) \
|
||||
(TREE_CODE (NODE) == VAR_DECL \
|
||||
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (NODE)) \
|
||||
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (NODE)) \
|
||||
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (NODE))
|
||||
|
||||
/* Nonzero if the DECL was initialized in the class definition itself,
|
||||
rather than outside the class. This is used for both static member
|
||||
VAR_DECLS, and FUNTION_DECLS that are defined in the class. */
|
||||
|
|
|
@ -1407,19 +1407,32 @@ duplicate_decls (tree newdecl, tree olddecl)
|
|||
/* One of the declarations is a template instantiation, and the
|
||||
other is not a template at all. That's OK. */
|
||||
return NULL_TREE;
|
||||
else if (TREE_CODE (newdecl) == NAMESPACE_DECL
|
||||
&& DECL_NAMESPACE_ALIAS (newdecl)
|
||||
&& DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl))
|
||||
/* In [namespace.alias] we have:
|
||||
else if (TREE_CODE (newdecl) == NAMESPACE_DECL)
|
||||
{
|
||||
/* In [namespace.alias] we have:
|
||||
|
||||
In a declarative region, a namespace-alias-definition can be
|
||||
used to redefine a namespace-alias declared in that declarative
|
||||
region to refer only to the namespace to which it already
|
||||
refers.
|
||||
|
||||
Therefore, if we encounter a second alias directive for the same
|
||||
alias, we can just ignore the second directive. */
|
||||
if (DECL_NAMESPACE_ALIAS (newdecl)
|
||||
&& (DECL_NAMESPACE_ALIAS (newdecl)
|
||||
== DECL_NAMESPACE_ALIAS (olddecl)))
|
||||
return olddecl;
|
||||
/* [namespace.alias]
|
||||
|
||||
In a declarative region, a namespace-alias-definition can be
|
||||
used to redefine a namespace-alias declared in that declarative
|
||||
region to refer only to the namespace to which it already
|
||||
refers.
|
||||
|
||||
Therefore, if we encounter a second alias directive for the same
|
||||
alias, we can just ignore the second directive. */
|
||||
return olddecl;
|
||||
A namespace-name or namespace-alias shall not be declared as
|
||||
the name of any other entity in the same declarative region.
|
||||
A namespace-name defined at global scope shall not be
|
||||
declared as the name of any other entity in any glogal scope
|
||||
of the program. */
|
||||
error ("declaration of `namespace %D' conflicts with", newdecl);
|
||||
cp_error_at ("previous declaration of `namespace %D' here", olddecl);
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *errmsg = redeclaration_error_message (newdecl, olddecl);
|
||||
|
|
|
@ -3233,9 +3233,7 @@ convert_nontype_argument (tree type, tree expr)
|
|||
will not return the initializer. Handle that special case
|
||||
here. */
|
||||
if (expr == const_expr
|
||||
&& TREE_CODE (expr) == VAR_DECL
|
||||
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (expr)
|
||||
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (expr))
|
||||
&& DECL_INTEGRAL_CONSTANT_VAR_P (expr)
|
||||
/* DECL_INITIAL can be NULL if we are processing a
|
||||
variable initialized to an expression involving itself.
|
||||
We know it is initialized to a constant -- but not what
|
||||
|
|
|
@ -2564,25 +2564,15 @@ finish_id_expression (tree id_expression,
|
|||
/* Only certain kinds of names are allowed in constant
|
||||
expression. Enumerators and template parameters
|
||||
have already been handled above. */
|
||||
if (integral_constant_expression_p)
|
||||
if (integral_constant_expression_p
|
||||
&& !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
|
||||
{
|
||||
/* Const variables or static data members of integral or
|
||||
enumeration types initialized with constant expressions
|
||||
are OK. */
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& CP_TYPE_CONST_P (TREE_TYPE (decl))
|
||||
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))
|
||||
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
|
||||
;
|
||||
else
|
||||
if (!allow_non_integral_constant_expression_p)
|
||||
{
|
||||
if (!allow_non_integral_constant_expression_p)
|
||||
{
|
||||
error ("`%D' cannot appear in a constant-expression", decl);
|
||||
return error_mark_node;
|
||||
}
|
||||
*non_integral_constant_expression_p = true;
|
||||
error ("`%D' cannot appear in a constant-expression", decl);
|
||||
return error_mark_node;
|
||||
}
|
||||
*non_integral_constant_expression_p = true;
|
||||
}
|
||||
|
||||
if (TREE_CODE (decl) == NAMESPACE_DECL)
|
||||
|
|
|
@ -5463,7 +5463,10 @@ build_ptrmemfunc (tree type, tree pfn, int force)
|
|||
}
|
||||
|
||||
/* Just adjust the DELTA field. */
|
||||
my_friendly_assert (TREE_TYPE (delta) == ptrdiff_type_node, 20030727);
|
||||
my_friendly_assert
|
||||
(same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (delta),
|
||||
ptrdiff_type_node),
|
||||
20030727);
|
||||
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
|
||||
n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node);
|
||||
delta = cp_build_binary_op (PLUS_EXPR, delta, n);
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
2004-08-01 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/16338
|
||||
* g++.dg/init/null1.C: New test.
|
||||
* g++.dg/tc1/dr76.C: Adjust error marker.
|
||||
|
||||
PR c++/16489
|
||||
* g++.dg/parse/namespace10.C: New test.
|
||||
|
||||
PR c++/16810
|
||||
* g++.dg/inherit/ptrmem2.C: New test.
|
||||
|
||||
2004-08-02 Ben Elliston <bje@au.ibm.com>
|
||||
|
||||
PR target/16155
|
||||
|
|
25
gcc/testsuite/g++.dg/inherit/ptrmem2.C
Normal file
25
gcc/testsuite/g++.dg/inherit/ptrmem2.C
Normal file
|
@ -0,0 +1,25 @@
|
|||
// PR c++/16810
|
||||
|
||||
struct C {
|
||||
virtual void f() {}
|
||||
};
|
||||
|
||||
struct B {virtual ~B() {} };
|
||||
|
||||
class D : public B, public C
|
||||
{
|
||||
public:
|
||||
virtual void f() {}
|
||||
};
|
||||
|
||||
typedef void ( C::*FP)();
|
||||
typedef void ( D::*D_f)();
|
||||
|
||||
int main() {
|
||||
D *d = new D();
|
||||
C *c = d;
|
||||
|
||||
const FP fptr = (FP) &D::f;;
|
||||
(d->* (D_f)fptr)();
|
||||
}
|
||||
|
6
gcc/testsuite/g++.dg/init/null1.C
Normal file
6
gcc/testsuite/g++.dg/init/null1.C
Normal file
|
@ -0,0 +1,6 @@
|
|||
// PR c++/16338
|
||||
|
||||
const int NULL = 0;
|
||||
int main() {
|
||||
double* p = NULL;
|
||||
}
|
9
gcc/testsuite/g++.dg/parse/namespace10.C
Normal file
9
gcc/testsuite/g++.dg/parse/namespace10.C
Normal file
|
@ -0,0 +1,9 @@
|
|||
// PR c++/16489
|
||||
|
||||
namespace m {} // { dg-error "" }
|
||||
|
||||
namespace n {
|
||||
namespace m {}
|
||||
}
|
||||
|
||||
namespace m = n::m; // { dg-error "" }
|
|
@ -5,4 +5,4 @@
|
|||
volatile const int a = 5;
|
||||
|
||||
template <int> struct K;
|
||||
template struct K<a>; // { dg-error "non-constant" }
|
||||
template struct K<a>; // { dg-error "" }
|
||||
|
|
Loading…
Add table
Reference in a new issue