1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-05 16:56:04 +02:00

Patch for Devin Steffler.

Fixed 77821 - usualArithmeticConversions doesn't handle pointers
This commit is contained in:
John Camelon 2004-11-18 14:34:42 +00:00
parent 502f1c4822
commit deabf0e68b
2 changed files with 67 additions and 6 deletions

View file

@ -2332,5 +2332,14 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
writer.write("#endif\n"); //$NON-NLS-1$
parse(writer.toString());
}
public void testBug77821() throws Exception {
Writer writer = new StringWriter();
writer.write("typedef struct { /* ... */ }TYPE;\n"); //$NON-NLS-1$
writer.write("void ptrArith(const TYPE* pType) {\n"); //$NON-NLS-1$
writer.write("TYPE *temp = 0;\n"); //$NON-NLS-1$
writer.write("temp = (TYPE*)(pType + 1); /* Parser error is here */\n}\n"); //$NON-NLS-1$
parse(writer.toString());
}
}

View file

@ -1368,7 +1368,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
* Apply the usual arithmetic conversions to find out the result of an expression
* that has a lhs and a rhs as indicated in the specs (section 5.Expressions, page 64)
*/
protected ITypeInfo usualArithmeticConversions( IASTScope scope, ASTExpression lhsExp, ASTExpression rhsExp) throws ASTSemanticException{
protected ITypeInfo usualArithmeticConversions( IASTScope scope, ASTExpression lhsExp, ASTExpression rhsExp, Kind kind) throws ASTSemanticException{
setFilename(lhsExp.getFilename());
ITypeInfo lhs = lhsExp.getResultType().getResult();
@ -1376,18 +1376,62 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
if( lhs == null ) return null;
if( rhs == null ) return null;
boolean isLhsPointer = false;
boolean isRhsPointer = false;
// if you have a variable of type basic type, then we need to go to the basic type first
while( (lhs.getType() == ITypeInfo.t_type) && (lhs.getTypeSymbol() != null)){
if (!isLhsPointer) isLhsPointer = lhs.hasPtrOperators();
lhs = lhs.getTypeSymbol().getTypeInfo();
}
while( (rhs.getType() == ITypeInfo.t_type) && (rhs.getTypeSymbol() != null)){
if (!isRhsPointer) isRhsPointer = rhs.hasPtrOperators();
rhs = rhs.getTypeSymbol().getTypeInfo();
}
if( !lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true );
if( !rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true );
// invalid arithmetic detection TODO add support for 4.5 Integral Promotions/4.7 Integral Conversions if necessary
// 5.6 Multiplicative Operators: The operands of * and / shall have arithmetic or enumeration type; the operands of % shall have integral or enumeration type.
if (kind == IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY || kind == IASTExpression.Kind.MULTIPLICATIVE_DIVIDE) {
if( !lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
if( !rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
} else if (kind == IASTExpression.Kind.MULTIPLICATIVE_MODULUS) {
if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) ))
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) ))
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
// 5.7 Additive Operators:
// For addition, either both operands shall have arithmetic or enumeration type, or one operand shall be a
// pointer to a completely defined object type and the other shall have integral or enumeration type.
// For subtraction, one of the following shall hold:
// both operands have arithmetic or enumeration type; or
// both operands are pointers to cvqualified or cvunqualified versions of the same completely defined object type; or
// the left operand is a pointer to a completely defined object type and the right operand has integral or
// enumeration type.
} else if (kind == IASTExpression.Kind.ADDITIVE_PLUS) {
if (!((isLhsPointer && (isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ))) ||
(isRhsPointer && (isIntegralType(lhs, isRhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ))))) {
if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
}
} else if (kind == IASTExpression.Kind.ADDITIVE_MINUS) {
if (!(isLhsPointer && (isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )))) {
if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
}
// 5.11, 5.12, 5.13: The operator applies only to integral or enumeration operands.
} else if (kind == IASTExpression.Kind.ANDEXPRESSION || kind == IASTExpression.Kind.EXCLUSIVEOREXPRESSION || kind == IASTExpression.Kind.INCLUSIVEOREXPRESSION) {
if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
}
ITypeInfo info = TypeInfoProvider.newTypeInfo( );
if(
@ -1739,7 +1783,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
ASTExpression left = (ASTExpression)lhs;
ASTExpression right = (ASTExpression)rhs;
if((left != null ) && (right != null)){
info = usualArithmeticConversions( scope, left, right);
info = usualArithmeticConversions( scope, left, right, kind );
}
else
handleProblem( scope, IProblem.SEMANTIC_MALFORMED_EXPRESSION, null );
@ -3812,4 +3856,12 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
this.filename = EMPTY_STRING;
}
}
// used to check if an ITypeInfo is an "integral type" based on 3.9.1-7
private boolean isIntegralType(ITypeInfo info, boolean isPointer) {
if (isPointer) return true;
if (info.getType() == ITypeInfo.t_bool || info.getType() == ITypeInfo.t_char || info.getType() == ITypeInfo.t_wchar_t || info.getType() == ITypeInfo.t_int) return true;
return false;
}
}