mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-26 02:59:04 +08:00
re PR c++/5661 (Gcc 3.0.3 Seg faults compiling bad code)
PR c++/5661 * cp-tree.h (variably_modified_type_p): New function. (grokdeclarator) Tighten check for variably modified types as fields. * pt.c (convert_template_argument): Do not allow variably modified types as template arguments. * tree.c (variably_modified_type_p): New function. PR c++/5661 * g++.dg/ext/vlm1.C: New test. * g++.dg/ext/vlm2.C: Likewise. From-SVN: r58060
This commit is contained in:
parent
46dd38849b
commit
dac45b5c09
@ -11,6 +11,14 @@
|
|||||||
|
|
||||||
2002-10-11 Mark Mitchell <mark@codesourcery.com>
|
2002-10-11 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
PR c++/5661
|
||||||
|
* cp-tree.h (variably_modified_type_p): New function.
|
||||||
|
(grokdeclarator) Tighten check for variably modified types as
|
||||||
|
fields.
|
||||||
|
* pt.c (convert_template_argument): Do not allow variably modified
|
||||||
|
types as template arguments.
|
||||||
|
* tree.c (variably_modified_type_p): New function.
|
||||||
|
|
||||||
* NEWS: Document removal of "new X = ..." extension.
|
* NEWS: Document removal of "new X = ..." extension.
|
||||||
* class.c (initialize_array): Set TREE_HAS_CONSTRUCTOR on
|
* class.c (initialize_array): Set TREE_HAS_CONSTRUCTOR on
|
||||||
brace-enclosed initializers.
|
brace-enclosed initializers.
|
||||||
|
@ -4179,6 +4179,7 @@ extern tree cxx_unsave_expr_now PARAMS ((tree));
|
|||||||
extern tree cxx_maybe_build_cleanup PARAMS ((tree));
|
extern tree cxx_maybe_build_cleanup PARAMS ((tree));
|
||||||
extern void init_tree PARAMS ((void));
|
extern void init_tree PARAMS ((void));
|
||||||
extern int pod_type_p PARAMS ((tree));
|
extern int pod_type_p PARAMS ((tree));
|
||||||
|
extern bool variably_modified_type_p (tree);
|
||||||
extern int zero_init_p PARAMS ((tree));
|
extern int zero_init_p PARAMS ((tree));
|
||||||
extern tree canonical_type_variant PARAMS ((tree));
|
extern tree canonical_type_variant PARAMS ((tree));
|
||||||
extern void unshare_base_binfos PARAMS ((tree));
|
extern void unshare_base_binfos PARAMS ((tree));
|
||||||
|
@ -10928,19 +10928,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||||||
|
|
||||||
type = create_array_type_for_decl (dname, type, size);
|
type = create_array_type_for_decl (dname, type, size);
|
||||||
|
|
||||||
/* VLAs never work as fields. */
|
|
||||||
if (decl_context == FIELD && !processing_template_decl
|
|
||||||
&& TREE_CODE (type) == ARRAY_TYPE
|
|
||||||
&& TYPE_DOMAIN (type) != NULL_TREE
|
|
||||||
&& !TREE_CONSTANT (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
|
|
||||||
{
|
|
||||||
error ("size of member `%D' is not constant", dname);
|
|
||||||
/* Proceed with arbitrary constant size, so that offset
|
|
||||||
computations don't get confused. */
|
|
||||||
type = create_array_type_for_decl (dname, TREE_TYPE (type),
|
|
||||||
integer_one_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctype = NULL_TREE;
|
ctype = NULL_TREE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -11420,6 +11407,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||||||
type = error_mark_node;
|
type = error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (decl_context == FIELD
|
||||||
|
&& !processing_template_decl
|
||||||
|
&& variably_modified_type_p (type))
|
||||||
|
{
|
||||||
|
error ("data member may not have variably modified type `%T'", type);
|
||||||
|
type = error_mark_node;
|
||||||
|
}
|
||||||
|
|
||||||
if (explicitp == 1 || (explicitp && friendp))
|
if (explicitp == 1 || (explicitp && friendp))
|
||||||
{
|
{
|
||||||
/* [dcl.fct.spec] The explicit specifier shall only be used in
|
/* [dcl.fct.spec] The explicit specifier shall only be used in
|
||||||
|
10
gcc/cp/pt.c
10
gcc/cp/pt.c
@ -3467,6 +3467,16 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
|
|||||||
val, t);
|
val, t);
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In order to avoid all sorts of complications, we do
|
||||||
|
not allow variably-modified types as template
|
||||||
|
arguments. */
|
||||||
|
if (variably_modified_type_p (val))
|
||||||
|
{
|
||||||
|
error ("template-argument `%T' is a variably modified type",
|
||||||
|
val);
|
||||||
|
return error_mark_node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1958,6 +1958,72 @@ pod_type_p (t)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if T is a variably modified type, in the sense of
|
||||||
|
C99.
|
||||||
|
|
||||||
|
In C99, a struct type is never variably modified because a VLA may
|
||||||
|
not appear as a structure member. However, in GNU C code like:
|
||||||
|
|
||||||
|
struct S { int i[f()]; };
|
||||||
|
|
||||||
|
is valid. Even though GNU C++ does not allow that, this function
|
||||||
|
may sometimes be used in the C front end, so it treats any type
|
||||||
|
with variable size in the same way that C99 treats VLAs.
|
||||||
|
|
||||||
|
In particular, a variably modified type is one that involves a type
|
||||||
|
with variable size. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
variably_modified_type_p (tree type)
|
||||||
|
{
|
||||||
|
/* If TYPE itself has variable size, it is variably modified.
|
||||||
|
|
||||||
|
We do not yet have a representation of the C99 '[*]' syntax.
|
||||||
|
When a representation is chosen, this function should be modified
|
||||||
|
to test for that case as well. */
|
||||||
|
if (TYPE_SIZE (type)
|
||||||
|
&& TYPE_SIZE (type) != error_mark_node
|
||||||
|
&& TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* If TYPE is a pointer or reference, it is variably modified if and
|
||||||
|
only if the type pointed to is variably modified. */
|
||||||
|
if (TYPE_PTR_P (type)
|
||||||
|
|| TREE_CODE (type) == REFERENCE_TYPE)
|
||||||
|
return variably_modified_type_p (TREE_TYPE (type));
|
||||||
|
|
||||||
|
/* If TYPE is an array, it is variably modified if the array
|
||||||
|
elements are. (Note that the VLA case has alredy been checked
|
||||||
|
above). */
|
||||||
|
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||||
|
return variably_modified_type_p (TREE_TYPE (type));
|
||||||
|
|
||||||
|
/* If TYPE is a pointer-to-member, it is variably modified if either
|
||||||
|
the class or the member are variably modified. */
|
||||||
|
if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
|
||||||
|
return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
|
||||||
|
|| variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type)));
|
||||||
|
|
||||||
|
/* If TYPE Is a function type, it is variably modified if any of the
|
||||||
|
parameters or the return type are variably modified. */
|
||||||
|
if (TREE_CODE (type) == FUNCTION_TYPE
|
||||||
|
|| TREE_CODE (type) == METHOD_TYPE)
|
||||||
|
{
|
||||||
|
tree parm;
|
||||||
|
|
||||||
|
if (variably_modified_type_p (TREE_TYPE (type)))
|
||||||
|
return true;
|
||||||
|
for (parm = TYPE_ARG_TYPES (type);
|
||||||
|
parm && parm != void_list_node;
|
||||||
|
parm = TREE_CHAIN (parm))
|
||||||
|
if (variably_modified_type_p (TREE_VALUE (parm)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All other types are not variably modified. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns 1 iff zero initialization of type T means actually storing
|
/* Returns 1 iff zero initialization of type T means actually storing
|
||||||
zeros in it. */
|
zeros in it. */
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
2002-10-11 Mark Mitchell <mark@codesourcery.com>
|
2002-10-11 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
PR c++/5661
|
||||||
|
* g++.dg/ext/vlm1.C: New test.
|
||||||
|
* g++.dg/ext/vlm2.C: Likewise.
|
||||||
|
|
||||||
* g++.dg/init/array1.C: Remove invalid braces.
|
* g++.dg/init/array1.C: Remove invalid braces.
|
||||||
* g++.dg/init/brace1.C: New test.
|
* g++.dg/init/brace1.C: New test.
|
||||||
* g++.dg/init/copy2.C: Likewise.
|
* g++.dg/init/copy2.C: Likewise.
|
||||||
|
13
gcc/testsuite/g++.dg/ext/vlm1.C
Normal file
13
gcc/testsuite/g++.dg/ext/vlm1.C
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// { dg-options "" }
|
||||||
|
|
||||||
|
template <class T> struct A {};
|
||||||
|
|
||||||
|
struct B {
|
||||||
|
static const int s;
|
||||||
|
A<int[s]> a; // { dg-error "variably modified|no type" }
|
||||||
|
};
|
||||||
|
|
||||||
|
const int B::s=16;
|
||||||
|
|
||||||
|
B b;
|
||||||
|
|
13
gcc/testsuite/g++.dg/ext/vlm2.C
Normal file
13
gcc/testsuite/g++.dg/ext/vlm2.C
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// { dg-options "" }
|
||||||
|
|
||||||
|
int n;
|
||||||
|
|
||||||
|
struct Y
|
||||||
|
{
|
||||||
|
void f () {
|
||||||
|
typedef int X[n];
|
||||||
|
struct Z {
|
||||||
|
X x; // { dg-error "variably modified" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user