re PR c++/5132 (NaN = 0.0 * HUGE_VAL fails to compile in templates)
cp: PR c++/5132 * typeck2.c (digest_init): Make sure non-array core type is instantiated. * decl2.c (reparse_absdcl_as_casts): Just store the type in the constructor, rather than build a new one. (build_expr_from_tree, CONSTRUCTOR case): Be careful with the PURPOSE of constructor elts. testsuite: * g++.dg/template/ctor1.C: Add instantiation. From-SVN: r49314
This commit is contained in:
parent
aee25e2d8e
commit
b8b98c66af
|
@ -1,3 +1,13 @@
|
|||
2002-01-29 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/5132
|
||||
* typeck2.c (digest_init): Make sure non-array core type is
|
||||
instantiated.
|
||||
* decl2.c (reparse_absdcl_as_casts): Just store the type in the
|
||||
constructor, rather than build a new one.
|
||||
(build_expr_from_tree, CONSTRUCTOR case): Be careful with the
|
||||
PURPOSE of constructor elts.
|
||||
|
||||
2002-01-23 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
* Make-lang.in (parse.c): Adjust expected number of
|
||||
|
|
|
@ -3620,7 +3620,7 @@ reparse_absdcl_as_casts (decl, expr)
|
|||
decl = TREE_OPERAND (decl, 0);
|
||||
|
||||
if (processing_template_decl)
|
||||
expr = build_min (CONSTRUCTOR, type, decl, CONSTRUCTOR_ELTS (expr));
|
||||
TREE_TYPE (expr) = type;
|
||||
else
|
||||
{
|
||||
expr = digest_init (type, expr, (tree *) 0);
|
||||
|
@ -3938,17 +3938,35 @@ build_expr_from_tree (t)
|
|||
case CONSTRUCTOR:
|
||||
{
|
||||
tree r;
|
||||
tree elts;
|
||||
tree type = TREE_TYPE (t);
|
||||
bool purpose_p;
|
||||
|
||||
/* digest_init will do the wrong thing if we let it. */
|
||||
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
|
||||
if (type && TYPE_PTRMEMFUNC_P (type))
|
||||
return t;
|
||||
|
||||
r = build_nt (CONSTRUCTOR, NULL_TREE,
|
||||
build_expr_from_tree (CONSTRUCTOR_ELTS (t)));
|
||||
r = NULL_TREE;
|
||||
/* We do not want to process the purpose of aggregate
|
||||
initializers as they are identifier nodes which will be
|
||||
looked up by digest_init. */
|
||||
purpose_p = !(type && IS_AGGR_TYPE (type));
|
||||
for (elts = CONSTRUCTOR_ELTS (t); elts; elts = TREE_CHAIN (elts))
|
||||
{
|
||||
tree purpose = TREE_PURPOSE (elts);
|
||||
tree value = TREE_VALUE (elts);
|
||||
|
||||
if (purpose && purpose_p)
|
||||
purpose = build_expr_from_tree (purpose);
|
||||
value = build_expr_from_tree (value);
|
||||
r = tree_cons (purpose, value, r);
|
||||
}
|
||||
|
||||
r = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (r));
|
||||
TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
|
||||
|
||||
if (TREE_TYPE (t))
|
||||
return digest_init (TREE_TYPE (t), r, 0);
|
||||
if (type)
|
||||
return digest_init (type, r, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -458,6 +458,12 @@ digest_init (type, init, tail)
|
|||
/* __PRETTY_FUNCTION__'s initializer is a bogus expression inside
|
||||
a template function. This gets substituted during instantiation. */
|
||||
return init;
|
||||
|
||||
/* We must strip the outermost array type when completing the type,
|
||||
because the its bounds might be incomplete at the moment. */
|
||||
if (!complete_type_or_else (TREE_CODE (type) == ARRAY_TYPE
|
||||
? TREE_TYPE (type) : type, NULL_TREE))
|
||||
return error_mark_node;
|
||||
|
||||
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
|
||||
if (TREE_CODE (init) == NON_LVALUE_EXPR)
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2002-01-29 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* g++.dg/template/ctor1.C: Add instantiation.
|
||||
|
||||
2002-01-28 Paul Koning <pkoning@equallogic.com>
|
||||
|
||||
* gcc.c-torture/execute/builtin-prefetch-1.c: Changed first
|
||||
|
|
|
@ -20,3 +20,12 @@ template <class F>
|
|||
void Tfoo( const F&) {
|
||||
HUGE_VAL; // g++ fails here
|
||||
}
|
||||
|
||||
template <typename T> struct M { T m; };
|
||||
|
||||
void Foo ()
|
||||
{
|
||||
Tfoo (1.2f);
|
||||
(__extension__ ((M<int>) {m:3}));
|
||||
(__extension__ ((M<short> []) {{m:3}}));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue