mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-29 20:05:35 +02:00
fix bug 100415: conversion to void * and qualification conversions
This commit is contained in:
parent
15ddfc4c44
commit
a857f47641
2 changed files with 37 additions and 17 deletions
|
@ -4806,5 +4806,20 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
assertSame( b, col.getName(8).resolveBinding() );
|
assertSame( b, col.getName(8).resolveBinding() );
|
||||||
assertSame( a, col.getName(9).resolveBinding() );
|
assertSame( a, col.getName(9).resolveBinding() );
|
||||||
assertSame( b, col.getName(10).resolveBinding() );
|
assertSame( b, col.getName(10).resolveBinding() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBug100415() throws Exception {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
buffer.append("void free( void * ); \n");
|
||||||
|
buffer.append("void f( char **p ){ \n");
|
||||||
|
buffer.append(" free( p ); \n");
|
||||||
|
buffer.append("} \n");
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP, true, true );
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept( col );
|
||||||
|
|
||||||
|
IFunction free = (IFunction) col.getName(0).resolveBinding();
|
||||||
|
assertSame( free, col.getName(4).resolveBinding() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2454,7 +2454,7 @@ public class CPPSemantics {
|
||||||
qualificationConversion( cost );
|
qualificationConversion( cost );
|
||||||
|
|
||||||
//if we can't convert the qualifications, then we can't do anything
|
//if we can't convert the qualifications, then we can't do anything
|
||||||
if( cost.qualification == 0 ){
|
if( cost.qualification == Cost.NO_MATCH_RANK ){
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2655,7 +2655,7 @@ public class CPPSemantics {
|
||||||
|
|
||||||
static private void qualificationConversion( Cost cost ) throws DOMException{
|
static private void qualificationConversion( Cost cost ) throws DOMException{
|
||||||
boolean canConvert = true;
|
boolean canConvert = true;
|
||||||
int conversionRequired = 1; //1 means it will work without a conversion, 2 means conversion was needed
|
int requiredConversion = Cost.IDENTITY_RANK;
|
||||||
|
|
||||||
IPointerType op1, op2;
|
IPointerType op1, op2;
|
||||||
IType s = cost.source, t = cost.target;
|
IType s = cost.source, t = cost.target;
|
||||||
|
@ -2694,6 +2694,7 @@ public class CPPSemantics {
|
||||||
//if const is in cv1,j then const is in cv2,j. Similary for volatile
|
//if const is in cv1,j then const is in cv2,j. Similary for volatile
|
||||||
if( ( op1.isConst() && !op2.isConst() ) || ( op1.isVolatile() && !op2.isVolatile() ) ) {
|
if( ( op1.isConst() && !op2.isConst() ) || ( op1.isVolatile() && !op2.isVolatile() ) ) {
|
||||||
canConvert = false;
|
canConvert = false;
|
||||||
|
requiredConversion = Cost.NO_MATCH_RANK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//if cv1,j and cv2,j are different then const is in every cv2,k for 0<k<j
|
//if cv1,j and cv2,j are different then const is in every cv2,k for 0<k<j
|
||||||
|
@ -2701,6 +2702,7 @@ public class CPPSemantics {
|
||||||
op1.isVolatile() != op2.isVolatile() ) )
|
op1.isVolatile() != op2.isVolatile() ) )
|
||||||
{
|
{
|
||||||
canConvert = false;
|
canConvert = false;
|
||||||
|
requiredConversion = Cost.NO_MATCH_RANK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
constInEveryCV2k &= op2.isConst();
|
constInEveryCV2k &= op2.isConst();
|
||||||
|
@ -2711,7 +2713,7 @@ public class CPPSemantics {
|
||||||
if( s instanceof IQualifierType ^ t instanceof IQualifierType ){
|
if( s instanceof IQualifierType ^ t instanceof IQualifierType ){
|
||||||
if( t instanceof IQualifierType ){
|
if( t instanceof IQualifierType ){
|
||||||
canConvert = true;
|
canConvert = true;
|
||||||
conversionRequired = 2;
|
requiredConversion = Cost.CONVERSION_RANK;
|
||||||
} else {
|
} else {
|
||||||
//4.2-2 a string literal can be converted to pointer to char
|
//4.2-2 a string literal can be converted to pointer to char
|
||||||
if( t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_char &&
|
if( t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_char &&
|
||||||
|
@ -2725,22 +2727,24 @@ public class CPPSemantics {
|
||||||
((IASTLiteralExpression)val).getKind() == IASTLiteralExpression.lk_string_literal );
|
((IASTLiteralExpression)val).getKind() == IASTLiteralExpression.lk_string_literal );
|
||||||
} else {
|
} else {
|
||||||
canConvert = false;
|
canConvert = false;
|
||||||
|
requiredConversion = Cost.NO_MATCH_RANK;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
canConvert = false;
|
canConvert = false;
|
||||||
|
requiredConversion = Cost.NO_MATCH_RANK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if( s instanceof IQualifierType && t instanceof IQualifierType ){
|
} else if( s instanceof IQualifierType && t instanceof IQualifierType ){
|
||||||
IQualifierType qs = (IQualifierType) s, qt = (IQualifierType) t;
|
IQualifierType qs = (IQualifierType) s, qt = (IQualifierType) t;
|
||||||
if( qs.isConst() && !qt.isConst() || qs.isVolatile() && !qt.isVolatile() )
|
if( qs.isConst() && !qt.isConst() || qs.isVolatile() && !qt.isVolatile() )
|
||||||
canConvert = false;
|
requiredConversion = Cost.NO_MATCH_RANK;
|
||||||
else if( qs.isConst() == qt.isConst() && qs.isVolatile() == qt.isVolatile() )
|
else if( qs.isConst() == qt.isConst() && qs.isVolatile() == qt.isVolatile() )
|
||||||
conversionRequired = 1;
|
requiredConversion = Cost.IDENTITY_RANK;
|
||||||
else
|
else
|
||||||
conversionRequired = 2;
|
requiredConversion = Cost.CONVERSION_RANK;
|
||||||
} else if( constInEveryCV2k && !canConvert ){
|
} else if( constInEveryCV2k && !canConvert ){
|
||||||
canConvert = true;
|
canConvert = true;
|
||||||
conversionRequired = 2;
|
requiredConversion = Cost.CONVERSION_RANK;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for( IType type = s; canConvert == true && i == 1; type = t, i++ ){
|
for( IType type = s; canConvert == true && i == 1; type = t, i++ ){
|
||||||
while( type instanceof ITypeContainer ){
|
while( type instanceof ITypeContainer ){
|
||||||
|
@ -2749,18 +2753,18 @@ public class CPPSemantics {
|
||||||
else if( type instanceof IPointerType ){
|
else if( type instanceof IPointerType ){
|
||||||
canConvert = !((IPointerType)type).isConst() && !((IPointerType)type).isVolatile();
|
canConvert = !((IPointerType)type).isConst() && !((IPointerType)type).isVolatile();
|
||||||
}
|
}
|
||||||
if( !canConvert )
|
if( !canConvert ){
|
||||||
|
requiredConversion = Cost.NO_MATCH_RANK;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
type = ((ITypeContainer)type).getType();
|
type = ((ITypeContainer)type).getType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cost.qualification = requiredConversion;
|
||||||
if( canConvert == true ){
|
if( canConvert == true ){
|
||||||
cost.qualification = conversionRequired;
|
|
||||||
cost.rank = Cost.LVALUE_OR_QUALIFICATION_RANK;
|
cost.rank = Cost.LVALUE_OR_QUALIFICATION_RANK;
|
||||||
} else {
|
|
||||||
cost.qualification = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2846,7 +2850,7 @@ public class CPPSemantics {
|
||||||
} catch( NumberFormatException e ) {
|
} catch( NumberFormatException e ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if( sPrev instanceof IPointerType && s instanceof ICPPClassType ){
|
} else if( sPrev instanceof IPointerType ){
|
||||||
IType tPrev = trg;
|
IType tPrev = trg;
|
||||||
while( tPrev instanceof ITypeContainer ){
|
while( tPrev instanceof ITypeContainer ){
|
||||||
IType next = ((ITypeContainer)tPrev).getType();
|
IType next = ((ITypeContainer)tPrev).getType();
|
||||||
|
@ -2868,14 +2872,15 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
//4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted
|
//4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted
|
||||||
//to an rvalue of type "pointer to cv B", where B is a base class of D.
|
//to an rvalue of type "pointer to cv B", where B is a base class of D.
|
||||||
else if( tPrev instanceof IPointerType && t instanceof ICPPClassType ){
|
else if( s instanceof ICPPClassType && tPrev instanceof IPointerType && t instanceof ICPPClassType ){
|
||||||
temp = hasBaseClass( (ICPPClassType)s, (ICPPClassType) t, false );
|
temp = hasBaseClass( (ICPPClassType)s, (ICPPClassType) t, false );
|
||||||
cost.rank = ( temp > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
|
cost.rank = ( temp > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
|
||||||
cost.conversion = ( temp > -1 ) ? temp : 0;
|
cost.conversion = ( temp > -1 ) ? temp : 0;
|
||||||
cost.detail = 1;
|
cost.detail = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if( t instanceof IBasicType && s instanceof IBasicType || s instanceof IEnumeration ){
|
}
|
||||||
|
if( t instanceof IBasicType && s instanceof IBasicType || s instanceof IEnumeration ){
|
||||||
//4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.
|
//4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.
|
||||||
//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
|
//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
|
||||||
cost.rank = Cost.CONVERSION_RANK;
|
cost.rank = Cost.CONVERSION_RANK;
|
||||||
|
|
Loading…
Add table
Reference in a new issue