Commit c6a25d3a by Ralph Loader Committed by Ralph Loader

re PR java/12374 (Segfault on "".x)


	PR java/12374:
	* parse.y (qualify_ambiguous_name): Remove lots of broken
	field access processing - there's no need to do that here,
	because we have resolve_field_access.  Remove
	RESOLVE_EXPRESSION_NAME_P as it isn't used anywhere else.
	* java-tree.h: Remove RESOLVE_EXPRESSION_NAME_P as it isn't
	used.

From-SVN: r74217
parent a0506b54
2003-12-03 Ralph Loader <rcl@ihug.co.nz>
PR java/12374:
* parse.y (qualify_ambiguous_name): Remove lots of broken
field access processing - there's no need to do that here,
because we have resolve_field_access. Remove
RESOLVE_EXPRESSION_NAME_P as it isn't used anywhere else.
* java-tree.h: Remove RESOLVE_EXPRESSION_NAME_P as it isn't
used.
2003-12-01 Jeff Sturm <jsturm@one-point.com> 2003-12-01 Jeff Sturm <jsturm@one-point.com>
Fix PR java/13237 Fix PR java/13237
......
...@@ -44,7 +44,6 @@ struct JCF; ...@@ -44,7 +44,6 @@ struct JCF;
/* Usage of TREE_LANG_FLAG_?: /* Usage of TREE_LANG_FLAG_?:
0: IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (in IDENTIFIER_NODE) 0: IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (in IDENTIFIER_NODE)
RESOLVE_EXPRESSION_NAME_P (in EXPR_WITH_FILE_LOCATION)
FOR_LOOP_P (in LOOP_EXPR) FOR_LOOP_P (in LOOP_EXPR)
SUPPRESS_UNREACHABLE_ERROR (for other _EXPR nodes) SUPPRESS_UNREACHABLE_ERROR (for other _EXPR nodes)
ANONYMOUS_CLASS_P (in RECORD_TYPE) ANONYMOUS_CLASS_P (in RECORD_TYPE)
...@@ -1550,9 +1549,6 @@ extern tree *type_map; ...@@ -1550,9 +1549,6 @@ extern tree *type_map;
feature a finalizer method. */ feature a finalizer method. */
#define HAS_FINALIZER_P(EXPR) TREE_LANG_FLAG_3 (EXPR) #define HAS_FINALIZER_P(EXPR) TREE_LANG_FLAG_3 (EXPR)
/* True if EXPR (a WFL in that case) resolves into an expression name */
#define RESOLVE_EXPRESSION_NAME_P(WFL) TREE_LANG_FLAG_0 (WFL)
/* True if EXPR (a LOOP_EXPR in that case) is part of a for statement */ /* True if EXPR (a LOOP_EXPR in that case) is part of a for statement */
#define FOR_LOOP_P(EXPR) TREE_LANG_FLAG_0 (EXPR) #define FOR_LOOP_P(EXPR) TREE_LANG_FLAG_0 (EXPR)
......
...@@ -9802,7 +9802,6 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl, ...@@ -9802,7 +9802,6 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
list = TREE_CHAIN (q); list = TREE_CHAIN (q);
while (list) while (list)
{ {
RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0; RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
list = TREE_CHAIN (list); list = TREE_CHAIN (list);
} }
...@@ -11280,211 +11279,58 @@ argument_types_convertible (tree m1, tree m2_or_arglist) ...@@ -11280,211 +11279,58 @@ argument_types_convertible (tree m1, tree m2_or_arglist)
/* Qualification routines */ /* Qualification routines */
/* Given a name x.y.z, look up x locally. If it's found, save the
decl. If it's not found, mark the name as RESOLVE_PACKAGE_NAME_P,
so that we later try and load the appropriate classes. */
static void static void
qualify_ambiguous_name (tree id) qualify_ambiguous_name (tree id)
{ {
tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE, tree name, decl;
saved_current_class;
int again, super_found = 0, this_found = 0, new_array_found = 0;
int code;
/* We first qualify the first element, then derive qualification of
others based on the first one. If the first element is qualified
by a resolution (field or type), this resolution is stored in the
QUAL_RESOLUTION of the qual element being examined. We need to
save the current_class since the use of SUPER might change the
its value. */
saved_current_class = current_class;
qual = EXPR_WFL_QUALIFICATION (id);
do {
/* Simple qualified expression feature a qual_wfl that is a /* We inspect the first item of the qualification list. As a sanity
WFL. Expression derived from a primary feature more complicated check, make sure that it is an identfier node. */
things like a CALL_EXPR. Expression from primary need to be tree qual = EXPR_WFL_QUALIFICATION (id);
worked out to extract the part on which the qualification will tree qual_wfl = QUAL_WFL (qual);
take place. */
qual_wfl = QUAL_WFL (qual);
switch (TREE_CODE (qual_wfl))
{
case CALL_EXPR:
qual_wfl = TREE_OPERAND (qual_wfl, 0);
if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION
|| (EXPR_WFL_QUALIFICATION (qual_wfl)
&& TREE_CODE (EXPR_WFL_QUALIFICATION (qual_wfl)) == TREE_LIST))
{
qual = EXPR_WFL_QUALIFICATION (qual_wfl);
qual_wfl = QUAL_WFL (qual);
}
break;
case NEW_ARRAY_EXPR:
case NEW_ANONYMOUS_ARRAY_EXPR:
qual = TREE_CHAIN (qual);
again = new_array_found = 1;
continue;
case CONVERT_EXPR:
break;
case NEW_CLASS_EXPR:
qual_wfl = TREE_OPERAND (qual_wfl, 0);
break;
case ARRAY_REF:
while (TREE_CODE (qual_wfl) == ARRAY_REF)
qual_wfl = TREE_OPERAND (qual_wfl, 0);
break;
case STRING_CST:
qual = TREE_CHAIN (qual);
qual_wfl = QUAL_WFL (qual);
break;
case CLASS_LITERAL:
qual = TREE_CHAIN (qual);
qual_wfl = QUAL_WFL (qual);
break;
default:
/* Fix for -Wall. Just break doing nothing */
break;
}
ptr_type = current_class;
again = 0;
code = TREE_CODE (qual_wfl);
/* Pos evaluation: non WFL leading expression nodes */
if (code == CONVERT_EXPR
&& TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
else if (code == INTEGER_CST) if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
name = qual_wfl; return;
else if (code == CONVERT_EXPR &&
TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
name = TREE_OPERAND (qual_wfl, 0);
else if (code == CONVERT_EXPR
&& TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == CALL_EXPR
&& (TREE_CODE (TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0))
== EXPR_WITH_FILE_LOCATION))
name = TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0);
else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
else if (code == TREE_LIST) name = EXPR_WFL_NODE (qual_wfl);
name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
else if (code == STRING_CST || code == CONDITIONAL_EXPR /* If we don't have an identifier, or we have a 'this' or 'super',
|| code == PLUS_EXPR) then field access processing is all we need : there is nothing
{ for us to do. */
qual = TREE_CHAIN (qual); if (!name || TREE_CODE (name) != IDENTIFIER_NODE ||
qual_wfl = QUAL_WFL (qual); name == this_identifier_node ||
again = 1; name == super_identifier_node)
} return;
else
{
name = EXPR_WFL_NODE (qual_wfl);
if (!name)
{
qual = EXPR_WFL_QUALIFICATION (qual_wfl);
again = 1;
}
}
/* If we have a THIS (from a primary), we set the context accordingly */
if (name == this_identifier_node)
{
/* This isn't really elegant. One more added irregularity
before I start using COMPONENT_REF (hopefully very soon.) */
if (TREE_CODE (TREE_PURPOSE (qual)) == ARRAY_REF
&& TREE_CODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
EXPR_WITH_FILE_LOCATION
&& EXPR_WFL_NODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
this_identifier_node)
{
qual = TREE_OPERAND (TREE_PURPOSE (qual), 0);
qual = EXPR_WFL_QUALIFICATION (qual);
}
qual = TREE_CHAIN (qual);
qual_wfl = QUAL_WFL (qual);
if (TREE_CODE (qual_wfl) == CALL_EXPR)
again = 1;
else if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION)
name = EXPR_WFL_NODE (qual_wfl);
else if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
name = TREE_OPERAND (qual_wfl, 0);
this_found = 1;
}
/* If we have a SUPER, we set the context accordingly */
if (name == super_identifier_node)
{
current_class = CLASSTYPE_SUPER (ptr_type);
/* Check that there is such a thing as a super class. If not,
return. The error will be caught later on, during the
resolution */
if (!current_class)
{
current_class = saved_current_class;
return;
}
qual = TREE_CHAIN (qual);
/* Do one more iteration to set things up */
super_found = again = 1;
}
} while (again);
/* If name appears within the scope of a local variable declaration /* If name appears within the scope of a local variable declaration
or parameter declaration, then it is an expression name. We don't or parameter declaration, or is a field within an enclosing
carry this test out if we're in the context of the use of SUPER class, then it is an expression name. Save the decl and let
or THIS */ resolve_field_access do it's work. */
if (!this_found && !super_found if ((decl = IDENTIFIER_LOCAL_VALUE (name)) ||
&& TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST (decl = lookup_field_wrapper (current_class, name)))
&& (decl = IDENTIFIER_LOCAL_VALUE (name))) {
{
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
QUAL_RESOLUTION (qual) = decl; QUAL_RESOLUTION (qual) = decl;
return;
} }
/* If within the class/interface NAME was found to be used there /* If name is a known class name (either declared or imported), mark
exists a (possibly inherited) field named NAME, then this is an us as a type name. */
expression name. If we saw a NEW_ARRAY_EXPR before and want to if ((decl = resolve_and_layout (name, NULL_TREE)))
address length, it is OK. */
else if ((decl = lookup_field_wrapper (ptr_type, name))
|| name == length_identifier_node)
{
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
}
/* We reclassify NAME as yielding to a type name resolution if:
- NAME is a class/interface declared within the compilation
unit containing NAME,
- NAME is imported via a single-type-import declaration,
- NAME is declared in an another compilation unit of the package
of the compilation unit containing NAME,
- NAME is declared by exactly on type-import-on-demand declaration
of the compilation unit containing NAME.
- NAME is actually a STRING_CST.
This can't happen if the expression was qualified by `this.' */
else if (! this_found &&
(TREE_CODE (name) == STRING_CST ||
TREE_CODE (name) == INTEGER_CST ||
(decl = resolve_and_layout (name, NULL_TREE))))
{ {
RESOLVE_TYPE_NAME_P (qual_wfl) = 1; RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
QUAL_RESOLUTION (qual) = decl; QUAL_RESOLUTION (qual) = decl;
} }
/* Method call, array references and cast are expression name */
else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
|| TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
|| TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR
|| TREE_CODE (QUAL_WFL (qual)) == MODIFY_EXPR)
RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
/* Check here that NAME isn't declared by more than one /* Check here that NAME isn't declared by more than one
type-import-on-demand declaration of the compilation unit type-import-on-demand declaration of the compilation unit
containing NAME. FIXME */ containing NAME. FIXME */
/* Otherwise, NAME is reclassified as a package name */ /* We couldn't find a declaration for the name. Assume for now that
we have a qualified class name that needs to be loaded from an
external class file. */
else else
RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1; RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
...@@ -11495,21 +11341,14 @@ qualify_ambiguous_name (tree id) ...@@ -11495,21 +11341,14 @@ qualify_ambiguous_name (tree id)
{ {
if (RESOLVE_PACKAGE_NAME_P (qual_wfl)) if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1; RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
else
RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
} }
/* Store the global qualification for the ambiguous part of ID back /* Store the global qualification for the ambiguous part of ID back
into ID fields */ into ID fields */
if (RESOLVE_EXPRESSION_NAME_P (qual_wfl)) if (RESOLVE_TYPE_NAME_P (qual_wfl))
RESOLVE_EXPRESSION_NAME_P (id) = 1;
else if (RESOLVE_TYPE_NAME_P (qual_wfl))
RESOLVE_TYPE_NAME_P (id) = 1; RESOLVE_TYPE_NAME_P (id) = 1;
else if (RESOLVE_PACKAGE_NAME_P (qual_wfl)) else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
RESOLVE_PACKAGE_NAME_P (id) = 1; RESOLVE_PACKAGE_NAME_P (id) = 1;
/* Restore the current class */
current_class = saved_current_class;
} }
static int static int
......
2003-12-03 Ralph Loader <rcl@ihug.co.nz>
PR java/12374:
* libjava.compile/PR12374.java: New file.
2003-12-01 Jeff Sturm <jsturm@one-point.com> 2003-12-01 Jeff Sturm <jsturm@one-point.com>
PR optimization/13024 PR optimization/13024
......
public class PR12374 {
/* We weren't coping with field refs on a string constant... */
Object Foo()
{
return "".CASE_INSENSITIVE_ORDER;
}
/* Special casing access to array.length while analysing syntax is
evil. Especially when it means we can't cope with a type
called length. */
class length
{
static final int i = 2;
}
int bar()
{
return length.i;
}
public static void main (String[] argv)
{
}
}
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