Commit ae58fa02 by Mark Mitchell Committed by Mark Mitchell

typeck.c (require_complete_type): Use complete_type_or_else.

	* typeck.c (require_complete_type): Use complete_type_or_else.
	(complete_type_or_else): Always return NULL_TREE on failure, as
	documented.
	* pt.c (tsubst_aggr_type): Prototype.
	(tsubst_decl): New function, split out from tsubst.  Set
	input_filename and lineno as appropriate.
	(pop_tinst_level): Restore the file and line number saved in
	push_tinst_level.
	(instantiate_class_template): Set input_filename and lineno as
	appropriate.
	(tsubst): Move _DECL processing to tsubst_decl.  Make sure the
	context for a TYPENAME_TYPE is complete.
	* decl2.c (grokbitfield): Issue errors on bitfields declared with
	function type.
	(do_dtors): As in do_ctors, pretend to be a member of the same
	class as a static data member while generating a call to its
	destructor.

From-SVN: r21627
parent 52363387
1998-08-07 Mark Mitchell <mark@markmitchell.com> 1998-08-07 Mark Mitchell <mark@markmitchell.com>
* cvt.c (cp_convert_to_pointer): Handle a NULL pointer * typeck.c (require_complete_type): Use complete_type_or_else.
(complete_type_or_else): Always return NULL_TREE on failure, as
documented.
* pt.c (tsubst_aggr_type): Prototype.
(tsubst_decl): New function, split out from tsubst. Set
input_filename and lineno as appropriate.
(pop_tinst_level): Restore the file and line number saved in
push_tinst_level.
(instantiate_class_template): Set input_filename and lineno as
appropriate.
(tsubst): Move _DECL processing to tsubst_decl. Make sure the
context for a TYPENAME_TYPE is complete.
* decl2.c (grokbitfield): Issue errors on bitfields declared with
function type.
(do_dtors): As in do_ctors, pretend to be a member of the same
class as a static data member while generating a call to its
destructor.
* cvt.c (cp_convert_to_pointer): Handle NULL pointer
conversions, even in complex virtual base class hierarchies. conversions, even in complex virtual base class hierarchies.
1998-08-06 Mark Mitchell <mark@markmitchell.com> 1998-08-06 Mark Mitchell <mark@markmitchell.com>
......
...@@ -1845,6 +1845,17 @@ grokbitfield (declarator, declspecs, width) ...@@ -1845,6 +1845,17 @@ grokbitfield (declarator, declspecs, width)
return NULL_TREE; return NULL_TREE;
} }
/* Usually, finish_struct_1 catches bitifields with invalid types.
But, in the case of bitfields with function type, we confuse
ourselves into thinking they are member functions, so we must
check here. */
if (TREE_CODE (value) == FUNCTION_DECL)
{
cp_error ("cannot declare bitfield `%D' with funcion type",
DECL_NAME (value));
return NULL_TREE;
}
if (IS_SIGNATURE (current_class_type)) if (IS_SIGNATURE (current_class_type))
{ {
error ("field declaration not allowed in signature"); error ("field declaration not allowed in signature");
...@@ -3001,6 +3012,25 @@ do_dtors () ...@@ -3001,6 +3012,25 @@ do_dtors ()
if (! current_function_decl) if (! current_function_decl)
start_objects ('D'); start_objects ('D');
/* Because of:
[class.access.spec]
Access control for implicit calls to the constructors,
the conversion functions, or the destructor called to
create and destroy a static data member is per- formed as
if these calls appeared in the scope of the member's
class.
we must convince enforce_access to let us access the
DECL. */
if (member_p (decl))
{
DECL_CLASS_CONTEXT (current_function_decl)
= DECL_CONTEXT (decl);
DECL_STATIC_FUNCTION_P (current_function_decl) = 1;
}
temp = build_cleanup (decl); temp = build_cleanup (decl);
if (protect) if (protect)
...@@ -3015,6 +3045,11 @@ do_dtors () ...@@ -3015,6 +3045,11 @@ do_dtors ()
if (protect) if (protect)
expand_end_cond (); expand_end_cond ();
/* Now that we're done with DECL we don't need to pretend to
be a member of its class any longer. */
DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE;
DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
} }
} }
......
...@@ -80,7 +80,9 @@ target_type (type) ...@@ -80,7 +80,9 @@ target_type (type)
} }
/* Do `exp = require_complete_type (exp);' to make sure exp /* Do `exp = require_complete_type (exp);' to make sure exp
does not have an incomplete type. (That includes void types.) */ does not have an incomplete type. (That includes void types.)
Returns the error_mark_node if the VALUE does not have
complete type when this function returns. */
tree tree
require_complete_type (value) require_complete_type (value)
...@@ -120,13 +122,10 @@ require_complete_type (value) ...@@ -120,13 +122,10 @@ require_complete_type (value)
return require_complete_type (value); return require_complete_type (value);
} }
if (TYPE_SIZE (complete_type (type))) if (complete_type_or_else (type))
return value; return value;
else else
{
incomplete_type_error (value, type);
return error_mark_node; return error_mark_node;
}
} }
/* Try to complete TYPE, if it is incomplete. For example, if TYPE is /* Try to complete TYPE, if it is incomplete. For example, if TYPE is
...@@ -170,7 +169,10 @@ complete_type_or_else (type) ...@@ -170,7 +169,10 @@ complete_type_or_else (type)
tree type; tree type;
{ {
type = complete_type (type); type = complete_type (type);
if (type != error_mark_node && !TYPE_SIZE (type)) if (type == error_mark_node)
/* We already issued an error. */
return NULL_TREE;
else if (!TYPE_SIZE (type))
{ {
incomplete_type_error (NULL_TREE, type); incomplete_type_error (NULL_TREE, type);
return NULL_TREE; return NULL_TREE;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
typedef void (func_type) (); typedef void (func_type) ();
struct s { struct s {
func_type f:32; // ERROR - XFAIL *-*-* func_type f:32; // ERROR - bitified with function type
}; };
int main () { return 0; } int main () { return 0; }
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
const int ArraySize = 12; const int ArraySize = 12;
template <class Type> template <class Type>
class Array { class Array { // ERROR - .struct Array_RC redecl.*
friend class Array_RC; friend class Array_RC;
public: public:
Array(const Type *ar, int sz) { init(ar,sz); } Array(const Type *ar, int sz) { init(ar,sz); }
...@@ -97,7 +97,7 @@ try_array( Array_RC<Type> &rc ) ...@@ -97,7 +97,7 @@ try_array( Array_RC<Type> &rc )
main() main()
{ {
static int ia[10] = { 12, 7, 14, 9, 128, 17, 6, 3, 27, 5 }; static int ia[10] = { 12, 7, 14, 9, 128, 17, 6, 3, 27, 5 };
Array_RC<int> iA(ia, 10);// ERROR - .struct Array_RC redecl.* Array_RC<int> iA(ia, 10);// ERROR - instantiated from here
cout << "template Array_RC class" << endl; cout << "template Array_RC class" << endl;
try_array(iA); try_array(iA);
......
// Build don't link:
class K {
public:
friend class C;
private:
static K qwe;
K();
~K();
};
K K::qwe;
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
template <class T = int> // ERROR - original definition template <class T = int> // ERROR - original definition
struct S struct S
{ { // ERROR - redefinition of default arg
template <class U = int> template <class U = int>
friend class S; friend class S;
}; };
template struct S<int>; // ERROR - redefinition of default arg template struct S<int>; // ERROR - instantiated from here
// Build don't link: // Build don't link:
template <class A> class B { template <class A> class B { // ERROR - candidates
A a; A a;
public: public:
B(A&aa); // ERROR - B(A&aa); // ERROR - near match
~B(); ~B();
}; };
static B<int> b_int (3); // ERROR - static B<int> b_int (3); // ERROR - no matching function
// Build don't link:
template < class T > class A
{
public:
typedef typename T::myT anotherT; // ERROR - undefined type
anotherT t; // ERROR - undefined type
A(anotherT _t) { // ERROR - undefined type
t=_t;
}
anotherT getT() {
return t;
}
};
class B : public A< B >
{
public:
typedef int myT;
};
int main() {
B b;
}
...@@ -17,7 +17,7 @@ inline istream& operator>>(istream& is, Empty& ) { return is;} ...@@ -17,7 +17,7 @@ inline istream& operator>>(istream& is, Empty& ) { return is;}
template<class VertexType, class EdgeType> template<class VertexType, class EdgeType>
class Graph class Graph
{ { // ERROR - candidates
public: public:
// public type interface // public type interface
typedef map<int, EdgeType > Successor; typedef map<int, EdgeType > Successor;
......
template<class T> template<class T>
struct A { struct A {
typedef T* iterator; typedef T* iterator; // ERROR - pointer to reference
public: public:
A(){} A(){}
}; };
void f() void f()
{ {
A<int&> a; // ERROR - pointer to reference A<int&> a; // ERROR - instantiated from here
} }
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