mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-24 00:49:30 +08:00
In gcc/objc/: 2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/objc/: 2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com> * objc-act.c (objc_eh_runtime_type): Avoid ICE if error_mark_node is passed as argument. (objc_begin_catch_clause): Added code to deal with an error_mark_node or NULL_TREE argument. Improved checks for invalid arguments. Added code to traverse typedefs. In gcc/testsuite/: 2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com> * objc.dg/exceptions-1.m: New. * objc.dg/exceptions-2.m: New. * objc.dg/exceptions-3.m: New. * objc.dg/exceptions-4.m: New. * objc.dg/exceptions-5.m: New. * obj-c++.dg/exceptions-1.mm: New. * obj-c++.dg/exceptions-2.mm: New. * obj-c++.dg/exceptions-3.mm: New. * obj-c++.dg/exceptions-4.mm: New. * obj-c++.dg/exceptions-5.mm: New. In gcc/cp/: 2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com> * parser.c (cp_parser_objc_try_catch_finally_statement): Parse @catch(...) and pass NULL_TREE to objc_begin_catch_clause() in that case. Improved error recovery. Reorganized code to be almost identical to c_parser_objc_try_catch_finally_statement. In gcc/: 2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com> * c-parser.c (c_parser_objc_try_catch_statement): Renamed to c_parser_objc_try_catch_finally_statement for consistency with the C++ parser. Parse @catch(...) and pass NULL_TREE to objc_begin_catch_clause() in that case. Improved error recovery. Reorganized code to be almost identical to cp_parser_objc_try_catch_finally_statement. From-SVN: r167233
This commit is contained in:
parent
45f9cadb2a
commit
437c232224
@ -1,3 +1,12 @@
|
||||
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* c-parser.c (c_parser_objc_try_catch_statement): Renamed to
|
||||
c_parser_objc_try_catch_finally_statement for consistency with the
|
||||
C++ parser. Parse @catch(...) and pass NULL_TREE to
|
||||
objc_begin_catch_clause() in that case. Improved error recovery.
|
||||
Reorganized code to be almost identical to
|
||||
cp_parser_objc_try_catch_finally_statement.
|
||||
|
||||
2010-11-29 Joern Rennecke <amylaar@spamcop.net>
|
||||
|
||||
PR tree-optimization/46621
|
||||
|
@ -1155,7 +1155,7 @@ static void c_parser_objc_methodproto (c_parser *);
|
||||
static tree c_parser_objc_method_decl (c_parser *, bool, tree *);
|
||||
static tree c_parser_objc_type_name (c_parser *);
|
||||
static tree c_parser_objc_protocol_refs (c_parser *);
|
||||
static void c_parser_objc_try_catch_statement (c_parser *);
|
||||
static void c_parser_objc_try_catch_finally_statement (c_parser *);
|
||||
static void c_parser_objc_synchronized_statement (c_parser *);
|
||||
static tree c_parser_objc_selector (c_parser *);
|
||||
static tree c_parser_objc_selector_arg (c_parser *);
|
||||
@ -4371,7 +4371,7 @@ c_parser_statement_after_labels (c_parser *parser)
|
||||
break;
|
||||
case RID_AT_TRY:
|
||||
gcc_assert (c_dialect_objc ());
|
||||
c_parser_objc_try_catch_statement (parser);
|
||||
c_parser_objc_try_catch_finally_statement (parser);
|
||||
break;
|
||||
case RID_AT_SYNCHRONIZED:
|
||||
gcc_assert (c_dialect_objc ());
|
||||
@ -7468,53 +7468,97 @@ c_parser_objc_protocol_refs (c_parser *parser)
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Parse an objc-try-catch-statement.
|
||||
/* Parse an objc-try-catch-finally-statement.
|
||||
|
||||
objc-try-catch-statement:
|
||||
objc-try-catch-finally-statement:
|
||||
@try compound-statement objc-catch-list[opt]
|
||||
@try compound-statement objc-catch-list[opt] @finally compound-statement
|
||||
|
||||
objc-catch-list:
|
||||
@catch ( parameter-declaration ) compound-statement
|
||||
objc-catch-list @catch ( parameter-declaration ) compound-statement
|
||||
*/
|
||||
@catch ( objc-catch-parameter-declaration ) compound-statement
|
||||
objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
|
||||
|
||||
objc-catch-parameter-declaration:
|
||||
parameter-declaration
|
||||
'...'
|
||||
|
||||
where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
|
||||
|
||||
PS: This function is identical to cp_parser_objc_try_catch_finally_statement
|
||||
for C++. Keep them in sync. */
|
||||
|
||||
static void
|
||||
c_parser_objc_try_catch_statement (c_parser *parser)
|
||||
c_parser_objc_try_catch_finally_statement (c_parser *parser)
|
||||
{
|
||||
location_t loc;
|
||||
location_t location;
|
||||
tree stmt;
|
||||
|
||||
gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
|
||||
c_parser_consume_token (parser);
|
||||
loc = c_parser_peek_token (parser)->location;
|
||||
location = c_parser_peek_token (parser)->location;
|
||||
stmt = c_parser_compound_statement (parser);
|
||||
objc_begin_try_stmt (loc, stmt);
|
||||
objc_begin_try_stmt (location, stmt);
|
||||
|
||||
while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
|
||||
{
|
||||
struct c_parm *parm;
|
||||
tree parameter_declaration = error_mark_node;
|
||||
bool seen_open_paren = false;
|
||||
|
||||
c_parser_consume_token (parser);
|
||||
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
|
||||
break;
|
||||
parm = c_parser_parameter_declaration (parser, NULL_TREE);
|
||||
if (parm == NULL)
|
||||
seen_open_paren = true;
|
||||
if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
|
||||
{
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
|
||||
break;
|
||||
/* We have "@catch (...)" (where the '...' are literally
|
||||
what is in the code). Skip the '...'.
|
||||
parameter_declaration is set to NULL_TREE, and
|
||||
objc_being_catch_clauses() knows that that means
|
||||
'...'. */
|
||||
c_parser_consume_token (parser);
|
||||
parameter_declaration = NULL_TREE;
|
||||
}
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
|
||||
objc_begin_catch_clause (grokparm (parm));
|
||||
else
|
||||
{
|
||||
/* We have "@catch (NSException *exception)" or something
|
||||
like that. Parse the parameter declaration. */
|
||||
parm = c_parser_parameter_declaration (parser, NULL_TREE);
|
||||
if (parm == NULL)
|
||||
parameter_declaration = error_mark_node;
|
||||
else
|
||||
parameter_declaration = grokparm (parm);
|
||||
}
|
||||
if (seen_open_paren)
|
||||
c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
|
||||
else
|
||||
{
|
||||
/* If there was no open parenthesis, we are recovering from
|
||||
an error, and we are trying to figure out what mistake
|
||||
the user has made. */
|
||||
|
||||
/* If there is an immediate closing parenthesis, the user
|
||||
probably forgot the opening one (ie, they typed "@catch
|
||||
NSException *e)". Parse the closing parenthesis and keep
|
||||
going. */
|
||||
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
|
||||
c_parser_consume_token (parser);
|
||||
|
||||
/* If these is no immediate closing parenthesis, the user
|
||||
probably doesn't know that parenthesis are required at
|
||||
all (ie, they typed "@catch NSException *e"). So, just
|
||||
forget about the closing parenthesis and keep going. */
|
||||
}
|
||||
objc_begin_catch_clause (parameter_declaration);
|
||||
if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
|
||||
c_parser_compound_statement_nostart (parser);
|
||||
objc_finish_catch_clause ();
|
||||
}
|
||||
if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
|
||||
{
|
||||
location_t finloc;
|
||||
tree finstmt;
|
||||
c_parser_consume_token (parser);
|
||||
finloc = c_parser_peek_token (parser)->location;
|
||||
finstmt = c_parser_compound_statement (parser);
|
||||
objc_build_finally_clause (finloc, finstmt);
|
||||
location = c_parser_peek_token (parser)->location;
|
||||
stmt = c_parser_compound_statement (parser);
|
||||
objc_build_finally_clause (location, stmt);
|
||||
}
|
||||
objc_finish_try_stmt ();
|
||||
}
|
||||
|
@ -1,3 +1,10 @@
|
||||
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* parser.c (cp_parser_objc_try_catch_finally_statement): Parse
|
||||
@catch(...) and pass NULL_TREE to objc_begin_catch_clause() in
|
||||
that case. Improved error recovery. Reorganized code to be
|
||||
almost identical to c_parser_objc_try_catch_finally_statement.
|
||||
|
||||
2010-11-27 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
PR objc++/46222
|
||||
|
@ -22598,15 +22598,25 @@ cp_parser_objc_declaration (cp_parser* parser, tree attributes)
|
||||
objc-catch-clause objc-catch-clause-seq [opt]
|
||||
|
||||
objc-catch-clause:
|
||||
@catch ( exception-declaration ) compound-statement
|
||||
@catch ( objc-exception-declaration ) compound-statement
|
||||
|
||||
objc-finally-clause
|
||||
objc-finally-clause:
|
||||
@finally compound-statement
|
||||
|
||||
Returns NULL_TREE. */
|
||||
objc-exception-declaration:
|
||||
parameter-declaration
|
||||
'...'
|
||||
|
||||
where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
|
||||
|
||||
Returns NULL_TREE.
|
||||
|
||||
PS: This function is identical to c_parser_objc_try_catch_finally_statement
|
||||
for C. Keep them in sync. */
|
||||
|
||||
static tree
|
||||
cp_parser_objc_try_catch_finally_statement (cp_parser *parser) {
|
||||
cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
|
||||
{
|
||||
location_t location;
|
||||
tree stmt;
|
||||
|
||||
@ -22620,22 +22630,60 @@ cp_parser_objc_try_catch_finally_statement (cp_parser *parser) {
|
||||
|
||||
while (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_CATCH))
|
||||
{
|
||||
cp_parameter_declarator *parmdecl;
|
||||
tree parm;
|
||||
cp_parameter_declarator *parm;
|
||||
tree parameter_declaration = error_mark_node;
|
||||
bool seen_open_paren = false;
|
||||
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
|
||||
parmdecl = cp_parser_parameter_declaration (parser, false, NULL);
|
||||
parm = grokdeclarator (parmdecl->declarator,
|
||||
&parmdecl->decl_specifiers,
|
||||
PARM, /*initialized=*/0,
|
||||
/*attrlist=*/NULL);
|
||||
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
|
||||
objc_begin_catch_clause (parm);
|
||||
if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
|
||||
seen_open_paren = true;
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
|
||||
{
|
||||
/* We have "@catch (...)" (where the '...' are literally
|
||||
what is in the code). Skip the '...'.
|
||||
parameter_declaration is set to NULL_TREE, and
|
||||
objc_being_catch_clauses() knows that that means
|
||||
'...'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
parameter_declaration = NULL_TREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We have "@catch (NSException *exception)" or something
|
||||
like that. Parse the parameter declaration. */
|
||||
parm = cp_parser_parameter_declaration (parser, false, NULL);
|
||||
if (parm == NULL)
|
||||
parameter_declaration = error_mark_node;
|
||||
else
|
||||
parameter_declaration = grokdeclarator (parm->declarator,
|
||||
&parm->decl_specifiers,
|
||||
PARM, /*initialized=*/0,
|
||||
/*attrlist=*/NULL);
|
||||
}
|
||||
if (seen_open_paren)
|
||||
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
|
||||
else
|
||||
{
|
||||
/* If there was no open parenthesis, we are recovering from
|
||||
an error, and we are trying to figure out what mistake
|
||||
the user has made. */
|
||||
|
||||
/* If there is an immediate closing parenthesis, the user
|
||||
probably forgot the opening one (ie, they typed "@catch
|
||||
NSException *e)". Parse the closing parenthesis and keep
|
||||
going. */
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
/* If these is no immediate closing parenthesis, the user
|
||||
probably doesn't know that parenthesis are required at
|
||||
all (ie, they typed "@catch NSException *e"). So, just
|
||||
forget about the closing parenthesis and keep going. */
|
||||
}
|
||||
objc_begin_catch_clause (parameter_declaration);
|
||||
cp_parser_compound_statement (parser, NULL, false);
|
||||
objc_finish_catch_clause ();
|
||||
}
|
||||
|
||||
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_FINALLY))
|
||||
{
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
@ -1,3 +1,11 @@
|
||||
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* objc-act.c (objc_eh_runtime_type): Avoid ICE if error_mark_node
|
||||
is passed as argument.
|
||||
(objc_begin_catch_clause): Added code to deal with an
|
||||
error_mark_node or NULL_TREE argument. Improved checks for
|
||||
invalid arguments. Added code to traverse typedefs.
|
||||
|
||||
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* objc-act.c (objc_demangle): Return immediately if the string is
|
||||
|
@ -5024,7 +5024,14 @@ static GTY(()) tree objc_eh_personality_decl;
|
||||
tree
|
||||
objc_eh_runtime_type (tree type)
|
||||
{
|
||||
return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
|
||||
/* Use 'ErrorMarkNode' as class name when error_mark_node is found
|
||||
to prevent an ICE. Note that we know that the compiler will
|
||||
terminate with an error and this 'ErrorMarkNode' class name will
|
||||
never be actually used. */
|
||||
if (type == error_mark_node)
|
||||
return add_objc_string (get_identifier ("ErrorMarkNode"), class_names);
|
||||
else
|
||||
return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
|
||||
}
|
||||
|
||||
tree
|
||||
@ -5355,7 +5362,9 @@ objc_begin_try_stmt (location_t try_locus, tree body)
|
||||
|
||||
/* Called just after parsing "@catch (parm)". Open a binding level,
|
||||
enter DECL into the binding level, and initialize it. Leave the
|
||||
binding level open while the body of the compound statement is parsed. */
|
||||
binding level open while the body of the compound statement is
|
||||
parsed. If DECL is NULL_TREE, then we are compiling "@catch(...)"
|
||||
which we compile as "@catch(id tmp_variable)". */
|
||||
|
||||
void
|
||||
objc_begin_catch_clause (tree decl)
|
||||
@ -5365,46 +5374,99 @@ objc_begin_catch_clause (tree decl)
|
||||
/* Begin a new scope that the entire catch clause will live in. */
|
||||
compound = c_begin_compound_stmt (true);
|
||||
|
||||
/* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
|
||||
decl = build_decl (input_location,
|
||||
VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
|
||||
lang_hooks.decls.pushdecl (decl);
|
||||
/* Create the appropriate declaration for the argument. */
|
||||
if (decl == error_mark_node)
|
||||
type = error_mark_node;
|
||||
else
|
||||
{
|
||||
if (decl == NULL_TREE)
|
||||
{
|
||||
/* If @catch(...) was specified, create a temporary variable of
|
||||
type 'id' and use it. */
|
||||
decl = objc_create_temporary_var (objc_object_type, "__objc_generic_catch_var");
|
||||
DECL_SOURCE_LOCATION (decl) = input_location;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
|
||||
decl = build_decl (input_location,
|
||||
VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
|
||||
}
|
||||
lang_hooks.decls.pushdecl (decl);
|
||||
|
||||
/* Since a decl is required here by syntax, don't warn if its unused. */
|
||||
/* ??? As opposed to __attribute__((unused))? Anyway, this appears to
|
||||
be what the previous objc implementation did. */
|
||||
TREE_USED (decl) = 1;
|
||||
DECL_READ_P (decl) = 1;
|
||||
/* Mark the declaration as used so you never any warnings whether
|
||||
you use the exception argument or not. TODO: Implement a
|
||||
-Wunused-exception-parameter flag, which would cause warnings
|
||||
if exception parameter is not used. */
|
||||
TREE_USED (decl) = 1;
|
||||
DECL_READ_P (decl) = 1;
|
||||
|
||||
/* Verify that the type of the catch is valid. It must be a pointer
|
||||
to an Objective-C class, or "id" (which is catch-all). */
|
||||
type = TREE_TYPE (decl);
|
||||
type = TREE_TYPE (decl);
|
||||
}
|
||||
|
||||
if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
|
||||
type = NULL;
|
||||
else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
|
||||
/* Verify that the type of the catch is valid. It must be a pointer
|
||||
to an Objective-C class, or "id" (which is catch-all). */
|
||||
if (type == error_mark_node)
|
||||
{
|
||||
;/* Just keep going. */
|
||||
}
|
||||
else if (!objc_type_valid_for_messaging (type, false))
|
||||
{
|
||||
error ("@catch parameter is not a known Objective-C class type");
|
||||
type = error_mark_node;
|
||||
}
|
||||
else if (cur_try_context->catch_list)
|
||||
else if (TYPE_HAS_OBJC_INFO (TREE_TYPE (type))
|
||||
&& TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (type)))
|
||||
{
|
||||
/* Examine previous @catch clauses and see if we've already
|
||||
caught the type in question. */
|
||||
tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
|
||||
for (; !tsi_end_p (i); tsi_next (&i))
|
||||
error ("@catch parameter can not be protocol-qualified");
|
||||
type = error_mark_node;
|
||||
}
|
||||
else if (objc_is_object_id (TREE_TYPE (type)))
|
||||
type = NULL;
|
||||
else
|
||||
{
|
||||
/* If 'type' was built using typedefs, we need to get rid of
|
||||
them and get a simple pointer to the class. */
|
||||
bool is_typedef = false;
|
||||
tree x = TYPE_MAIN_VARIANT (type);
|
||||
|
||||
/* Skip from the pointer to the pointee. */
|
||||
if (TREE_CODE (x) == POINTER_TYPE)
|
||||
x = TREE_TYPE (x);
|
||||
|
||||
/* Traverse typedef aliases */
|
||||
while (TREE_CODE (x) == RECORD_TYPE && OBJC_TYPE_NAME (x)
|
||||
&& TREE_CODE (OBJC_TYPE_NAME (x)) == TYPE_DECL
|
||||
&& DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (x)))
|
||||
{
|
||||
tree stmt = tsi_stmt (i);
|
||||
t = CATCH_TYPES (stmt);
|
||||
if (t == error_mark_node)
|
||||
continue;
|
||||
if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
|
||||
is_typedef = true;
|
||||
x = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (x));
|
||||
}
|
||||
|
||||
/* If it was a typedef, build a pointer to the final, original
|
||||
class. */
|
||||
if (is_typedef)
|
||||
type = build_pointer_type (x);
|
||||
|
||||
if (cur_try_context->catch_list)
|
||||
{
|
||||
/* Examine previous @catch clauses and see if we've already
|
||||
caught the type in question. */
|
||||
tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
|
||||
for (; !tsi_end_p (i); tsi_next (&i))
|
||||
{
|
||||
warning (0, "exception of type %<%T%> will be caught",
|
||||
TREE_TYPE (type));
|
||||
warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
|
||||
TREE_TYPE (t ? t : objc_object_type));
|
||||
break;
|
||||
tree stmt = tsi_stmt (i);
|
||||
t = CATCH_TYPES (stmt);
|
||||
if (t == error_mark_node)
|
||||
continue;
|
||||
if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
|
||||
{
|
||||
warning (0, "exception of type %<%T%> will be caught",
|
||||
TREE_TYPE (type));
|
||||
warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
|
||||
TREE_TYPE (t ? t : objc_object_type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,16 @@
|
||||
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* objc.dg/exceptions-1.m: New.
|
||||
* objc.dg/exceptions-2.m: New.
|
||||
* objc.dg/exceptions-3.m: New.
|
||||
* objc.dg/exceptions-4.m: New.
|
||||
* objc.dg/exceptions-5.m: New.
|
||||
* obj-c++.dg/exceptions-1.mm: New.
|
||||
* obj-c++.dg/exceptions-2.mm: New.
|
||||
* obj-c++.dg/exceptions-3.mm: New.
|
||||
* obj-c++.dg/exceptions-4.mm: New.
|
||||
* obj-c++.dg/exceptions-5.mm: New.
|
||||
|
||||
2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* obj-c++.dg/property/at-property-1.mm: Fixed testcase.
|
||||
|
42
gcc/testsuite/obj-c++.dg/exceptions-1.mm
Normal file
42
gcc/testsuite/obj-c++.dg/exceptions-1.mm
Normal file
@ -0,0 +1,42 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* This test checks the syntax @catch (...) which catches any
|
||||
exceptions. At the moment, @catch (...) is identical to @catch (id
|
||||
exception). */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
@try
|
||||
{
|
||||
@throw object;
|
||||
}
|
||||
@catch (MyObject *o)
|
||||
{
|
||||
i += 1;
|
||||
}
|
||||
@catch (...)
|
||||
{
|
||||
i += 2;
|
||||
}
|
||||
@finally
|
||||
{
|
||||
i += 4;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
54
gcc/testsuite/obj-c++.dg/exceptions-2.mm
Normal file
54
gcc/testsuite/obj-c++.dg/exceptions-2.mm
Normal file
@ -0,0 +1,54 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
|
||||
/* FIXME: This does not test running the code, because Objective-C exceptions at the moment
|
||||
do not execute correctly in Objective-C++. See PR objc++/23616. Once that is fixed,
|
||||
this test should be changed to use 'dg-run' instead of just 'dg-compile'. */
|
||||
/* { dg-compile } */
|
||||
|
||||
/* This test checks the syntax @catch (...) which catches any
|
||||
exceptions. Check that code using it runs correctly. */
|
||||
|
||||
#include "../objc-obj-c++-shared/Object1.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
@interface MyObject : Object
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
@try
|
||||
{
|
||||
@throw object;
|
||||
}
|
||||
@catch (MyObject *o)
|
||||
{
|
||||
i += 1;
|
||||
}
|
||||
@catch (...)
|
||||
{
|
||||
i += 2;
|
||||
}
|
||||
@finally
|
||||
{
|
||||
i += 4;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
if (test ([MyObject new]) != 5)
|
||||
abort ();
|
||||
|
||||
if (test ([Object new]) != 6)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
114
gcc/testsuite/obj-c++.dg/exceptions-3.mm
Normal file
114
gcc/testsuite/obj-c++.dg/exceptions-3.mm
Normal file
@ -0,0 +1,114 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test that the compiler is checking the argument of @catch(), and
|
||||
produce errors when invalid types are used. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
@protocol MyProtocol;
|
||||
|
||||
typedef MyObject MyObjectTypedef;
|
||||
typedef MyObject *MyObjectPtrTypedef;
|
||||
typedef int intTypedef;
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int dummy = 0;
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (int x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (intTypedef x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (int *x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (id x) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (id <MyProtocol> x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject *x) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{ /* { dg-error "no matching function" "" { target *-*-* } 72 } */
|
||||
dummy++; /* { dg-warning "MyObject" "" { target *-*-* } 13 } */
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (static MyObject *x) /* { dg-error "storage class" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectTypedef *x) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectTypedef <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectPtrTypedef x) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (Class x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (...) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
return dummy;
|
||||
}
|
64
gcc/testsuite/obj-c++.dg/exceptions-4.mm
Normal file
64
gcc/testsuite/obj-c++.dg/exceptions-4.mm
Normal file
@ -0,0 +1,64 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test warnings when parsing syntax errors in @catch(). */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
@interface MyObject2
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject2
|
||||
@end
|
||||
|
||||
@protocol MyProtocol;
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int dummy = 0;
|
||||
|
||||
@try { @throw object; }
|
||||
@catch
|
||||
{ /* { dg-error "expected" } */
|
||||
dummy++; /* { dg-error "@catch parameter is not a known Objective-C class type" "" { target *-*-* } 35 } */
|
||||
}
|
||||
@catch () /* { dg-error "expected identifier before" } */
|
||||
{ /* { dg-error "@catch parameter is not a known Objective-C class type" "" { target *-*-* } 38 } */
|
||||
dummy++;
|
||||
}
|
||||
@catch (i) /* { dg-error ".i. has not been declared" } */
|
||||
{ /* { dg-error "@catch parameter is not a known Objective-C class type" "" { target *-*-* } 42 } */
|
||||
dummy++;
|
||||
}
|
||||
@catch (id <MyProtocol x) /* { dg-error "expected ... before .x." } */
|
||||
{ /* { dg-error "@catch parameter can not be protocol-qualified" "" { target *-*-* } 46 } */
|
||||
dummy++;
|
||||
}
|
||||
@catch MyObject *x /* { dg-error "expected ... before .MyObject." } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
@catch MyObject2 *x) /* { dg-error "expected ... before .MyObject2." } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject *x)
|
||||
@catch (MyObject2 *y) /* { dg-error "expected ... before .catch." } */
|
||||
|
||||
return dummy; /* { dg-error "expected ... before .return." } */
|
||||
}
|
114
gcc/testsuite/obj-c++.dg/exceptions-5.mm
Normal file
114
gcc/testsuite/obj-c++.dg/exceptions-5.mm
Normal file
@ -0,0 +1,114 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test that you can use an unnamed argument with @catch. This test is the same
|
||||
as exceptions-3.mm, but with no name for @catch arguments. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
@protocol MyProtocol;
|
||||
|
||||
typedef MyObject MyObjectTypedef;
|
||||
typedef MyObject *MyObjectPtrTypedef;
|
||||
typedef int intTypedef;
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int dummy = 0;
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (int) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (intTypedef) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (int *) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (id) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (id <MyProtocol>) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject *) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{ /* { dg-error "no matching function" "" { target *-*-* } 72 } */
|
||||
dummy++; /* { dg-warning "MyObject" "" { target *-*-* } 13 } */
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (static MyObject *) /* { dg-error "storage class" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectTypedef *) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectTypedef <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectPtrTypedef) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (Class) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (...) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
return dummy;
|
||||
}
|
42
gcc/testsuite/objc.dg/exceptions-1.m
Normal file
42
gcc/testsuite/objc.dg/exceptions-1.m
Normal file
@ -0,0 +1,42 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* This test checks the syntax @catch (...) which catches any
|
||||
exceptions. At the moment, @catch (...) is identical to @catch (id
|
||||
exception). */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
@try
|
||||
{
|
||||
@throw object;
|
||||
}
|
||||
@catch (MyObject *o)
|
||||
{
|
||||
i += 1;
|
||||
}
|
||||
@catch (...)
|
||||
{
|
||||
i += 2;
|
||||
}
|
||||
@finally
|
||||
{
|
||||
i += 4;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
52
gcc/testsuite/objc.dg/exceptions-2.m
Normal file
52
gcc/testsuite/objc.dg/exceptions-2.m
Normal file
@ -0,0 +1,52 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
|
||||
/* { dg-additional-sources "../objc-obj-c++-shared/Object1.m" } */
|
||||
|
||||
/* This test checks the syntax @catch (...) which catches any
|
||||
exceptions. Check that code using it runs correctly. */
|
||||
|
||||
#include "../objc-obj-c++-shared/Object1.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
@interface MyObject : Object
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
@try
|
||||
{
|
||||
@throw object;
|
||||
}
|
||||
@catch (MyObject *o)
|
||||
{
|
||||
i += 1;
|
||||
}
|
||||
@catch (...)
|
||||
{
|
||||
i += 2;
|
||||
}
|
||||
@finally
|
||||
{
|
||||
i += 4;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
if (test ([MyObject new]) != 5)
|
||||
abort ();
|
||||
|
||||
if (test ([Object new]) != 6)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
114
gcc/testsuite/objc.dg/exceptions-3.m
Normal file
114
gcc/testsuite/objc.dg/exceptions-3.m
Normal file
@ -0,0 +1,114 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test that the compiler is checking the argument of @catch(), and
|
||||
produce errors when invalid types are used. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
@protocol MyProtocol;
|
||||
|
||||
typedef MyObject MyObjectTypedef;
|
||||
typedef MyObject *MyObjectPtrTypedef;
|
||||
typedef int intTypedef;
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int dummy = 0;
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (int x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (intTypedef x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (int *x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (id x) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (id <MyProtocol> x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject *x) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{ /* { dg-error "conversion to non-scalar type requested" "" { target *-*-* } 72 } */
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (static MyObject *x) /* { dg-error "storage class specified for" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectTypedef *x) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectTypedef <MyProtocol> *x) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectPtrTypedef x) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (Class x) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (...) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
return dummy;
|
||||
}
|
64
gcc/testsuite/objc.dg/exceptions-4.m
Normal file
64
gcc/testsuite/objc.dg/exceptions-4.m
Normal file
@ -0,0 +1,64 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test warnings when parsing syntax errors in @catch(). */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
@interface MyObject2
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject2
|
||||
@end
|
||||
|
||||
@protocol MyProtocol;
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int dummy = 0;
|
||||
|
||||
@try { @throw object; }
|
||||
@catch
|
||||
{ /* { dg-error "expected ... before ... token" } */
|
||||
dummy++;
|
||||
}
|
||||
@catch () /* { dg-error "expected declaration specifiers or ..... before ..." } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
@catch (i) /* { dg-error "expected declaration specifiers or ..... before .i." } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
@catch (id <MyProtocol x) /* { dg-error "expected ... before .x." } */
|
||||
{ /* { dg-error "@catch parameter can not be protocol-qualified" "" { target *-*-* } 46 } */
|
||||
dummy++;
|
||||
}
|
||||
@catch MyObject *x /* { dg-error "expected ... before .MyObject." } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
@catch MyObject2 *x) /* { dg-error "expected ... before .MyObject2." } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject *x)
|
||||
@catch (MyObject2 *y) /* { dg-error "expected ... before .catch." } */
|
||||
|
||||
return dummy;
|
||||
}
|
114
gcc/testsuite/objc.dg/exceptions-5.m
Normal file
114
gcc/testsuite/objc.dg/exceptions-5.m
Normal file
@ -0,0 +1,114 @@
|
||||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-options "-fobjc-exceptions" } */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test that you can use an unnamed argument with @catch. This test is the same
|
||||
as exceptions-3.m, but with no name for @catch arguments. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyObject
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyObject
|
||||
@end
|
||||
|
||||
@protocol MyProtocol;
|
||||
|
||||
typedef MyObject MyObjectTypedef;
|
||||
typedef MyObject *MyObjectPtrTypedef;
|
||||
typedef int intTypedef;
|
||||
|
||||
int test (id object)
|
||||
{
|
||||
int dummy = 0;
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (int) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (intTypedef) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (int *) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (id) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (id <MyProtocol>) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject *) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObject) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{ /* { dg-error "conversion to non-scalar type requested" "" { target *-*-* } 72 } */
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (static MyObject *) /* { dg-error "storage class specified for" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectTypedef *) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectTypedef <MyProtocol> *) /* { dg-error "@catch parameter can not be protocol-qualified" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (MyObjectPtrTypedef) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (Class) /* { dg-error "@catch parameter is not a known Objective-C class type" } */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
@try { @throw object; }
|
||||
@catch (...) /* Ok */
|
||||
{
|
||||
dummy++;
|
||||
}
|
||||
|
||||
return dummy;
|
||||
}
|
Loading…
Reference in New Issue
Block a user