mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
fix bug 95734: conversion of integer literal 0 to pointer, also conversion of pointer to boolean
This commit is contained in:
parent
59e8ca66d9
commit
238118db0b
2 changed files with 69 additions and 2 deletions
|
@ -4307,4 +4307,41 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
ICPPMethod op = (ICPPMethod) col.getName(2).resolveBinding();
|
||||
assertSame( op, col.getName(6).resolveBinding() );
|
||||
}
|
||||
|
||||
public void testBug95734() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("int str( const char * ); \n"); //$NON-NLS-1$
|
||||
buffer.append("void f(){ \n"); //$NON-NLS-1$
|
||||
buffer.append(" str( 0 ); \n"); //$NON-NLS-1$
|
||||
buffer.append(" str( 00 ); str( 0x0 ); \n"); //$NON-NLS-1$
|
||||
buffer.append("} \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept(col);
|
||||
|
||||
ICPPFunction str = (ICPPFunction) col.getName(0).resolveBinding();
|
||||
assertSame( str, col.getName(3).resolveBinding() );
|
||||
assertSame( str, col.getName(4).resolveBinding() );
|
||||
assertSame( str, col.getName(5).resolveBinding() );
|
||||
}
|
||||
|
||||
public void testBug95734_2() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("int str( bool ); \n"); //$NON-NLS-1$
|
||||
buffer.append("enum { ONE }; \n"); //$NON-NLS-1$
|
||||
buffer.append("void f( char * p ){ \n"); //$NON-NLS-1$
|
||||
buffer.append(" str( 1.2 ); \n"); //$NON-NLS-1$
|
||||
buffer.append(" str( ONE ); str( p ); \n"); //$NON-NLS-1$
|
||||
buffer.append("} \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept(col);
|
||||
|
||||
ICPPFunction str = (ICPPFunction) col.getName(0).resolveBinding();
|
||||
assertSame( str, col.getName(6).resolveBinding() );
|
||||
assertSame( str, col.getName(7).resolveBinding() );
|
||||
assertSame( str, col.getName(9).resolveBinding() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2646,6 +2646,21 @@ public class CPPSemantics {
|
|||
IQualifierType qs = (IQualifierType) s, qt = (IQualifierType) t;
|
||||
if( qs.isConst() && !qt.isConst() || qs.isVolatile() && !qt.isVolatile() )
|
||||
canConvert = false;
|
||||
} else if( constInEveryCV2k && !canConvert ){
|
||||
canConvert = true;
|
||||
int i = 1;
|
||||
for( IType type = s; canConvert == true && i == 1; type = t, i++ ){
|
||||
while( type instanceof ITypeContainer ){
|
||||
if( type instanceof IQualifierType )
|
||||
canConvert = false;
|
||||
else if( type instanceof IPointerType ){
|
||||
canConvert = !((IPointerType)type).isConst() && !((IPointerType)type).isVolatile();
|
||||
}
|
||||
if( !canConvert )
|
||||
break;
|
||||
type = ((ITypeContainer)type).getType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( canConvert == true ){
|
||||
|
@ -2718,7 +2733,18 @@ public class CPPSemantics {
|
|||
sPrev = next;
|
||||
}
|
||||
|
||||
if( sPrev instanceof IPointerType && s instanceof ICPPClassType ){
|
||||
if( src instanceof IBasicType && trg instanceof IPointerType ){
|
||||
//4.10-1 an integral constant expression of integer type that evaluates to 0 can be converted to a pointer type
|
||||
IASTExpression exp = ((IBasicType)src).getValue();
|
||||
if( exp instanceof IASTLiteralExpression &&
|
||||
((IASTLiteralExpression)exp).getKind() == IASTLiteralExpression.lk_integer_constant )
|
||||
{
|
||||
if( Integer.decode( exp.toString() ).intValue() == 0 ){
|
||||
cost.rank = Cost.CONVERSION_RANK;
|
||||
cost.conversion = 1;
|
||||
}
|
||||
}
|
||||
} else if( sPrev instanceof IPointerType && s instanceof ICPPClassType ){
|
||||
IType tPrev = trg;
|
||||
while( tPrev instanceof ITypeContainer ){
|
||||
IType next = ((ITypeContainer)tPrev).getType();
|
||||
|
@ -2749,6 +2775,10 @@ public class CPPSemantics {
|
|||
//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
|
||||
cost.rank = Cost.CONVERSION_RANK;
|
||||
cost.conversion = 1;
|
||||
} else if( t instanceof IBasicType && ((IBasicType)t).getType() == ICPPBasicType.t_bool && s instanceof IPointerType ){
|
||||
//4.12 pointer or pointer to member type can be converted to an rvalue of type bool
|
||||
cost.rank = Cost.CONVERSION_RANK;
|
||||
cost.conversion = 1;
|
||||
} else if( s instanceof ICPPPointerToMemberType && t instanceof ICPPPointerToMemberType ){
|
||||
//4.11-2 An rvalue of type "pointer to member of B of type cv T", where B is a class type,
|
||||
//can be converted to an rvalue of type "pointer to member of D of type cv T" where D is a
|
||||
|
|
Loading…
Add table
Reference in a new issue