mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 14:15:23 +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( a, col.getName(9).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 );
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
|
@ -2655,7 +2655,7 @@ public class CPPSemantics {
|
|||
|
||||
static private void qualificationConversion( Cost cost ) throws DOMException{
|
||||
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;
|
||||
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( ( op1.isConst() && !op2.isConst() ) || ( op1.isVolatile() && !op2.isVolatile() ) ) {
|
||||
canConvert = false;
|
||||
requiredConversion = Cost.NO_MATCH_RANK;
|
||||
break;
|
||||
}
|
||||
//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() ) )
|
||||
{
|
||||
canConvert = false;
|
||||
requiredConversion = Cost.NO_MATCH_RANK;
|
||||
break;
|
||||
}
|
||||
constInEveryCV2k &= op2.isConst();
|
||||
|
@ -2711,7 +2713,7 @@ public class CPPSemantics {
|
|||
if( s instanceof IQualifierType ^ t instanceof IQualifierType ){
|
||||
if( t instanceof IQualifierType ){
|
||||
canConvert = true;
|
||||
conversionRequired = 2;
|
||||
requiredConversion = Cost.CONVERSION_RANK;
|
||||
} else {
|
||||
//4.2-2 a string literal can be converted to pointer to 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 );
|
||||
} else {
|
||||
canConvert = false;
|
||||
requiredConversion = Cost.NO_MATCH_RANK;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else {
|
||||
canConvert = false;
|
||||
requiredConversion = Cost.NO_MATCH_RANK;
|
||||
}
|
||||
}
|
||||
} else if( s instanceof IQualifierType && t instanceof IQualifierType ){
|
||||
IQualifierType qs = (IQualifierType) s, qt = (IQualifierType) t;
|
||||
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() )
|
||||
conversionRequired = 1;
|
||||
requiredConversion = Cost.IDENTITY_RANK;
|
||||
else
|
||||
conversionRequired = 2;
|
||||
requiredConversion = Cost.CONVERSION_RANK;
|
||||
} else if( constInEveryCV2k && !canConvert ){
|
||||
canConvert = true;
|
||||
conversionRequired = 2;
|
||||
requiredConversion = Cost.CONVERSION_RANK;
|
||||
int i = 1;
|
||||
for( IType type = s; canConvert == true && i == 1; type = t, i++ ){
|
||||
while( type instanceof ITypeContainer ){
|
||||
|
@ -2749,18 +2753,18 @@ public class CPPSemantics {
|
|||
else if( type instanceof IPointerType ){
|
||||
canConvert = !((IPointerType)type).isConst() && !((IPointerType)type).isVolatile();
|
||||
}
|
||||
if( !canConvert )
|
||||
if( !canConvert ){
|
||||
requiredConversion = Cost.NO_MATCH_RANK;
|
||||
break;
|
||||
}
|
||||
type = ((ITypeContainer)type).getType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cost.qualification = requiredConversion;
|
||||
if( canConvert == true ){
|
||||
cost.qualification = conversionRequired;
|
||||
cost.rank = Cost.LVALUE_OR_QUALIFICATION_RANK;
|
||||
} else {
|
||||
cost.qualification = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2846,7 +2850,7 @@ public class CPPSemantics {
|
|||
} catch( NumberFormatException e ) {
|
||||
}
|
||||
}
|
||||
} else if( sPrev instanceof IPointerType && s instanceof ICPPClassType ){
|
||||
} else if( sPrev instanceof IPointerType ){
|
||||
IType tPrev = trg;
|
||||
while( tPrev instanceof ITypeContainer ){
|
||||
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
|
||||
//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 );
|
||||
cost.rank = ( temp > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
|
||||
cost.conversion = ( temp > -1 ) ? temp : 0;
|
||||
cost.detail = 1;
|
||||
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.
|
||||
//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
|
||||
cost.rank = Cost.CONVERSION_RANK;
|
||||
|
|
Loading…
Add table
Reference in a new issue